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

#include <exec/types.h>
#include <proto/icon.h>

#include "MakeILBM.h"
#include "Scanner.h"
#include "Scanner_protos.h"

static int    depth;
static ULONG  color;
static double fx0,fy0,fx1,fy1;
static int    resolution;
static int    brightness;
static int    contrast;
static int    shadow;
static int    highlight;
static int    midtone;
static int    halftonePattern;
static int    exposureTime;   
static double gamma;
static int    compress;
static char*  outputFile;

short readToolTypes(char **array,struct ScannerOptions* option);

/**************************************************************************/

/**********************           M A I N           ***********************/

/**************************************************************************/
int main(int argc, char **argv)
{
  struct ScannerOptions option;
  BYTE   status;
 
  memset(&option,0,sizeof(struct ScannerOptions));
  openScanner("scsi.device",2,&option,&status);

  if( status == 0)
  {
    struct ScanParameters  param;
    struct ScanInformation inform;
   
    if( status = readToolTypes(&argv[1],&option) )
    {
      closeScanner();
      exit(status);
    }
 
    param.sp_ColorNum = color;
    param.sp_x0 = fx0;
    param.sp_y0 = fy0;
    param.sp_x1 = fx1;
    param.sp_y1 = fy1;
    param.sp_xResolution = resolution;
    param.sp_yResolution = resolution;
    param.sp_brightness[0] = brightness;
    param.sp_brightness[1] = brightness;
    param.sp_brightness[2] = brightness;
    param.sp_contrast = contrast;
    param.sp_shadow = shadow;
    param.sp_highlight = highlight;
    param.sp_midtone = midtone; 
    param.sp_halftonePattern = halftonePattern; 
    param.sp_exposureTime = exposureTime;
    param.sp_gamma = gamma;
    param.sp_flags = 0;
   
    setParameter(&param,&status);
   
    if( status == 0 )
    {
      startScanning(&inform,&status);
     
      if( status == 0 )
      {
        struct ILBMFile *fh;
        UBYTE* line = NULL;
        
        if( (line = malloc(inform.sv_bytesPerLine+1)) && (fh = openILBM(outputFile,inform.sv_imageWidth,inform.sv_imageHeight,depth,inform.sv_xResolution,inform.sv_yResolution,compress)) )
        {
          ULONG length;
          
          while( status == 0 )
          {
            length = inform.sv_bytesPerLine+1;
            readScanLine(line,&length,&status);
            if( status == 0 )
              writeILBM(fh,line+1,*line);
          }
          
          if( status == SCAN_STATUS_EOF )
          {
            closeILBM(fh,0);
            status = 0;
          }
          else
            closeILBM(fh,1);
        }

        stopScanning();
        
        if( line )
          free(line);
      }
    }
 
   closeScanner();
 }
 return status;
}

