/**********************************************************************
 *     EPSCAN, an EPSON ES-1200 scanner driver     
 *     Adam P. Jenkins <ajenkins@cs.umass.edu>
 *     
 *     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.
 *
 **********************************************************************/

// implementation of SScanner and SScanSettings non-virtual members
#include <qapp.h>

#include "SScanner.h"

void
SScanSettings::setResolution(int res)
{
  // make sure it's valid
  for (int i = 0; identity.resolutions[i]; i++)
    if (identity.resolutions[i] == res) {
      settings.main_scan_res = settings.sub_scan_res = res;
      break;
    }
}

void
SScanSettings::calculate()
{
  // calculate the true vertical and horizontal offsets and lengths,
  // and the number of lines for the block size
  float real_vdpi = ((float)settings.sub_scan_res *
		     ((float)settings.sub_scan_zoom / 100.0));
  float real_hdpi = ((float)settings.main_scan_res *
		     ((float)settings.main_scan_zoom / 100.0));
  int mainlen = (int)(real_hdpi * hlength);
  int sublen = (int)(real_vdpi * vlength);
  
  int mainmax = (int)(maxHorLength() *
		      ((float)settings.main_scan_res *
		       (float)settings.main_scan_zoom / 100.0));
  int submax = (int)(maxVerLength() *
		     ((float)settings.sub_scan_res *
		      (float)settings.sub_scan_zoom / 100.0));

  settings.main_scan_offset = (int)(hoffset * real_hdpi);
  settings.sub_scan_offset = (int)(voffset * real_vdpi);
  if ((mainlen + settings.main_scan_offset) > mainmax)
    settings.main_scan_area = mainmax - settings.main_scan_offset;
  else
    settings.main_scan_area = mainlen;
  if ((sublen + settings.sub_scan_offset) > submax)
    settings.sub_scan_area = submax - settings.sub_scan_offset;
  else
    settings.main_scan_area = mainlen;

  // calculate number of lines per block
  if (settings.color_mode == SCN_CLR_COLOR_LINE)
    settings.linecounter = maxblocksize /
      ((settings.main_scan_area / (8 / settings.bits_per_pixel)) * 3);
  else
    settings.linecounter = maxblocksize /
      (settings.main_scan_area / (8 / settings.bits_per_pixel));
  if (settings.linecounter < 1)
    settings.linecounter = 1;
  else if (settings.linecounter > 255)
    settings.linecounter = 255;
}

void
SScanSettings::setSettings(ScanSettings& set)
{
  settings = set;
  defaults = set;
  float real_hdpi =
    (float)settings.main_scan_res * ((float)settings.main_scan_zoom / 100.0);
  float real_vdpi =
    (float)settings.sub_scan_res * ((float)settings.sub_scan_zoom / 100.0);
  hoffset = (float)settings.main_scan_offset / real_hdpi;
  voffset = (float)settings.sub_scan_offset / real_vdpi;
  hlength = (float)settings.main_scan_area / real_hdpi;
  vlength = (float)settings.sub_scan_area / real_vdpi;
}

// SScanner member function

SScanner::SScanner()
{
  dev = 0;
  ok = false;
}

SScanner::~SScanner()
{
  if (dev)
    delete dev;
}

int
SScanner::open(const char *device)
{
  ok = false;
  if (dev)
    delete dev;
  dev = new Scanner;
  CHECK_PTR(dev);

  if (device) {
    if (dev->open(device)) {
      fatal("Failed to open scanner device: %s", dev->strError());
      return -1;			// not reached
    }
  } else if (dev->open()) {
    fatal("Failed to find scanner device: %s", dev->strError());
    return -1;			// not reached
  }
  ScanSettings set;
  ScanIdentity id;
  dev->getSettings(set);
  dev->getIdentity(id);
  setSettings(set);
  setIdentity(id);
  
  ok = true;
  return 0;
}

void
SScanner::close()
{
  if (dev) {
    delete dev;
    dev = 0;
  }
}
    
void
SScanner::acquire(const char *fname)
{
  if (dev) {
    if (dev->applySettings(getSettings())) {
      warning("Failed to apply settings to scanner\n%s",
	      dev->strError());
      ok = false;
      return;
    }
    
    QApplication::setOverrideCursor(waitCursor);
    int ret = dev->startScan(fname);
    QApplication::restoreOverrideCursor();
    if (ret) {
      warning("Scanning Failed\n%s", dev->strError());
      ok = false;
    } else {
      // show message saying scanning done
      ok = true;
    }
  }
}
