#include <stdio.h>
#include <conio.h>
#include <allegro.h>
#include <jpeg.h>
#include "graphlib.h"

extern FILE *fp;
extern int screen_mode;

double evaluate_ex();
int evaluate_strexpr(char* string);


int SCREEN_Handler()
  {
    int scr_num = evaluate_ex();

    switch (scr_num)
      {
        case 0:
          set_gfx_mode(GFX_TEXT,80,25,0,0);
          screen_mode = 0;
          break;
        case 7:
          allegro_init();
          set_color_depth(8);
          set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0);
          screen_mode = 7;
          break;
        case 12:
          allegro_init();
          set_color_depth(8);
          set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0);
          screen_mode = 12;
          break;
        case 11:
          allegro_init();
          set_color_depth(24);
          set_gfx_mode(GFX_AUTODETECT, 640, 480, 0, 0);
          screen_mode = 11;
          break;
        case 13:
          allegro_init();
          set_color_depth(8);
          set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0);
          screen_mode = 13;
          break;
        case 14:
          allegro_init();
          set_color_depth(24);
          set_gfx_mode(GFX_AUTODETECT, 320, 200, 0, 0);
          screen_mode = 14;
          break;
      }

    return 0;
  }
/** END SCREEN_HANDLER **/


void SHOWJPEG_Handler()
  {
    BITMAP *bmp;
    PALETTE pal;
    jpeg_decode_param jpeg;
    char *string = (char*)malloc(1024);
    int x,y,scale;

    //jpeg.color_type=CT_GRAYSCALE; /* greyscale output   */

    evaluate_strexpr(string);
    x = evaluate_ex();
    y = evaluate_ex();
    scale = evaluate_ex();

    jpeg.decoding_speed=DS_FAST;  /* fastest method     */
    jpeg.scale_factor=scale;          /* smaller size       */

    bmp = load_jpeg_ex(string,pal,&jpeg);
    
    if (bmp == NULL)
      {
        set_gfx_mode(GFX_TEXT,80,25,0,0);
        printf("Cannot open %s, file missing or data corrupted\n",string);
        exit(EXIT_FAILURE);
      }
    
    blit(bmp,screen,0,0,x,y,bmp->w,bmp->h);

    destroy_bitmap(bmp);

    free(string);

  }
/** END SHOWJPEG_HANDLER **/


void LINE_Handler(int b)
  {
     int x1 = evaluate_ex(),
         y1 = evaluate_ex(),
         x2 = evaluate_ex(),
         y2 = evaluate_ex(),
          c = evaluate_ex();

     switch (b)
       {
         case 0:
           line(screen,x1,y1,x2,y2,c);
           break;
         case 1:
           rect(screen,x1,y1,x2,y2,c);
           break;
         case 2:
           rectfill(screen,x1,y1,x2,y2,c);
           break;
       }
  }

void CIRCLE_Handler()
  {
     int x = evaluate_ex(),
         y = evaluate_ex(),
         c;
     float r = evaluate_ex();

     c = evaluate_ex();
     circle(screen,x,y,r,c);
  }

void PAINT_Handler()
  {
     int x = evaluate_ex(),
         y = evaluate_ex(),
         c = evaluate_ex(),
         n = evaluate_ex();

     floodfill(screen,x,y,c);
  }

void PSET_Handler()
  {
     int x = evaluate_ex(),
         y = evaluate_ex(),
         c = evaluate_ex();

     putpixel(screen,x,y,c);
  }

int POINT_Handler()
  {
     int x = evaluate_ex(),
         y = evaluate_ex(),
         c;

     c = getpixel(screen,x,y);

     return c;
  }

int GPRINT_Handler(int crlf)
  {
    char *string;
    struct text_info *ti;
    byte fore;

    gettextinfo(ti);

    fore = (ti->attribute) % 16;

    switch (fgetc(fp))
      {
        case DT_NONE:
           //printf("\n");
           gotoxy(1,wherey()+1);
           break;
        case DT_STREXPR:
           string = (char*)malloc(2048);
           evaluate_strexpr(string);
           textout(screen,font,string,(wherex()-1)*8,(wherey()-1)*8,fore);
           gotoxy(wherex()+(strlen(string)),wherey());
           free(string);
           break;
        case DT_EXPRESSION:
           //printf("expression\n");
           string = (char*)malloc(80);
           sprintf(string,"%-1.6g",evaluate_ex());
           textout(screen,font,string,(wherex()-1)*8,(wherey()-1)*8,fore);
           gotoxy(wherex()+6,wherey());
           free(string);
           break;
      }

  return 0;

}
/** End GPRINT_HANDLER **/

void GCLS_Handler()
  {
    struct text_info *ti;
    byte back;

    gettextinfo(ti);

    back = ((ti->attribute) - ((ti->attribute) % 16)) % 15;

    rectfill(screen,0,0,640,480,back);
  }


void GRAPHICS_Library() {
// CLS, LOCATE, etc.

  switch (fgetc(fp))
  {
      case IK_SCREEN:
         SCREEN_Handler();
         break;
      case IK_SHOWJPG:
         SHOWJPEG_Handler();
         break;
      case IK_CIRCLE:
         CIRCLE_Handler();
         break;
      case IK_PAINT:
         PAINT_Handler();
         break;
      case IK_LINE:
         LINE_Handler(0);
         break;
      case IK_RECT:
         LINE_Handler(1);
         break;
      case IK_RECTFILL:
         LINE_Handler(2);
         break;
      case IK_PSET:
         PSET_Handler();
         break;
  }

} /** Endof GRAPHICS_Library **/
