/* Copyright © 1995-1996 : David Atkinson */
/* V1.22  Menus.c */
/* Calgor */

#include <hold/extra.h>
#include <hold/funchead.h>
#include <hold/mowd.h>

#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>

#include <intuition/intuition.h>

#include <graphics/gfx.h>
#include <graphics/gfxmacros.h>
#include <graphics/copper.h>
#include <graphics/view.h>
#include <graphics/text.h>
#include <graphics/sprite.h>
#include <graphics/gfxbase.h>

#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/dos_protos.h>
#include <clib/diskfont_protos.h>

extern void get_source(TEXT *);
extern void showcode(void);
extern void play_col(int);
extern void ff_col(int);
extern void clr_code(void);
extern void killsprite(void);
extern void clean_local(void);
extern void clr_dem(void);
extern void set_sprite(void);
extern void reset_sprites(void);
extern void chk_view(struct View *, struct View *);
extern SHORT anim_button(void);
extern SHORT menu_button(void);
#ifdef TEST
extern void write_log(TEXT *,SHORT);
#endif
extern void back_drop(void);
extern void shutdown(void);
extern void clearkeybuf(void);
extern void draw_modes(UBYTE,struct RastPort *,long,long,UBYTE);
extern void alert(TEXT *);
extern void cleanup(void);

extern struct GfxBase *ps;
extern struct Window *my_window;
extern int last;
extern int dem_num;
#ifdef TEST
extern SHORT Diagnostic;
#endif
extern UWORD colour_table[VYOUS][COLOURS];

void show_display(int);
void menu_opt(void);
void put_back(int);
void copy_object(int, long, long, struct BitMap * );
void write_opt(int,long);
void anim_opt(void);

extern struct BitMap ft_bitmap;
extern struct BitMap thd_bitmap;
extern struct ViewPort ft_viewport;
extern struct ViewPort sec_viewport;
extern struct View ft_view;
extern struct View sec_view;
extern struct RastPort ft_rastport;
extern struct TextFont *font_ptr;

extern TEXT choices[NUMOFOPT][SLENGTH];     /* Options */
extern TEXT editor[MAXCHARPATH];            /* Editor Buffer */

int old_dem=0;                       /* Dem_num changes a bit, old_dem doesn't */

void show_display(int vselect)
{
  switch(vselect){
    case(1):
      MakeVPort(&ft_view, &ft_viewport );
      MrgCop(&ft_view);
      LoadView(&ft_view);
      break;
    case(2):
      MakeVPort(&sec_view, &sec_viewport );
      MrgCop(&sec_view);
      LoadView(&sec_view);
      set_sprite();
      reset_sprites();
      break;
    default:
      clean_local();
      alert("Failed view selection (prep_hardware)\n");
      break;
  }
}

/* The status when we hit this routine is that the second view and viewport
   are showing */

