/*  SVGATextMode -- An SVGA textmode manipulation/enhancement tool
 *
 *  Copyright (C) 1995  Koen Gadeyne
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */


/***
 *** setpalette: palette set/get program
 *** (c) 1995 Koen Gadeyne (kmg@barco.be)
 ***
 ***/

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "misc.h"
#include "vga_prg.h"
#include "messages.h"
#include "configfile.h"
#include "textregs.h"

char *CommandName;
int debug_messages=FALSE;
int setreg=FALSE;


inline void printrgb(int index, int r, int g, int b, int hexdata)
{
  if (hexdata)
    printf("0x%02x: 0x%02x 0x%02x 0x%02x\n",index,r,g,b);
  else
    printf("%03d: %03d %03d %03d\n",index,r,g,b);
}

void dumprgb(int index, int hexdata)
{
  int r,g,b;
  
  outb(index,DAC_STATUS);
  r=inb(DAC_DATA);
  g=inb(DAC_DATA);
  b=inb(DAC_DATA);
  printrgb(index, r, g, b, hexdata);
}  

void usage(int setreg)
{
   if (setreg)
     PMESSAGE(("version %s. (c) 1995 Koen Gadeyne.\n Usage: %s [options]  color_index  R G B\n\n\
     Options: -n  Don't program VGA hardware\n\
              -d  print debugging information\n\
              -x  input palette values in hex instead of decimal\n\
              -s  load a standard VGA palette (this doesn't need other parameters)\n\
                   (use `getpalette -s' to find out what palette this is\n\
              -h  print usage information\n\n\
     color_index: index number in the palette look-up table (0..255).\n\
                  or '-' to use standard input\n\
                    (Input format = '<index>: <R-value> <G-value> <B-value>')\n\
     R, G, B : color intensity for Red, Green or Blue (0..63).\n",
     VERSION, CommandName));
   else
     PMESSAGE(("version %s. (c) 1995 Koen Gadeyne.\n Usage: %s [options] <color_index>\n\n\
     Options: -n  Don't program VGA hardware\n\
              -d  print debugging information\n\
              -x  output palette values in hex instead of decimal\n\
              -s  output a standard VGA palette (this doesn't read anything from the VGA card)\n\
                   (this is the palette that will be programmed when running `setpalette -s')\n\
              -h  print usage information\n\n\
     color_index: index number in the palette look-up table (0..255).\n\
                    or 'all' to show all 256 entries\n",
     VERSION, CommandName));
}
 

void main (int argc, char* argv[])
{
  int index,r,g,b;
  char* commandfilename;
  int program_hardware=TRUE;
  int hexdata=FALSE;
  int stdpal=FALSE;
  char c;
   
 /*
  * See what action is required: read or write VGA register
  */

  CommandName = argv[0];
  commandfilename = strrchr(CommandName, '/');
  if (commandfilename) commandfilename++;
  else commandfilename = CommandName;
  setreg = (!strncasecmp(commandfilename,"set",3));
 
 /*
  * command-line argument parsing
  */

  while ((c = getopt (argc, argv, "ndxsh")) != EOF)
    switch (c)
    {
      case 'n': program_hardware=FALSE;
                break;
      case 'd': debug_messages=TRUE;
                break;
      case 'x': hexdata=TRUE;
                break;
      case 's': stdpal=TRUE;
                break;
      case 'h': usage(setreg);
                exit(0);
                break;
      case '?': usage(setreg);
                PERROR(("Bad option `-%c'\n",(char)optopt));
                exit(-1);
                break;
      default: PERROR(("getopt returned unknown token '%c'.",c));
    }
    
  PVERSION

  PDEBUG(("'%cetpalette' function selected through command name '%s'", (setreg) ? 's' : 'g', commandfilename));

  if (!stdpal) 
  {
    /* get color-index from commandline , if '-' use stdin */
    if (argc<optind+1) PERROR(("Missing color index (or `%s') on commandline", (setreg) ? "-" : "all" ));
  }

  if (!stdpal || setreg)
    if (program_hardware) get_VGA_io_perm(CS_VGA);
  
 /*
  * Start doing something useful
  */

  if (stdpal)
  {
    if (setreg)
    {
      if (program_hardware)
        for (index=0; index<256; index++)
          WRITERGB(index,STD_PALETTE[index][0],STD_PALETTE[index][1],STD_PALETTE[index][2]);
    }
    else
    {
      if (program_hardware)
        for(index=0;index<256;index++)
          printrgb(index, STD_PALETTE[index][0],STD_PALETTE[index][1],STD_PALETTE[index][2], hexdata);
    } 
  }
  else
  {
    if (setreg)
    {  /* setpalette */
    if(!strcmp(argv[optind],"-"))      /* use standard input */
      {
        char linebuf[1000];
        int lc=0;

        while(fgets(linebuf,999,stdin))
        {
          lc++;
          r=g=b=-1;
          if (hexdata)
            sscanf(linebuf,"0x%02x: 0x%02x 0x%02x 0x%02x",&index,&r,&g,&b);
          else
            sscanf(linebuf,"%03d: %03d %03d %03d",&index,&r,&g,&b);
          if(r==-1 || b==-1 || b==-1) PERROR(("Malformed line #%d",lc));
          if (program_hardware) WRITERGB(index,r,g,b);
        }
      }
      else 
      {
        index = getbyte(argv[optind], "color index", 0, 255);
        optind++;
        if (argc<optind+1) PERROR(("Missing color value R"));
        r = getbyte(argv[optind], "Color value R", 0, 63);
        optind++;
        if (argc<optind+1) PERROR(("Missing color value G"));
        g = getbyte(argv[optind], "Color value G", 0, 63);
        optind++;
        if (argc<optind+1) PERROR(("Missing color value B"));
        b = getbyte(argv[optind], "Color value B", 0, 63);
        PDEBUG(("Color index = %d (0x%x); Color values : R = %d (0x%x) , G = %d (0x%x) , B = %d (0x%x).", index, index, r, r, g, g, b, b));
   
        if (program_hardware) WRITERGB(index,r,g,b);
      }
    }
    else
    {  /* getpalette */
      if(strcasecmp(argv[optind],"all"))
      {
        index = getbyte(argv[optind], "color index", 0, 255);
        if (program_hardware) dumprgb(index, hexdata);
      }
      else 
        if (program_hardware) for(index=0;index<256;index++) dumprgb(index, hexdata);
    }
  }
}
