/******************************************************************************
** <AUTO>
**   FILE: tclCompletetile.c
**   ABSTRACT:
** <HTML>
**   Routines to assign objects to fibers on each plate
** </HTML>
** </AUTO>
*******************************************************************************/
/******************************************************************************
 *
 * TCL verbs 				installed in target:
 *
 *              taWithinFiberSpacing	June 23, 1999
 *              taOnPlate		July 06, 1999
 *
 *                             Dan Vanden Berk and Heidi Newberg
 *
 ******************************************************************************/

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
#include "dervish.h"
#include "taCompletetile.h"

static char *module = "ta";   /* name of this set of code */

/******************************************************************************
 *                    tclWithinFiberSpacing                                   *
 ******************************************************************************/

/******************************************************************************
*******************************************************************************
** <AUTO EXTRACT>
**  TCL VERB: taWithinFiberSpacing
**
**  <HTML>
**  C ROUTINE CALLED:
**		<A HREF=taCompletetile.html#taWithinFiberSpacing>
**                 taWithinFiberSpacing</A> in taCompletetile.c
**
** <P>
**      Determine whether a given object can be assigned a fiber on this
**      plate.
**
**      Returns 1 if the object is within fiberspacing of any object in
**      chain of PLUGMAPOBJs or too near the center hole.
**      Returns 0 otherwise.
**
**  </HTML>
**
** </AUTO>
*******************************************************************************
*******************************************************************************/

static ftclArgvInfo taWithinFiberSpacingTable[] = {
  {NULL,          FTCL_ARGV_HELP, NULL, NULL,
  "Returns 0 if the fiber for the targetobject can be placed on\n"
  "a plate on which plugobjs have already been placed"},
  {"<targetobj>", FTCL_ARGV_STRING, NULL, NULL, "target object of type TARGETOBJ"},
  {"<plugobjs>", FTCL_ARGV_STRING, NULL, NULL, "chain of type PLUGMAPOBJ"},
  {"<raCen>", FTCL_ARGV_DOUBLE, NULL, NULL, "RA of plate center"},
  {"<decCen>", FTCL_ARGV_DOUBLE, NULL, NULL, "dec of plate center"},
  {"<fiberspacing>", FTCL_ARGV_DOUBLE, NULL, NULL, "minimum dist in deg between 2 fibers"},
  {"<centerholeradius>", FTCL_ARGV_DOUBLE, NULL, NULL, "minimum dist to plate center hole in deg"},
  {(char *) NULL, FTCL_ARGV_END, NULL, NULL, (char *) NULL}
};
static char *taWithinFiberSpacing_name = "taWithinFiberSpacing";

static int
tclWithinFiberSpacing(
                ClientData clientData,
                Tcl_Interp *interp,
                int argc,
                char **argv
                )
{
                                /* INPUT */
  char *targetobjName;          /* targetobj name */
  TARGETOBJ *targetobj = NULL; /* pointer to the timeStamp */
  double raCen, decCen;         /* position of center of plate */
  double fiberspacing, centerholeradius; /* spacing parameters */
  char *plugobjsName;           /* name of plugobjs chain */
  CHAIN *plugobjs = NULL;       /* pointer to chain of PLUGOBJs */
                                /* OUTPUT */
  int logicalanswer;		/* result of taWithinFiberSpacing */
  int returnValue=0;            /* info on atAirmassFind performance */
                                /* 0= ok, 1= wrong */

  char answer[40];              /* sent back to Tcl */


/* Parse the command */

  taWithinFiberSpacingTable[1].dst = &targetobjName;
  taWithinFiberSpacingTable[2].dst = &plugobjsName;
  taWithinFiberSpacingTable[3].dst = &raCen;
  taWithinFiberSpacingTable[4].dst = &decCen;
  taWithinFiberSpacingTable[5].dst = &fiberspacing;
  taWithinFiberSpacingTable[6].dst = &centerholeradius;

  if ((returnValue = shTclParseArgv(
        interp, &argc, argv, taWithinFiberSpacingTable, FTCL_ARGV_NO_LEFTOVERS, taWithinFiberSpacing_name))
                                                != FTCL_ARGV_SUCCESS) {
        return(returnValue);
  }

/* translate handles */
    if (shTclAddrGetFromName
		(interp, targetobjName, (void **) &targetobj, "TARGETOBJ") != TCL_OK) {
      Tcl_AppendResult
        	(interp, "taWithinFiberSpacing: bad targetobj name", NULL);
      return TCL_ERROR;
    }
    if (shTclAddrGetFromName
		(interp, plugobjsName, (void **) &plugobjs, "CHAIN") != TCL_OK) {
      Tcl_AppendResult
        	(interp, "taWithinFiberSpacing: bad targetobj name", NULL);
      return TCL_ERROR;
    }
    /* Verify that chain is for PLUGMAPOBJ */
    if (shChainTypeGet(plugobjs) != shTypeGetFromName("PLUGMAPOBJ")) {
      Tcl_AppendResult(interp, taWithinFiberSpacing_name,
                       ": input CHAIN not of type PLUGMAPOBJ", NULL);
      return TCL_ERROR;
    }


/************************************
 * 
 *   Do the actual call 
 * 
 ************************************
 */

/* send back the answer */
  logicalanswer = taWithinFiberSpacing(targetobj, plugobjs, raCen, decCen, fiberspacing, centerholeradius);
  if (logicalanswer < 0) {
      Tcl_SetResult (interp, "taWithinFiberSpacing: error", TCL_VOLATILE);
      return TCL_ERROR;
  }

  sprintf(answer, "%d", logicalanswer);
  Tcl_SetResult(interp, answer, TCL_VOLATILE);

  return TCL_OK;
}