void anim_opt(void)
{
TEXT filename[MAXCHARPATH];
SHORT butpress=0;
ULONG check;

   old_dem=dem_num;
   show_display(2);
   while(dem_num!=-1){

     check = LockIBase(0);
     ps = (struct GfxBase *) GfxBase;
     UnlockIBase(check);
     if(ps->ActiView!=&sec_view)
       chk_view(ps->ActiView,&sec_view);
     Wait(1L << my_window->UserPort->mp_SigBit);
     raise(SIGINT);
     butpress = anim_button();
     clearkeybuf();
     switch(butpress){
       case PLAYBUT : case NUM1KEY :
         /*  PLAY BUTTON */
         #ifdef TEST
           write_log("Playbut Pressed PASSED (anim_opt)\n",PRITHREE);
         #endif
         dem_num=old_dem;
         strcpy(filename,ONEONE);
         strcat(filename,&choices[8+(old_dem*2)][0]);
         strcat(filename,".c");
         clr_code();
         clr_dem();
         reset_sprites();
         play_col(1);
         get_source(filename);
         showcode();
         switch (dem_num){
           case 100:
             break;
           case 1:
             ifelse_control();
             break;
           case 2 :
             switch_control();
             break;
           case 3 :
             for_control();
             break;
           case 4 :
             while_control();
             break;
           case 5 :
             dowhile_control();
             break;
           case 6:
             array_control();
             break;
           case 11 :
             bubble_control();
             break;
           case 12 :
             insert_control();
             break;
           case 13 :
             select_control();
             break;
           case 14 :
             quick_control();
             break;
           case 21:
             user1_control();
             break;
           case 22:
             user2_control();
             break;
           case 23:
             user3_control();
             break;
           case 24:
             user4_control();
             break;
           case 25:
             user5_control();
             break;
           default :
             clean_local();
             printf("Falied to lock %d\n",dem_num);
             alert("Failed to get opt num (anim_opt)\n");
             break;
           }
           play_col(0);
           ff_col(0);
           break;
         case EJECTBUT : case ESCKEY :
           #ifdef TEST
             write_log("Eject Pressed (anim_opt) PASSED\n",PRITHREE);
           #endif
           /* EJECT BUTTON */
           clean_local();
           clr_code();
           clr_dem();
           dem_num=-1;
           show_display(1);
           break;
         case INFOBUT : case NUM5KEY :
           /* INFORMATION BUTTON */
           #ifdef TEST
             write_log("Info Pressed (anim_opt) PASSED\n",PRITHREE);
           #endif
           killsprite();
           shutdown();
           strcpy(filename,editor);
           strcat(filename," ");
           strcat(filename,ONETHREE);
           strcat(filename,&choices[8+(old_dem*2)][0]);
           strcat(filename,".txt");
           system(filename);
           back_drop();
           LoadView(&sec_view);
           set_sprite();
           reset_sprites();
           break;
        default :
           #ifdef TEST
             write_log("No Action Needed (anim_opt) PASSED\n",PRITHREE);
           #endif
           break;
     }
   }
}

void menu_opt(void)
{
ULONG chit;
SHORT key=0;

  while(dem_num==-1){
      chit = LockIBase(0);
      ps = (struct GfxBase *) GfxBase;
      UnlockIBase(chit);
      if(ps->ActiView!=&ft_view)
        chk_view(ps->ActiView,&ft_view);
      Wait(1L << my_window->UserPort->mp_SigBit);
      raise(SIGINT);
      key=menu_button();
      clearkeybuf();
      /* F1 Option 1 */
      if ( (key==F1BUTTON) && (last!=0)  ){
         copy_object(1,55,93,&ft_bitmap);
         put_back(last);
         last=0;
         write_opt(0,MBLACK);
         #ifdef TEST
           write_log("F1 Pressed (Menu_opt) PASSED \n",PRITHREE);
         #endif
      }
      /* F2 Option 2 */
      if ( (key==F2BUTTON) && (last!=1) ){
         copy_object(1,169,93,&ft_bitmap);
         put_back(last);
         last=1;
         write_opt(1,MBLACK);
         #ifdef TEST
           write_log("F2 Pressed (Menu_opt) PASSED\n",PRITHREE);
         #endif
      }

      /* F3 Option 3 */
     if ( (key==F3BUTTON) && (last!=2) ){
        copy_object(1,283,93,&ft_bitmap);
        put_back(last);
        last=2;
        write_opt(2,MBLACK);
        #ifdef TEST
          write_log("F3 Pressed (Menu_opt) PASSED\n",PRITHREE);
        #endif
     }

     /* F4 Option 4 */
     if ( (key==F4BUTTON) && (last!=3) ){
        copy_object(1,397,93,&ft_bitmap);
        put_back(last);
        last=3;
        write_opt(3,MBLACK);
        #ifdef TEST
          write_log("F4 Pressed (Menu_opt) PASSED\n",PRITHREE);
        #endif
     }

     /* F5 Option 5 */
     if ( (key==F5BUTTON) && (last!=4) ){
        copy_object(1,511,93,&ft_bitmap);
        put_back(last);
        last=4;
        write_opt(4,MBLACK);
        #ifdef TEST
          write_log("F5 Pressed (Menu_opt) PASSED\n",PRITHREE);
        #endif
     }

     /* Scan y coords for key options */
     switch(key){
       case NUM1KEY:
         dem_num=(last*5+1);
         #ifdef TEST
           write_log("NUM1KEY Pressed (Menu_opt) PASSED\n",PRITHREE);
         #endif
         if( (choices[8+(dem_num*2)][0]!='\0') && (choices[8+(dem_num*2)][0]!='!') )
           anim_opt();
         else
           dem_num=-1;
         break;
       case NUM2KEY:
         dem_num=(last*5+2);
         #ifdef TEST
           write_log("NUM2KEY Pressed (Menu_opt) PASSED\n",PRITHREE);
         #endif
         if( (choices[8+(dem_num*2)][0]!='\0') && (choices[8+(dem_num*2)][0]!='!') )
           anim_opt();
         else
           dem_num=-1;
         break;
       case NUM3KEY:
         dem_num=(last*5+3);
         #ifdef TEST
           write_log("NUM3KEY Pressed (Menu_opt) PASSED\n",PRITHREE);
         #endif
         if( (choices[8+(dem_num*2)][0]!='\0') && (choices[8+(dem_num*2)][0]!='!') )
           anim_opt();
         else
           dem_num=-1;
         break;
       case NUM4KEY:
         dem_num=(last*5+4);
         #ifdef TEST
           write_log("NUM4KEY Pressed (Menu_opt) PASSED\n",PRITHREE);
         #endif
         if( (choices[8+(dem_num*2)][0]!='\0') && (choices[8+(dem_num*2)][0]!='!') )
           anim_opt();
         else
           dem_num=-1;
         break;
       case NUM5KEY:
         dem_num=(last*5+5);
         #ifdef TEST
           write_log("NUM5KEY Pressed (Menu_Opt) PASSED\n",PRITHREE);
         #endif
         if( (choices[8+(dem_num*2)][0]!='\0') && (choices[8+(dem_num*2)][0]!='!') )
           anim_opt();
         else
           dem_num=-1;
         break;
       case ESCKEY :
         #ifdef TEST
           if(Diagnostic>=2)
             system("avail > Cal:Memory");
           write_log("ESCKEY Pressed (Menu_opt) PASSED\n",PRITHREE);
         #endif
         cleanup();
         exit(0);
         break;
       default:
         #ifdef TEST
           write_log("No Action Needed (Menu_Opt) PASSED\n",PRITHREE);
         #endif
         dem_num=-1;
         break;
     }
  }
}

