/*
  Copyright (C) 2000 by Adrian Perez Jorge

  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, see <https://www.gnu.org/licenses/>.
 */

#ifndef _HP4200_H
#define _HP4200_H

#include <sys/types.h>

#define MCLKDIV_SCALING 2
#define NUM_REGISTERS 0x80

#define min(a, b) (((a) < (b)) ? (a) : (b))
#define max(a, b) (((a) > (b)) ? (a) : (b))


/*--------------------------------------------------------------------------*/

#define DBG_error0  0
#define DBG_error   1
#define DBG_sense   2
#define DBG_warning 3
#define DBG_inquiry 4
#define DBG_info    5
#define DBG_info2   6
#define DBG_proc    7
#define DBG_read    8
#define DBG_sane_init   10
#define DBG_sane_proc   11
#define DBG_sane_info   12
#define DBG_sane_option 13

/*--------------------------------------------------------------------------*/

enum HP4200_Option
{
  OPT_NUM_OPTS = 0,

  OPT_RES,

  OPT_TL_X,			/* top-left x */
  OPT_TL_Y,			/* top-left y */
  OPT_BR_X,			/* bottom-right x */
  OPT_BR_Y,			/* bottom-right y */

  OPT_BACKTRACK,

  OPT_GAMMA_VECTOR_R,
  OPT_GAMMA_VECTOR_G,
  OPT_GAMMA_VECTOR_B,

  OPT_PREVIEW,

  NUM_OPTIONS			/* must come last */
};

/* already declared in the sane includes...
typedef union
{
	SANE_Word w;
	SANE_Bool b;
	SANE_Fixed f;
	SANE_Word *wa;
}
Option_Value;
*/

enum ScannerModels
{
  HP4200
};

typedef struct HP4200_Device
{
  struct HP4200_Device *next;
  SANE_Device dev;
  SANE_Handle handle;
}
HP4200_Device;

struct _scanner_buffer_t
{
  unsigned char *buffer;	/* buffer memory space */
  int size;			/* size of the buffer */
  int num_bytes;		/* number of bytes left (to read) */
  unsigned char *data_ptr;	/* cursor in buffer */
};

typedef struct _scanner_buffer_t scanner_buffer_t;

struct _ciclic_buffer_t
{
  int good_bytes;		/* number of valid bytes of the image */
  int num_lines;		/* number of lines of the ciclic buffer */
  int size;			/* size in bytes of the buffer space */
  unsigned char *buffer;	/* pointer to the buffer space */
  unsigned char **buffer_ptrs;	/* pointers to the beginning of each
				   line in the buffer space */
  int can_consume;		/* num of bytes the ciclic buf can consume */
  int current_line;		/* current scanned line */
  int first_good_line;		/* number of lines to fill the ``pipeline'' */
  unsigned char *buffer_position;	/* pointer to the first byte that
					   can be copied */
  int pixel_position;		/* pixel position in current line */

  /* color indexes for the proper line in the ciclic buffer */
  int red_idx;
  int green_idx;
  int blue_idx;
};

typedef struct _ciclic_buffer_t ciclic_buffer_t;

struct _hardware_parameters_t
{
  unsigned int SRAM_size;
  unsigned char SRAM_bandwidth;
  unsigned long crystal_frequency;
  unsigned int min_pixel_data_buffer_limit;
  unsigned int motor_full_steps_per_inch;
  float motor_max_speed;
  unsigned int scan_bar_max_speed;
  unsigned int start_of_scanning_area;
  unsigned int calibration_strip_height;
  unsigned int scan_area_width;
  double scan_area_length;	/* in inches */
  unsigned int sensor_num_pixels;
  unsigned int sensor_pixel_start;
  unsigned int sensor_pixel_end;
  int sensor_cds_state;		/* 0 == off, 1 == on */
  int sensor_signal_polarity;	/* 0 == ??, 1 == ?? */
  int sensor_max_integration_time;
  int sensor_line_separation;
  int sensor_type;
  unsigned int sensor_resolution;
  int sensor_control_signals_polarity;
  int sensor_control_signals_state;
  int sensor_control_pixel_rate_timing;
  int sensor_control_line_rate_timing;
  unsigned int sensor_black_clamp_timing;	/* ??? */
  unsigned int sensor_CIS_timing;
  int sensor_toshiba_timing;
  int sensor_color_modes;	/* bitmask telling color modes supported */
  int illumination_mode;
  int motor_control_mode;
  int motor_paper_sense_mode;
  int motor_pause_reverse_mode;
  int misc_io_mode;
  int num_tr_pulses;
  int guard_band_duration;
  int pulse_duration;
  int fsteps_25_speed;
  int fsteps_50_speed;
  int steps_to_reverse;
  struct
  {
    int red;
    int green;
    int blue;
  }
  target_value;
  unsigned short home_sensor;
};

typedef struct _hardware_parameters_t hardware_parameters_t;

struct _user_parameters_t
{
  unsigned int image_width;
  unsigned int lines_to_scan;
  unsigned int horizontal_resolution;
  unsigned int vertical_resolution;
  int hres_reduction_method;	/* interpolation/??? */
  int vres_reduction_method;
  SANE_Bool color;		/* color/grayscale */
  int bpp;
  int scan_mode;		/* preview/full scan */
  SANE_Bool no_reverse;
  SANE_Word gamma[3][1024];	/* gamma table for rgb */
};

typedef struct _user_parameters_t user_parameters_t;

struct _measured_parameters_t
{
  unsigned int datalink_bandwidth;
  struct
  {
    int red;
    int green;
    int blue;
  }
  coarse_calibration_data;
  struct
  {
    int *pRedOffset;
    int *pGreenOffset;
    int *pBlueOffset;
    int *pRedGain;
    int *pGreenGain;
    int *pBlueGain;
  }
  fine_calibration_data;
  int max_integration_time;
  int color_mode;
};

typedef struct _measured_parameters_t measured_parameters_t;

struct _runtime_parameters_t
{
  long num_bytes_left_to_scan;
  int status_bytes;		/* number of status bytes per line */
  int image_line_size;		/* line size in bytes without status bytes */
  int scanner_line_size;	/* line size in bytes including the
				   status bytes */
  int first_pixel;		/* first pixel in the line to be scanned */
  int steps_to_skip;
};

typedef struct _runtime_parameters_t runtime_parameters_t;

struct _HP4200_Scanner
{
  struct _HP4200_Scanner *next;

  SANE_Option_Descriptor opt[NUM_OPTIONS];
  Option_Value val[NUM_OPTIONS];

  SANE_Bool scanning;
  SANE_Bool aborted_by_user;

  SANE_Parameters params;

  HP4200_Device *dev;
  hardware_parameters_t hw_parms;
  user_parameters_t user_parms;
  measured_parameters_t msrd_parms;
  unsigned int regs[NUM_REGISTERS];
  int mclk;
  float mclk_div;

  int fd;

  ciclic_buffer_t ciclic_buffer;
  scanner_buffer_t scanner_buffer;
  runtime_parameters_t runtime_parms;
};

typedef struct _HP4200_Scanner HP4200_Scanner;

#endif /* !_HP4200_H */
