/**********************************************************************\
*                                                                      *
*  main.c -- Fastgraph and Fastgraph/Light demo program v 1.0          *
*                                                                      *
*  This program is provided without warranty of any kind.  It may      *
*  be distributed freely as long as the files are not modified.  You   *
*  may use this source code in your own applications as long as it     *
*  clearly understood that we are not responsible for any bugs in      *
*  this code or in your code.  Use this code freely, use it in good    *
*  health, but use it at your own risk.  Further disclaimers are       *
*  listed at the end of this file.                                     *   
*                                                                      *
*  This program requires Fastgraph or Fastgraph/Light to link          *
*  I compiled this program using the MSC 5.1 medium memory model       *
*                                                                      *
\**********************************************************************/

#include "defs.h"

int  menu_top;
int  menu_bottom;

char matrix1[] = {0xAA,0x55,0xAA,0x55};
char matrix2[] = {0x24,0x92,0x24,0x92};

/**********************************************************************\
*                                                                      *
*                                 main                                 *
*                                                                      *
\**********************************************************************/

void main()
{
   unsigned char key, aux;
   int mousex, mousey, count;
   register int i;
   int current;

   /* initialize the video environment */

   initialize();

   /* read the 8pt and 14pt fonts */

   get_font();

   /* draw the screen on the hidden page and copy it to the visual page */

   draw_screen();
   fg_restore(0,xlimit,0,ylimit);

   /* begin the main program loop */

   current = 0;
   while (TRUE)
   {
      fg_mousevis(ON);
      fg_waitfor(2);

      /* intercept a keystroke */

      fg_intkey(&key,&aux);
      if (key == ESC)
      {
         exit_program();
         continue;
      }
      else if (aux == RIGHT_ARROW)
      {
         current++;
         if (current == ITEMS)
            current = 0;
      }
      else if (aux == LEFT_ARROW)
      {
         current--;
         if (current < 0)
            current = ITEMS - 1;
      }

      /* display menu according to keystroke pressed */

      if (key+aux > 0)
      {
         fg_mousevis(OFF);
         current = horizontal_menu(main_menu,6,current,0,15,15,0);
         if (current == ESC)
         {
            exit_program();
            current = 0;
         }
         fg_mousevis(OFF);
         fg_restore(0,xlimit,menu_top,ylimit);
         fg_mousevis(ON);
      }

      /* intercept a mouse click */

      fg_mousebut(1,&count,&mousex,&mousey);
      if (count > 0 && BETWEEN(mousey,menu_top,menu_bottom))
      {
         for (i = 0; i <= ITEMS; i++)
         {
            if (BETWEEN(mousex, mouse_limits[i], mouse_limits[i+1]))
            {
               if (horizontal_menu(main_menu,6,i,0,15,15,0) == ESC)
                  exit_program();
               fg_mousevis(OFF);
               fg_restore(0,xlimit,menu_top,ylimit);
               fg_mousevis(ON);
               break;
            }
         }
      }
   }
}

/**********************************************************************\
*                                                                      *
*  draw_screen -- draw the main menu screen on the hidden page         *
*                                                                      *
\**********************************************************************/

void draw_screen()
{
   int y1, y2, y3;

   /* calculate y coordinates based on screen resolution */

   if (mode11 || mode16)
   {
      y1 = 3; y2 = 21; y3 = 38;
   }
   else
   {
      y1 = 1; y2 = 12; y3 = 23;
   }

   menu_top = y2 + 1;
   menu_bottom  = y3 + 1;

   /* erase the hidden page */

   background = 15;
   fg_setpage(hidden);
   fg_erase();

   /* draw some rectangles */

   fg_setcolor(15);
   fg_rect(0,xlimit,0,ylimit);

   fg_setcolor(0);
   fg_rect(0,xlimit,0,y2);

   /* draw the large dithered rectangles */

   if (mode06 || mode11)
      fg_drect(0,xlimit,y3+1,ylimit,matrix1);
   else
   {
      fg_setcolor(9);
      fg_drect(0,xlimit,0,y2-1,matrix1);
      fg_setcolor(14);
      fg_drect(0,xlimit,y3+1,ylimit,matrix2);
   }

   /* put the title in the title bar */

   fg_setcolor(15);
   center_pstring("Fastgraph Demo",0,xlimit,y2-1);

   fg_setcolor(8);
   draw_box(0,xlimit,0,ylimit);

   /* draw some black and grey outlines */

   fg_setcolor(7);
   draw_box(1,xlimit-1,scale(1),ylimit-scale(1));
   draw_box(2,xlimit-2,scale(2),ylimit-scale(2));

   fg_setcolor(0);
   draw_box(3,xlimit-3,y1,y3);
   draw_box(3,xlimit-3,y1,ylimit-y1);
   draw_box(4,xlimit-4,y1,ylimit-y1);

   /* draw those little boxes in the corners */

   if (mode06 || mode11)
   {
      fg_drect(5,25,y1+1,y2-1,matrix1);
      fg_drect(xlimit-25,xlimit-5,y1+1,y2-1,matrix1);
   }
   else
   {
      fg_setcolor(7);
      fg_rect(5,25,y1+1,y2-1);
      fg_rect(xlimit-25,xlimit-5,y1+1,y2-1);
   }

   /* display the horizontal menu */

   horizontal_menu(main_menu,-6,0,0,15,15,0);
   fg_setpage(visual);
}

