/***********************************************************************/
/*                                                                     */
/* Project      : GRAV                                                 */
/* Current Rel. : 3.1                                                  */
/* Creator      : Michael Knigge                                       */
/* Creation Date: 01/21/95                                             */
/* Description  : miscellanous functions                               */
/*                                                                     */
/* Functions    : grav_interpret_params()                              */
/*                grav_guess_filetype()                                */
/*                grav_init()                                          */
/*                grav_init_ncurses()                                  */
/*                grav_init_colors()                                   */
/*                grav_goodbye()                                       */
/*                grav_cleanup()                                       */
/*                grav_change_mode()                                   */
/*                grav_display_mode()                                  */
/*                grav_display_card()                                  */
/*                grav_reading_msg()                                   */
/*                grav_writing_msg()                                   */
/*                grav_show_help()                                     */
/*                                                                     */
/***********************************************************************/

#include <stdio.h>
#include <string.h>
#include <ncurses.h>
#include <vga.h>
#include "standard.h"
#include "gbm.h"
#include "defines.h"
#include "misc.h"
#include "screen.h"
#include "directory.h"

int grav_interpret_params(int argc, char *argv[], int *color, int *error_id)
{
   int local;
   int rc;

   /*
    * set the returncode. If no file was specified at the commandline,
    * this function will return zero. If a filename was specified,
    * the elementnumber of the filename in argv[] is returned. If an
    * error occured, -1 will be returned. If a directory was specified
    * GRAV will chage to the specified directory here.
    */
    
   rc        = 0;
   *error_id = GRAV_NO_ERROR;
   
   for (local=1;local<argc;local++)
   {
      if (strncmp(argv[local], "-", 1) == 0)
      {
         /*
          * if the first character of the string is a "-", than
          * the string is identified as a parameter
          */
         
         if (strcmp(argv[local], "-mono") == 0)
            *color = FALSE;

         if (strcmp(argv[local], "-bw") == 0)
            *color = FALSE;
               
         if (strcmp(argv[local], "-color") == 0)
            *color = TRUE;

         if (strcmp(argv[local], "-colour") == 0)
            *color = TRUE;
      }
      else
      {
         switch (grav_check_filename(argv[local]))
         {
         case IS_FILE:
              rc = local;
              break;
         case IS_DIRECTORY:
              if (chdir(argv[local]) == -1)
              {
                 *error_id = GRAV_ERROR_CHDIR;
                 return(-1);
              }
              break;
         case IS_NOT_FOUND:
              *error_id = GRAV_ERROR_EXIST;
              return(-1);
              break;
         }
      }
   }
   return(rc);
}