short readToolTypes(char **array,struct ScannerOptions* option)
{
  char* str;
  
  // Get scan color
  if( str = FindToolType(array,"color") )
  {
    if( MatchToolValue(str,"halftone") )
    {
      color = COLORNUM_HALFTONE;
      depth = 1;
    }
    else if( MatchToolValue(str,"bw") )
    {
      color = COLORNUM_BW;
      depth = 1;
    }
    else if( MatchToolValue(str,"gray") )
    {
      color = COLORNUM_GREY8;
      depth = 8;
    }
    else if( MatchToolValue(str,"rgb24") )
    {
      color = COLORNUM_RGB24;
      depth = 24;
    }
    else
      return 1;
      
    if( !(option->so_colorMode & color) )
      return 1;
  }
  else
  {
    color = COLORNUM_RGB24;
    depth = 24;
  }
    
  // Get frame coordinates
  if( str = FindToolType(array,"frame") )
  {
    fx0 = strtod(str,&str);
    if( *(str++) != ',' )
      return 2;
    fy0 = strtod(str,&str);
    if( *(str++) != ',' )
      return 2;
    fx1 = strtod(str,&str);
    if( *(str++) != ',' )
      return 2;
    fy1 = strtod(str,&str);
    if( (*str != ' ') && (*str != 0) )
      return 2;
  }
  else
  {
    fx0 = 25.0;
    fy0 = 50.0;
    fx1 = 75.0;
    fy1 = 100.0;
  }

  // Get resolution
  if( str = FindToolType(array,"resolution") )
  {
    resolution = strtol(str,NULL,10);
    if( (resolution <= 0) || (resolution > option->so_interResolution) )
      return 3;
  }
  else
    resolution = option->so_opticResolution;

  if( option->so_brightnessStep && (str = FindToolType(array,"brightness")) )
  {
    brightness = ((strtol(str,NULL,10)-option->so_brightnessMin)/option->so_brightnessStep)*option->so_brightnessStep+option->so_brightnessMin;
    if( (brightness < option->so_brightnessMin) || (brightness > option->so_brightnessMax) )
      return 4;
  }
  else
    brightness = option->so_brightnessDefault;

  if( option->so_contrastStep && (str = FindToolType(array,"contrast")) )
  {
    contrast = ((strtol(str,NULL,10)-option->so_contrastMin)/option->so_contrastStep)*option->so_contrastStep+option->so_contrastMin;
    if( (contrast < option->so_contrastMin) || (contrast > option->so_contrastMax) )
      return 5;
  }
  else
    contrast = option->so_contrastDefault;

  if( option->so_shadowStep && (str = FindToolType(array,"shadow")) )
  {
    shadow = ((strtol(str,NULL,10)-option->so_shadowMin)/option->so_shadowStep)*option->so_shadowStep+option->so_shadowMin;
    if( (shadow < option->so_shadowMin) || (shadow > option->so_shadowMax) )
      return 5;
  }
  else
    shadow = option->so_shadowDefault;

  if( option->so_highlightStep && (str = FindToolType(array,"highlight")) )
  {
    highlight = ((strtol(str,NULL,10)-option->so_highlightMin)/option->so_highlightStep)*option->so_highlightStep+option->so_highlightMin;
    if( (highlight < option->so_highlightMin) || (highlight > option->so_highlightMax) )
      return 6;
  }
  else
    highlight = option->so_highlightDefault;

  if( option->so_midtoneStep && (str = FindToolType(array,"midtone")) )
  {
    midtone = ((strtol(str,NULL,10)-option->so_midtoneMin)/option->so_midtoneStep)*option->so_midtoneStep+option->so_midtoneMin;
    if( (midtone < option->so_midtoneMin) || (midtone > option->so_midtoneMax) )
      return 7;
  }
  else
    midtone = option->so_midtoneDefault;

  if( option->so_halftonePatternStep && (str = FindToolType(array,"pattern")) )
  {
    halftonePattern = ((strtol(str,NULL,10)-option->so_halftonePatternMin)/option->so_halftonePatternStep)*option->so_halftonePatternStep+option->so_halftonePatternMin;
    if( (halftonePattern < option->so_halftonePatternMin) || (halftonePattern > option->so_halftonePatternMax) )
      return 8;
  }
  else
    halftonePattern = option->so_halftonePatternDefault;

  if( option->so_exposureTimeStep && (str = FindToolType(array,"time")) )
  {
    exposureTime = ((strtol(str,NULL,10)-option->so_exposureTimeMin)/option->so_exposureTimeStep)*option->so_exposureTimeStep+option->so_exposureTimeMin;
    if( (exposureTime < option->so_exposureTimeMin) || (exposureTime > option->so_exposureTimeMax) )
      return 9;
  }
  else
    exposureTime = option->so_exposureTimeDefault;

  if( option->so_maxLookupTableSize && (str = FindToolType(array,"gamma")) )
  {
    gamma = strtod(str,&str);
    if( (*str != ' ') && (*str != 0) )
      return 10;
    if( gamma <= 0.0 )
      return 10;
  }
  else
    gamma = 1.0;

  if( str = FindToolType(array,"compress") )
  {
    if( MatchToolValue(str,"on") )
      compress = 1;
    else if( MatchToolValue(str,"off") )
      compress = 0;
    else
      return 11;
  }
  else
    compress = 1;

  if( !(outputFile = FindToolType(array,"file")) )
    outputFile = "ram:scanner.ilbm";
    
  return 0;
}
