#ifndef TS_MERGE_H
#define TS_MERGE_H

#include "tsMatchStats.h"
#include <arObject.h>
#include <dervish.h>

// An objects status in relation to its location in the field
enum tsRange
{
  TS_IN,                      // In this field's primary range of rows
  TS_OUT,                     // Out of this field's primary range of rows
  TS_DUPLICATE                // Duplicates object in adjacent field (could be
                              // either in or out of primary range).
};

// An uncalibrated object, with temporary status variables.
typedef struct tsObject
{
  int index;                  // index to handle in associated ooTVArray
  int bright;		      // 1="bright" object, 0="faint"
  double row;                 // scan row position (pixels)
  double col;                 // scan col position (pixels)
} TSOBJ;

// An object with its calibrated survey position.
typedef struct tsCalibObject
{
  int index;                  // index to handle in associated ooTVArray
  double mu;                  // great circle longitude (degrees)
  double nu;                  // great circle latitude (degrees)
} TSCALIBOBJ;

class ooHandle(arObjectList);
class ooHandle(arAstromCalib);
class ooHandle(arFinalPhotoCalib);

declare(ooTVArray,ooHandle(arObject));

// Prototypes
void tsMatchStatsInit(TSMATCHSTATS *stats);
RET_CODE tsFieldUnsetObjectStatus(ooHandle(arObjectList)& field);
RET_CODE tsFieldUnmerge(ooHandle(arObjectList)& field);
RET_CODE tsFieldMatchStatsByPixel(const ooHandle(arObjectList)& field,
				  const ooHandle(arObjectList)& other,
				  int rowsPerField,
				  double nSigma,
				  TSMATCHSTATS *stats,
				  int noBlends);
RET_CODE tsFieldMatchStatsByArcsec(const ooHandle(arObjectList)& field,
			      const ooHandle(arAstromCalib)& fieldCalib,
			      const ooHandle(arFinalPhotoCalib)& fieldFinal,
			      double fieldExpTime,
			      const ooHandle(ooDBObj)& other,
			      uint8 otherCamCol,
			      const ooHandle(arAstromCalib)& otherCalib,
			      const ooHandle(arFinalPhotoCalib)& otherFinal,
			      double otherExpTime,
			      double minMag,
			      double maxMag,
			      char magFilter,
			      TSMATCHSTATS *stats,
			      CHAIN *starChain,
			      CHAIN *galaxyChain,
			      int full,
			      int noBlends);
int tsObjectStatusSet(const ooHandle(arObjectList)& field,
		      int rowsPerField,
		      int overlapRows,
		      double matchRadius,
		      double nSigma,
		      ooTVArray(ooHandle(arObject)) **handles,
		      TSOBJ **array,
		      TSMATCHSTATS *stats);
void tsSelfMerge(ooTVArray(ooHandle(arObject)) *handles,
		 TSOBJ *array,
		 ooTVArray(ooHandle(arObject)) *previousHandles,
		 TSOBJ *previousArray,
		 double matchRadius,
		 double rowMin,
		 double rowMax,
		 TSMATCHSTATS *stats);
int tsRunToCalibArray(const ooHandle(arFramesPipeRun)& run,
		      const ooHandle(arAstromCalib)& astrom,
		      ooTVArray(ooHandle(arObject)) **handles,
		      TSCALIBOBJ **array,
		      double *minNu,
		      double *maxNu);
RET_CODE tsRunMergeOne(ooTVArray(ooHandle(arObject)) *handles,
		       TSCALIBOBJ *array,
		       int nObjects,
		       double minNu,
		       double maxNu,
		       double node,
		       double incl,
		       double equinox,
		       ooHandle(arFramesPipeRun)& other,
		       double matchRadius);

#endif