int grav_init(int *color, GMODE gmode[])
{
   int  local;

   /*
    * ask ncurses if we can use colors (TRUE or FALSE). this can be
    * overrided with the commandline-switches -mono, -bw, -color and
    * -colour
    */
    
   *color = has_colors();

   /*
    * now initialize the gbm-package....
    */
    
   gbm_init();
    
   /*
    * and don't forget to init the svgalib... :-)
    */
    
   vga_init();
   vga_disabledriverreport();
/*   vga_runinbackground(TRUE);  */

   /*
    * now fill the graphic-mode structure with all available
    * graphic-modes
    */

   strcpy(gmode[0].name,"320x200x16   ");   gmode[0].index  =    1;
   gmode[0].colors    =    16;              gmode[0].width  =  320;
   gmode[0].supported = FALSE;              gmode[0].height =  200;
      
   strcpy(gmode[1].name,"640x200x16   ");   gmode[1].index  =  2;
   gmode[1].colors    =    16;              gmode[1].width  =  640;
   gmode[1].supported = FALSE;              gmode[1].height =  200;
      
   strcpy(gmode[2].name,"640x350x16   ");   gmode[2].index  =  3;
   gmode[2].colors    =    16;              gmode[2].width  =  640;
   gmode[2].supported = FALSE;              gmode[2].height =  350;
      
   strcpy(gmode[3].name,"640x480x16   ");   gmode[3].index  =  4;
   gmode[3].colors    =    16;              gmode[3].width  =  640;
   gmode[3].supported = FALSE;              gmode[3].height =  480;
   
   strcpy(gmode[4].name,"320x200x256  ");   gmode[4].index  =  5;
   gmode[4].colors    =   256;              gmode[4].width  =  320;
   gmode[4].supported = FALSE;              gmode[4].height =  200;
   
   strcpy(gmode[5].name,"320x240x256  ");   gmode[5].index  =  6;
   gmode[5].colors    =   256;              gmode[5].width  =  320;
   gmode[5].supported = FALSE;              gmode[5].height =  240;
   
   strcpy(gmode[6].name,"320x400x256  ");   gmode[6].index  =  7;
   gmode[6].colors    =   256;              gmode[6].width  =  320;
   gmode[6].supported = FALSE;              gmode[6].height =  400;
   
   strcpy(gmode[7].name,"360x480x256  ");   gmode[7].index  =  8;
   gmode[7].colors    =   256;              gmode[7].width  =  360;
   gmode[7].supported = FALSE;              gmode[7].height =  480;
   
   strcpy(gmode[8].name,"640x480x256  ");   gmode[8].index  = 10;
   gmode[8].colors    =   256;              gmode[8].width  =  640;
   gmode[8].supported = FALSE;              gmode[8].height =  480;
   
   strcpy(gmode[9].name,"800x600x256  ");   gmode[9].index  =    11;
   gmode[9].colors    =   256;              gmode[9].width  =   800;
   gmode[9].supported = FALSE;              gmode[9].height =   600;
   
   strcpy(gmode[10].name,"1024x768x256 ");  gmode[10].index  =   12;
   gmode[10].colors    =   256;             gmode[10].width  = 1024;
   gmode[10].supported = FALSE;             gmode[10].height =  768;
   
   strcpy(gmode[11].name,"1280x1024x256");  gmode[11].index  =   13;
   gmode[11].colors    =   256;             gmode[11].width  = 1280;
   gmode[11].supported = FALSE;             gmode[11].height = 1024;

   /*
    * and from now the 15bpp, 16bpp and 24bpp modes....
    */

   strcpy(gmode[12].name,"320x200x32K  ");  gmode[12].index  =   14;
   gmode[12].colors    =  32768;            gmode[12].width  =  320;
   gmode[12].supported =  FALSE;            gmode[12].height =  200;

   strcpy(gmode[13].name,"320x200x64K  ");  gmode[13].index  =   15;
   gmode[13].colors    =  65536;            gmode[13].width  =  320;
   gmode[13].supported =  FALSE;            gmode[13].height =  200;

   strcpy(gmode[14].name,"320x200x16M  ");  gmode[14].index  =   16;
   gmode[14].colors    = 16777216;          gmode[14].width  =  320;
   gmode[14].supported =    FALSE;          gmode[14].height =  200;

   strcpy(gmode[15].name,"640x480x32K  ");  gmode[15].index  =   17;
   gmode[15].colors    =  32768;            gmode[15].width  =  640;
   gmode[15].supported =  FALSE;            gmode[15].height =  480;

   strcpy(gmode[16].name,"640x480x64K  ");  gmode[16].index  =   18;
   gmode[16].colors    =  65536;            gmode[16].width  =  640;
   gmode[16].supported =  FALSE;            gmode[16].height =  480;

   strcpy(gmode[17].name,"640x480x16M  ");  gmode[17].index  =   19;
   gmode[17].colors    = 16777216;          gmode[17].width  =  640;
   gmode[17].supported =    FALSE;          gmode[17].height =  480;

   strcpy(gmode[18].name,"800x600x32K  ");  gmode[18].index  =   20;
   gmode[18].colors    =  32768;            gmode[18].width  =  800;
   gmode[18].supported =  FALSE;            gmode[18].height =  600;

   strcpy(gmode[19].name,"800x600x64K  ");  gmode[19].index  =   21;
   gmode[19].colors    =  65536;            gmode[19].width  =  800;
   gmode[19].supported =  FALSE;            gmode[19].height =  600;

   strcpy(gmode[20].name,"800x600x16M  ");  gmode[20].index  =   22;
   gmode[20].colors    = 16777216;          gmode[20].width  =  800;
   gmode[20].supported =    FALSE;          gmode[20].height =  600;

   strcpy(gmode[21].name,"1024x768x32K ");  gmode[21].index  =   23;
   gmode[21].colors    =  32768;            gmode[21].width  = 1024;
   gmode[21].supported =  FALSE;            gmode[21].height =  768;

   strcpy(gmode[22].name,"1024x768x64K ");  gmode[22].index  =   24;
   gmode[22].colors    =  65536;            gmode[22].width  = 1024;
   gmode[22].supported =  FALSE;            gmode[22].height =  768;

   strcpy(gmode[23].name,"1024x768x16M ");  gmode[23].index  =   25;
   gmode[23].colors    = 16777216;          gmode[23].width  = 1024;
   gmode[23].supported =    FALSE;          gmode[23].height =  768;

   strcpy(gmode[24].name,"1280x1024x32K");  gmode[24].index  =   26;
   gmode[24].colors    =  32768;            gmode[24].width  = 1280;
   gmode[24].supported =  FALSE;            gmode[24].height = 1024;

   strcpy(gmode[25].name,"1280x1024x64K");  gmode[25].index  =   27;
   gmode[25].colors    =  65536;            gmode[25].width  = 1280;
   gmode[25].supported =  FALSE;            gmode[25].height = 1024;

   strcpy(gmode[26].name,"1280x1024x16M");  gmode[26].index  =   28;
   gmode[26].colors    = 16777216;          gmode[26].width  = 1280;
   gmode[26].supported =    FALSE;          gmode[26].height = 1024;
  
   /*
    * and now fill the graphic-mode structure and check every mode if
    * this mode is supported....
    */
    
    for (local=0; local<MAX_MODES; local++)
    {
       if (vga_hasmode(gmode[local].index))
          gmode[local].supported = TRUE;
    }

   return(TRUE);
}

