/*   input routines using ASCII mode digitizer   */


#include "objects.h"
#include <string.h>
#include <stdio.h>


int digi_valid = 0;

static FILE *serialport = NULL;

static double offsetx, offsety, factorx, factory;  /* digitizer -> map coordinates */
static double a, b, c, d;    /* conversion matrix */
static double x, y;          /* map origin offset in cm */
static int u, v;             /* and in digitizer pixels */

extern double mapWidthcm, mapHeightcm;   /* declared in map.c */
extern LOCATION map_origin;              /* declared in coord.c */

/* wait for button and get position, return button number */

int digi_getpos (int *x, int *y)
{
  char line[256];
  int readx, ready, readbutton;

  fgets (line, 255, serialport);

  sscanf (line, "%d,%d,%d", &readx, &ready, &readbutton);

  *x = readx;
  *y = ready;

  return readbutton;
}


/*
   calibrate digitizer so that current map can be treated
   parameters: the two reference points that have to be 'shot at'
*/


void digi_calibrate (LOCATION ref1, LOCATION ref2)
{
  int u1, v1, u2, v2;     /* digitizer coordinations of reference points */
  double x1, y1, x2, y2;  /* map coordinates (cm) of the same reference points */

  /* init map data */

  mapWidthcm = mapHeightcm = 20;   /* ca. size of map */
  map_initcoord(); 


  /* check if digitier input file is open, if not: open it */

  if (!serialport)
    {
      serialport = fopen ("/dev/podscat", "r");
    }

  if (!serialport)
    {
      puts ("Unable to open digitzer input port!");
    }
  else
  {
    puts ("\ndigitizer calibration:");
    printf ("Please move to map origin (%s) and press a button!\n",
	    internal2string (map_origin));
    digi_getpos (&u, &v);

    printf ("Please move to %s and press a button!\n",
	    internal2string (ref1));
    digi_getpos (&u1, &v1);

    printf ("Please move to %s and press a button!\n",
	    internal2string (ref2));
    digi_getpos (&u2, &v2);

    /* get respective map coordinates (in cm) of the origin and reference points */

    internal2cm (map_origin, &x, &y);
    internal2cm (ref1, &x1, &y1);
    internal2cm (ref2, &x2, &y2);

    offsetx = x-u;    /* translate to map origin */
    offsety = y-v;

    /* get digitizer and cm coordinates of reference points relativ to map origin */

    u1 -= u;  u2 -= u;     x1 -= x;  x2 -= x;
    v1 -= v;  v2 -= v;     y1 -= y;  y2 -= y;


    /* calculate matrix of conversion function */

    a =  -(v1*x2-v2*x1) / (-v1*u2+v2*u1);
    b = -(-v2*y1+y2*v1) / (-v1*u2+v2*u1);
    c =   (u1*x2-x1*u2) / (-v1*u2+v2*u1);
    d =  (-u2*y1+u1*y2) / (-v1*u2+v2*u1);


    puts ("Thank you, calibration was successful!\n");
    digi_valid = 1;
  }
}


int is_digi_valid()
{
  return digi_valid;
}



/*
   read coordinates from digitizer using current map attributes
*/

LOCATION digi_input()
{
  int xx, yy, bb;
  double xcm, ycm;

  bb = digi_getpos (&xx, &yy);
  xx -= u;
  yy -= v;

/*  printf ("Position: (%d,%d) button: %d\n", xx, yy, bb);  */

  xcm = a*xx+c*yy + x;
  ycm = b*xx+d*yy + y;

  printf ("%s\n", cm2string (xcm, ycm));
  digi_input();

  return cm2internal(xcm, ycm);
}