void put_back(int where)
{
  switch(where){
    case(0):
      copy_object(2,55,93,&ft_bitmap);
      write_opt(0,MWHITE);
      break;
    case(1):
      copy_object(2,169,93,&ft_bitmap);
      write_opt(1,MWHITE);
      break;
    case(2):
      copy_object(2,283,93,&ft_bitmap);
      write_opt(2,MWHITE);
      break;
    case(3):
      copy_object(2,397,93,&ft_bitmap);
      write_opt(3,MWHITE);
      break;
    case(4):
      copy_object(2,511,93,&ft_bitmap);
      write_opt(4,MWHITE);
      break;
    default:
      clean_local();
      alert("Failed (put_back)\n");
      break;
  }
  #ifdef TEST
    write_log("put_back PASSED\n",PRITHREE);
  #endif
}

void copy_object(int object, long dx, long dy, struct BitMap *dest_bm)
{

long sx, sy, mw, mh, flag, mask;

flag = 0xC0;  /* Normal copy */
mask = 0xFF;  /* Use all bitplanes */

  switch(object){
    case(1):
      /* OPTION ON */
      sx = 1L;
      sy = 1L;
      mw = 79;
      mh = 53;
      break;
    case(2):
      /* OPTION OFF */
      sx = 82L;
      sy = 1L;
      mw = 79;
      mh = 53;
      break;
    case(3):
      /* VARIABLE */
      sx = 178L;
      sy = 2L;
      mw = 46;
      mh = 58;
      break;
    case(4):
      /* HOLE */
      sx = 240L;
      sy = 2L;
      mw = 53;
      mh = 53;
      break;
    case(5):
      /* VBB */
      sx = 298L;
      sy = 2L;
      mw = 6;
      mh = 18;
      break;
    case(6):
      /* HBB */
      sx = 298L;
      sy = 24L;
      mw = 18;
      mh = 6;
      break;
    case(7):
     /* FILL */
      sx = 307L;
      sy = 2L;
      mw = 8;
      mh = 6;
      break;
    case(8):
    /* IAR */
      sx = 319L;
      sy = 2L;
      mw = 46;
      mh = 22;
      break;
    case(9):
    /* IOFF */
      sx = 319L;
      sy = 29L;
      mw = 16;
      mh = 15;
      break;
    case(10):
    /* ION */
      sx = 338L;
      sy = 29L;
      mw = 16;
      mh = 15;
      break;
    default:
      clean_local();
      alert("Object doesn't exist (copy_object)\n");
      break;
  }
  WaitBlit();  /* Make sure we have blitter */
  BltBitMap(&thd_bitmap, sx, sy, dest_bm, dx, dy, mw, mh, flag, mask, NULL);
  #ifdef TEST
    write_log("Copy_object PASSED\n",PRITHREE);
  #endif
}