int grav_init_ncurses()
{
   initscr();
   curs_set(CURSOR_INVISIBLE);  
   keypad(stdscr,TRUE);
   noecho();          
   raw();             
   nl();              
   cbreak();          
   clear();

   return(TRUE);
}

int grav_init_colors()
{
   start_color();
   init_pair(WHITE_ON_BLUE,   COLOR_WHITE,  COLOR_BLUE);
   init_pair(YELLOW_ON_RED,   COLOR_YELLOW, COLOR_RED);
   init_pair(BLACK_ON_CYAN,   COLOR_BLACK,  COLOR_CYAN);
   init_pair(WHITE_ON_BLACK,  COLOR_WHITE,  COLOR_BLACK);
   init_pair(YELLOW_ON_CYAN,  COLOR_YELLOW, COLOR_CYAN);
   init_pair(YELLOW_ON_BLACK, COLOR_YELLOW, COLOR_BLACK);
   init_pair(YELLOW_ON_BLUE,  COLOR_YELLOW, COLOR_BLUE);
   
   return(TRUE);
}


int grav_guess_filetype(char *filename, int *ft)
{
   /*
    * here we define all file-extensions (suffix), that are not
    * known to the gbm-library. if we add a suffix, we also have to
    * modify the MAX_TYPES define in misc.h
    */
    
   char suffix_tab[MAX_TYPES][6] = { ".TIFF", ".PSG", ".JPG", ".PCD",".PNG" };
   int  type_tab[MAX_TYPES]      = {    3   ,   13  ,   100 ,   110 ,  120 };

   int  type;
   int  len;
   char suffix[5];

   /*
    * first, we call gbm_guess_filetype from the gbm-library. if no
    * error occured, we simply return TRUE and store the filetype
    * in ft
    */
    
    if (gbm_guess_filetype(filename, &type) == GBM_ERR_OK)
    {
       *ft = type;
       return(TRUE);
    }
   
   /*
    * "erase" suffix and get length of filename
    */

   suffix[0] = 0;
   len       = strlen(filename);
   *ft       = -1;

   /*
    * go further only if length of filename ist greater than four. 
    * if we would not do this if, there could be a seg fault if we
    * subtract more than the length of the string from the pointer
    */
    
   if (len < 5)
      return(FALSE);
   else
   {   
      if (filename[len-5] == '.')
         strcpy(suffix, filename+len-5);
      else
         if (filename[len-4] == '.')
            strcpy(suffix, filename+len-4);
   }

   /* 
    * if we found not a dot, return here
    */
   
   if (strlen(suffix) == 0)
      return(FALSE);

   /*
    * now translate the suffix to uppercase
    */
    
    for(len=0;len<5;len++)
       suffix[len] = toupper(suffix[len]);

   /*
    * and now look if the file is a grahic
    */
    
   for (len=0;len<MAX_TYPES;len++)
   {
      if (strcmp(suffix, suffix_tab[len]) == 0)
      {
         *ft = type_tab[len];
         return(TRUE);
      }
   }

   /*
    * if we get here, this file is not a graphic that
    * can be displayed
    */
                      
   return(FALSE);
}