/*********************************************************************/
/*void taTclCompletetileDeclare( Tcl_Interp *interp) {
*/
/*
*/
/*  shTclDeclare(
*/
/*               interp,
*/
/*               taWithinFiberSpacing_name,
*/
/*               (Tcl_CmdProc *)tclWithinFiberSpacing,
*/
/*               (ClientData) 0,
*/
/*               (Tcl_CmdDeleteProc *)NULL,
*/
/*               module,
*/
/*               shTclGetArgInfo(interp, taWithinFiberSpacingTable,
*/
/*                 FTCL_ARGV_NO_LEFTOVERS, taWithinFiberSpacing_name),
*/
/*               shTclGetUsage(interp, taWithinFiberSpacingTable,
*/
/*                 FTCL_ARGV_NO_LEFTOVERS, taWithinFiberSpacing_name));
*/
/*
*/
/*}
*/

/******************************************************************************
 *                              tclOnPlate                                    *
 ******************************************************************************/

/******************************************************************************
** <AUTO EXTRACT>
**  TCL VERB: taOnPlate
**
**  <HTML>
**  C ROUTINE CALLED:
**                <A HREF=taCompletetile.html#taOnPlate>taOnPlate</A>
**      in taCompletetile.c
**
**  <P>
**      Determine whether a given object is within the area covered by a plate.
**
**      Returns 1 if the object is within the plate area.
**      Returns 0 otherwise.
**
**  </HTML>
**
** </AUTO>
*******************************************************************************/

static ftclArgvInfo taOnPlateTable[] = {
  {NULL, FTCL_ARGV_HELP, NULL, NULL,
    "Returns 1 if the targetobject can be placed within\n"
    "the area covered by the plate"},
  {"<targetobj>", FTCL_ARGV_STRING, NULL, NULL,
    "target object of type TARGETOBJ"},
  {"<raCen>", FTCL_ARGV_DOUBLE, NULL, NULL, "RA of plate center in degrees"},
  {"<decCen>", FTCL_ARGV_DOUBLE, NULL, NULL, "dec of plate center in degrees"},
  {"<plateradius>", FTCL_ARGV_DOUBLE, NULL, NULL,
    "plate radius in degrees"},
  {(char *) NULL, FTCL_ARGV_END, NULL, NULL, (char *) NULL}
};
static char *taOnPlate_name = "taOnPlate";

static int
tclOnPlate(
           ClientData clientData,
           Tcl_Interp *interp,
           int argc,
           char **argv
           )
{
                                /* INPUT */
  char *targetobjName;          /* targetobj name */
  TARGETOBJ *targetobj = NULL; /* pointer to the timeStamp */
  double raCen, decCen;         /* position of center of plate */
  double plateradius; 		/* spacing parameter */
                                /* OUTPUT */
  int logicalanswer;            /* result of taOnPlate */
  int returnValue=0;            /* info on (somthing or other)*/
                                /* 0= ok, 1= wrong */

  char answer[40];              /* sent back to Tcl */


/* Parse the command */

  taOnPlateTable[1].dst = &targetobjName;
  taOnPlateTable[2].dst = &raCen;
  taOnPlateTable[3].dst = &decCen;
  taOnPlateTable[4].dst = &plateradius;

  if ((returnValue = shTclParseArgv(
        interp, &argc, argv, taOnPlateTable, FTCL_ARGV_NO_LEFTOVERS,
        taOnPlate_name)) != FTCL_ARGV_SUCCESS) {
        return(returnValue);
  }

/* translate handle */
    if (shTclAddrGetFromName
          (interp, targetobjName, (void **) &targetobj, "TARGETOBJ")
        != TCL_OK) {
      Tcl_AppendResult
                (interp, "taOnPlate: bad targetobj name", NULL);
      return TCL_ERROR;
    }


/************************************
 *   Do the actual call
 ************************************
 */

/* send back the answer */
  logicalanswer = taOnPlate(targetobj, raCen, decCen, plateradius);
  if (logicalanswer < 0) {
      Tcl_SetResult (interp, "taOnPlate: error", TCL_VOLATILE);
      return TCL_ERROR;
  }

  sprintf(answer, "%d", logicalanswer);
  Tcl_SetResult(interp, answer, TCL_VOLATILE);

  return TCL_OK;
}

/*********************************************************************/
void taTclCompletetileDeclare( Tcl_Interp *interp) {

  shTclDeclare(interp, taOnPlate_name,
               (Tcl_CmdProc *)tclOnPlate,
               (ClientData) 0,
               (Tcl_CmdDeleteProc *)NULL,
               module,
               shTclGetArgInfo(interp, taOnPlateTable,
                 FTCL_ARGV_NO_LEFTOVERS, taOnPlate_name),
               shTclGetUsage(interp, taOnPlateTable,
                 FTCL_ARGV_NO_LEFTOVERS, taOnPlate_name));
  shTclDeclare(
               interp, taWithinFiberSpacing_name,
               (Tcl_CmdProc *)tclWithinFiberSpacing,
               (ClientData) 0,
               (Tcl_CmdDeleteProc *)NULL,
               module,
               shTclGetArgInfo(interp, taWithinFiberSpacingTable,
                 FTCL_ARGV_NO_LEFTOVERS, taWithinFiberSpacing_name),
               shTclGetUsage(interp, taWithinFiberSpacingTable,
                 FTCL_ARGV_NO_LEFTOVERS, taWithinFiberSpacing_name));
}