/**********************************************************************\
*                                                                      *
*  draw_window -- display a pop-up window                              *
*                                                                      *
\**********************************************************************/

void draw_window(xmin,xmax,ymin,ymax,string)
int xmin, xmax, ymin, ymax;
char *string;
{
   register int y;

   /* display the window and its border */

   fg_setcolor(15);
   fg_rect(xmin,xmax,ymin,ymax);
   fg_setcolor(0);
   draw_box(xmin,xmax,ymin,ymax);
   draw_box(xmin+1,xmax-1,ymin,ymax);

   /* display the header bar at the top of the window */

   y = ymin + ptsize + 1;
   fg_rect(xmin,xmax,ymin,y+1);

   /* dither the header bar for 16 color modes */

   if (mode14 || mode16)
   {
      fg_setcolor(7);
      fg_rect(xmin+2,xmin+22,ymin+1,y);
      fg_rect(xmax-22,xmax-2,ymin+1,y);
      fg_setcolor(9);
      fg_drect(xmin+23,xmax-23,ymin+1,y,matrix1);
   }

   /* dither the header bar for 2 color modes */

   else
   {
      fg_drect(xmin+2,xmin+22,ymin+1,y,matrix1);
      fg_drect(xmax-22,xmax-2,ymin+1,y,matrix1);
   }

   /* display the text in the window's header bar */

   fg_setcolor(15);
   center_pstring(string,xmin,xmax,y+1);

   /* display the window's shadow */

   if (mode14 || mode16)
      fg_setcolor(8);
   else
      fg_setcolor(0);

   fg_rect(xmin+3,xmax+3,ymax+1,ymax+scale(2));
   fg_rect(xmax+1,xmax+3,ymin+scale(2),ymax);
}

/**********************************************************************\
*                                                                      *
*  erase_window -- erase the previously displayed pop-up window        *
*                                                                      *
\**********************************************************************/

void erase_window(xmin,xmax,ymin,ymax)
int xmin, xmax, ymin, ymax;
{
   register int x1, x2;

   /* restore the original area underneath the window */

   x1 = xmin & 0xFFF8;
   x2 = ((xmax+3) & 0xFFF8) + 7;
   fg_mousevis(OFF);
   fg_restore(x1,x2,ymin,ymax+2);

   /* redraw the dither pattern on the hidden page */

   fg_setpage(hidden);
   if (mode06 || mode11)
      fg_drect(x1,x2,ymin,ymax+2,matrix1);
   else
   {
      fg_setcolor(15);
      fg_rect(x1,x2,ymin,ymax+2);
      fg_setcolor(14);
      fg_drect(x1,x2,ymin,ymax+2,matrix2);
   }
   fg_setpage(visual);
}

/**********************************************************************\
*                                                                      *
*  get_answer -- accept a YES or NO answer from the keyboard or mouse  *
*                                                                      *
\**********************************************************************/