void write_opt(int select, long color)
{
int index;

   index = 10 * select;
   draw_modes(0xFF,&ft_rastport,MBAGE,0L,JAM1);
   SetFont(&ft_rastport,font_ptr);
   /* Write text to option squares */
   if (color!=MWHITE){
     Move(&ft_rastport,67,113);
     Text(&ft_rastport, &choices[0][0], strlen(&choices[0][0])  );
     Move(&ft_rastport,67,126);
     Text(&ft_rastport, &choices[1][0], strlen(&choices[1][0])  );
     Move(&ft_rastport,181,113);
     Text(&ft_rastport, &choices[2][0], strlen(&choices[2][0])  );
     Move(&ft_rastport,181,126);
     Text(&ft_rastport, &choices[3][0], strlen(&choices[3][0])  );
     Move(&ft_rastport,295,113);
     Text(&ft_rastport, &choices[4][0], strlen(&choices[4][0])  );
     Move(&ft_rastport,295,126);
     Text(&ft_rastport, &choices[5][0], strlen(&choices[5][0])  );
     Move(&ft_rastport,409,113);
     Text(&ft_rastport, &choices[6][0], strlen(&choices[6][0])  );
     Move(&ft_rastport,409,126);
     Text(&ft_rastport, &choices[7][0], strlen(&choices[7][0])  );
     Move(&ft_rastport,523,113);
     Text(&ft_rastport, &choices[8][0], strlen(&choices[8][0])  );
     Move(&ft_rastport,523,126);
     Text(&ft_rastport, &choices[9][0], strlen(&choices[9][0])  );
   }
   /*Write text to key sections */
   draw_modes(0xFF,&ft_rastport,color,0L,JAM1);
   /* Key 1 */
   Move(&ft_rastport,158,276);
   Text(&ft_rastport,&choices[10+index][0], strlen(&choices[10+index][0]) );
   Move(&ft_rastport,158,293);
   Text(&ft_rastport,&choices[11+index][0], strlen(&choices[11+index][0]) );
   /* Key 2 */
   Move(&ft_rastport,331,276);
   Text(&ft_rastport,&choices[12+index][0], strlen(&choices[12+index][0]) );
   Move(&ft_rastport,331,293);
   Text(&ft_rastport,&choices[13+index][0], strlen(&choices[13+index][0]) );
   /* Key 3 */
   Move(&ft_rastport,504,276);
   Text(&ft_rastport,&choices[14+index][0], strlen(&choices[14+index][0]) );
   Move(&ft_rastport,504,293);
   Text(&ft_rastport,&choices[15+index][0], strlen(&choices[15+index][0]) );
   /* Key 4 */
   Move(&ft_rastport,158,370);
   Text(&ft_rastport,&choices[16+index][0], strlen(&choices[16+index][0]) );
   Move(&ft_rastport,158,387);
   Text(&ft_rastport,&choices[17+index][0], strlen(&choices[17+index][0]) );
   /* Key 5 */
   Move(&ft_rastport,331,370);
   Text(&ft_rastport,&choices[18+index][0], strlen(&choices[18+index][0]) );
   Move(&ft_rastport,331,387);
   Text(&ft_rastport,&choices[19+index][0], strlen(&choices[19+index][0]) );
   #ifdef TEST
     write_log("write_opt PASSED\n",PRITHREE);
   #endif
}