int grav_goodbye(int use_color)
{
   int local;

   /*
    * to reset the console completely, we have do do a special
    * "clear screen" here
    */
    
   fprintf(stderr,"\x1b[H\x1b[J");
   clear();
      
   if (use_color == TRUE)
   {
      attron(A_BOLD);
      grav_draw_box(12,80,1,1,WHITE_ON_BLUE);
      attron(COLOR_PAIR(YELLOW_ON_BLUE));
   }
   else
   {
      grav_draw_box(12,80,1,1,COLOR_REVERSE);
      attron(A_REVERSE);
   }

   
   mvaddstr(1, 2, "GRAphic View 3.1");
   mvaddstr(1, 41,"(C) Copyright by Michael Knigge, 1995");

   move(2,2);
   for(local=2; local<78; local++)
      addch(ACS_HLINE);

   if (use_color == TRUE)
      attron(COLOR_PAIR(WHITE_ON_BLUE));

   mvaddstr(4, 2, "If you like (and more important if you use) this program, please send  me  a");
   mvaddstr(5, 2, "mail. My eMail-Address is knick@cove.han.de. Write what you think about GRAV");
   mvaddstr(6, 2, "and what features would be nice in further releases. And  please  excuse  my");
   mvaddstr(7, 2, "poor english ;-)");
   mvaddstr(9, 2, "Happy linuxing");
   mvaddstr(10, 5, "Michael");

   refresh();

   return(TRUE);
}

int grav_cleanup()
{
   endwin();
   return(TRUE);
}

int grav_change_mode(int *mode_index, int step, GMODE gmode[])
{
   do
   {
      *mode_index = *mode_index + step;
      
      if (*mode_index > MAX_MODES)
         *mode_index = 0;
         
      if (*mode_index < 0)
         *mode_index = MAX_MODES;
   }
   while(gmode[*mode_index].supported == FALSE);
}

int grav_display_mode(int use_color, int mode_index, GMODE gmode[])
{
   if (use_color)
      attron(COLOR_PAIR(WHITE_ON_BLUE));
   else
      attron(A_NORMAL);

   mvaddstr(10,53,"Graphic Mode:");   
   mvaddstr(11,53,gmode[mode_index].name);
   
   if (use_color)
      attroff(COLOR_PAIR(WHITE_ON_BLUE));
   else
      attroff(A_NORMAL);   
}