get_answer(xmin,xmax,y)
{
   int color;
   int count, lastx, lasty;
   int return_value;
   int x;
   int x1, x2, y1, y2;
   char yes_no[4];
   unsigned char key, aux;

   /* if using a mouse, display the "Yes" and "No" buttons */

   if (mouse)
   {
      color = fg_getcolor();
      x1 = ((3 * xmin) + xmax) / 4;
      x2 = ((3 * xmax) + xmin) / 4;
      y1 = y - ptsize/2 - 1;
      y2 = y + ptsize/2 + 1;
      fg_setcolor(0);
      draw_box(x1-25,x1+25,y1,y2);
      draw_box(x1-24,x1+24,y1,y2);
      draw_box(x2-25,x2+25,y1,y2);
      draw_box(x2-24,x2+24,y1,y2);
      center_pstring("Yes",x1,x1,y2);
      center_pstring("No",x2,x2,y2);
      fg_setcolor(8);
      fg_rect(x1-23,x1+27,y2+1,y2+scale(2));
      fg_rect(x1+26,x1+27,y1+scale(2),y2);
      fg_rect(x2-23,x2+27,y2+1,y2+scale(2));
      fg_rect(x2+26,x2+27,y1+scale(2),y2);
      fg_mousevis(ON);
   }

   /* read keystrokes until Y, y, N, n, or Esc is pressed */

   flushkey();
   while (TRUE)
   {
      fg_waitfor(2);
      fg_intkey(&key,&aux);
      key = tolower(key);

      if (mouse)
      {
         fg_mousebut(1,&count,&lastx,&lasty);
         if (BETWEEN(lastx,x1-25,x1+25) && BETWEEN(lasty,y1,y2))
            key = 'y';
         else if (BETWEEN(lastx,x2-25,x2+25) && BETWEEN(lasty,y1,y2))
            key = 'n';
      }

      if (key == 'y')
      {
         x = x1;
         strcpy(yes_no,"Yes");
         return_value = TRUE;
         break;
      }
      else if (key == 'n' || key == ESC)
      {
         x = x2;
         strcpy(yes_no,"No");
         return_value = FALSE;
         break;
      }
   }

   /* if using the mouse, flash the selected button */

   if (mouse)
   {
      fg_mousevis(OFF);
      fg_setcolor(0);
      fg_rect(x-23,x+23,y1+1,y2-1);
      fg_setcolor(15);
      center_pstring(yes_no,x,x,y2);
      fg_waitfor(2);
      fg_setcolor(15);
      fg_rect(x-23,x+23,y1+1,y2-1);
      fg_setcolor(0);
      center_pstring(yes_no,x,x,y2);
      fg_waitfor(2);
      fg_setcolor(color);
   }

   return(return_value);
}

/**********************************************************************\
*                                                                      *
*  info_window -- display text information in a window                 *
*                                                                      *
\**********************************************************************/

void info_window(xmin,xmax,ymin,string,nstrings)
int xmin,xmax,ymin;
char *string[];
int nstrings;
{
   register int i;
   int x, y;
   int miny, maxy;
   int len, maxlen;
   int ptsize1;

   /* center text in window according to length of longest string */

   ptsize1 = ptsize + 1;
   maxlen = 0;
   for (i = 1; i < nstrings; i++)
   {
      len = length_pstring(string[i]);
      if (len > maxlen) maxlen = len;
   }

   /* calculate top and bottom of info window */

   miny = scale(ymin);
   maxy = miny + (nstrings+1) * (ptsize1);

   /* draw the info window on the hidden page first */

   fg_setpage(hidden);

   /* draw the window and put the first string in the header bar */

   draw_window(xmin,xmax,miny,maxy,string[0]);

   /* calculate starting point for text */

   x = xmin + ((xmax - xmin) - maxlen) / 2;
   y = miny + ((ptsize+1)*2) + ptsize/2;

   /* put all the strings in the rest of the window */

   fg_setcolor(0);
   for (i = 1; i < nstrings; i++)
   {
      put_pstring(string[i],x,y);
      y += ptsize1;
   }

   /* restore the window to the visual page */

   fg_setpage(visual);
   fg_restore(xmin,xmax+3,miny,maxy+2);

   /* redraw the dither pattern on the hidden page */

   fg_setpage(hidden);
   if (mode06 || mode11)
      fg_drect(xmin,xmax+3,miny,maxy+2,matrix1);
   else
   {
      fg_setcolor(15);
      fg_rect(xmin,xmax+3,miny,maxy+2);
      fg_setcolor(14);
      fg_drect(xmin,xmax+3,miny,maxy+2,matrix2);
   }
   fg_setpage(visual);

}

/**********************************************************************\
*                                                                      *
*                         Further Disclaimers                          *
*                                                                      *
* Under no circumstances shall Ted Gruber Software be liable for any   *
* loss of profit or any other commercial damage, including but not     *
* limited to special, incidental, consequential, or other damages      *
* resulting from the use of or the inability to use the software,      *
* even if Ted Gruber Software has been notified of the possiblity      *
* of such damages. Ted Gruber Software disclaims all other warranties, *
* either expressed or implied, regarding the merchantability or        *
* fitness of this software and accompanying documentation for any      *
* particular application or purpose.                                   *
*                                                                      *
\**********************************************************************/