int grav_display_card(int use_color, int chipset)
{
   if (use_color)
      attron(COLOR_PAIR(WHITE_ON_BLUE));
   else
      attron(A_NORMAL);

   mvaddstr(7,53,"Graphic Card:");                  
   move(8,53);
   
   switch(chipset)
   {
   case 0: addstr("UNDEFINED   ");     break;
   case 1: addstr("NORMAL VGA  ");     break;
   case 2: addstr("ET4000      ");     break;
   case 3: addstr("CIRRUS      ");     break;
   case 4: addstr("TRIDENT 8900");     break;
   case 5: addstr("OAK         ");     break;
   case 6: addstr("EGA         ");     break;
   case 7: addstr("S3          ");     break;
   case 8: addstr("ET3000      ");     break;
   case 9: addstr("ATI MACH32 ");     break;
   }
   
   if (use_color)
      attroff(COLOR_PAIR(WHITE_ON_BLUE));
   else
      attroff(A_NORMAL);   

}

int grav_reading_msg(int use_color)
{
   if (use_color == TRUE)
   {
      attron(A_BOLD);
      grav_draw_box(5,24,18,54,YELLOW_ON_RED);
      attron(COLOR_PAIR(YELLOW_ON_RED));
      mvaddstr(19,57,"Reading Data...");
      attroff(A_BOLD);
      attroff(COLOR_PAIR(YELLOW_ON_RED));
   }
   else
   {
      grav_draw_box(5,24,18,54,COLOR_REVERSE);
      attron(A_REVERSE);
      mvaddstr(19,57,"Reading Data...");
      attroff(A_REVERSE);
   }

   refresh();
   
   return(TRUE);
}


int grav_writing_msg(int use_color)
{
   if (use_color == TRUE)
   {
      attron(A_BOLD);
      grav_draw_box(5,24,18,54,YELLOW_ON_RED);
      attron(COLOR_PAIR(YELLOW_ON_RED));
      mvaddstr(19,57,"Writing Data...");
      attroff(A_BOLD);
      attroff(COLOR_PAIR(YELLOW_ON_RED));
   }
   else
   {
      grav_draw_box(5,24,18,54,COLOR_REVERSE);
      attron(A_REVERSE);
      mvaddstr(19,57,"Writing Data...");
      attroff(A_REVERSE);
   }

   refresh();
   
   return(TRUE);
}


int grav_show_help(int use_color)
{
   int local;

   if (use_color)
   {
      attron(A_BOLD);
      grav_draw_box(16,24,8,54,YELLOW_ON_RED);
      attron(COLOR_PAIR(YELLOW_ON_RED));
   }
   else
   {
      grav_draw_box(16,24,8,54,COLOR_REVERSE);
      attron(A_REVERSE);
   }
                                     
   mvaddstr( 9,55,"'+'   Inc Resolution");
   mvaddstr(10,55,"'-'   Dec Resolution");
   mvaddstr(12,55,"'P'   Print File    ");
   mvaddstr(13,55,"'C'   Convert File  ");
   mvaddstr(14,55,"'I'   File Info     ");
   mvaddstr(16,55,"TAB   Enter Filename");
   mvaddstr(17,55,"SPACE Tag File      ");
   mvaddstr(19,55,"'Q'   Quit          ");
   mvaddstr(20,55,"F10   Quit too      ");

   refresh();
   getch();
   
   if (use_color)
   {
      attroff(A_BOLD);
      attroff(COLOR_PAIR(YELLOW_ON_RED));
      attron(COLOR_PAIR(WHITE_ON_BLUE));
   }
   else
   {
      attroff(A_REVERSE);
      attron(A_NORMAL);
   }
                  
   for(local=7;local<24;local++)
      mvaddstr(local,53,"                        ");

   mvaddstr(14,53,"Press F1 for Help");

   return(TRUE);                              
}
