// $Header: https://oberon.oapd.inaf.it/shins/trunk/shins/src/obs_ctrl/obsControl.ice 3989 2022-07-06 16:55:20Z depa $

#ifndef _OBS_CONTROL_ICE_
#define _OBS_CONTROL_ICE_

#include <sharknir.ice>
#include "System.ice"
#include <LbtoIIFInterface.ice>

module sharknir
{
  module obsControl
  {
      sequence<byte> SeqByte;
      ["cpp:comparable"]
      class DiagnosticRecordVar {
                int frameCounter;
                SeqByte slopeRecord;
                SeqByte asmRecord;
                SeqByte ccdRecord;
      };

      class DiagnosticRecord extends DiagnosticRecordVar{
            int getFrameCounter();
            SeqByte getSlopeRecord();
            SeqByte getAsmRecord();
            SeqByte getCcdRecord();
            int setFrameCounter(int fc);
            int setSlopeRecord(SeqByte sr);
            int setAsmRecord(SeqByte ar);
            int setCcdRecord(SeqByte cr);
      };

      sequence<DiagnosticRecord> SeqDiagnosticRecord;

	exception SashaTimeoutException {};
    /**
    Interface for seq component, calling methods from obs_ctrl
    **/
    interface Sequencer 
    {
      /**
      gets position from devices listed in in/out dictionary
      @param unit: optional, the string with the unit ins which position is asked
      @param dictPosition: out parameter, a dictionary string,double with
                           device name, position
      **/
      int getPosition (optional(1) string unit,
                       sharknir::dictSetupPos inDictPosition,
                       out sharknir::dictSetupPos outDictPosition);

      int osLogBanner(string banner);

      int setFlags(int flags, int moreFlags);
      int unsetFlags(int flags, int moreFlags);
      int toggleFlags(int flags, int moreFlags);

      int getStatus(sharknir::dictStatus inDictStatus, out sharknir::dictStatus outDictStatus);
      int getJsonStatus(out string jsonStatus);

      int getInternalSeqFloatVariable(string var, out sharknir::SeqFloat result);
      int setContext(sharknir::dictSetupNamedPos osContext);
      int setLampsStatus(sharknir::dictSetupNamedPos osLampsStatus);
      string getCurrentDataDirectory();

      //////////////////
      // CALUNIT CTRL //
      //////////////////
      /**
      Initialize calibration unit devices from input sequence
      @param vecDevAlias, sequence of strings with device TaN alias
      **/
      int initCalibUnit     (sharknir::SeqString vecDevAlias);

      /**
      Start initialization of calibration unit devices from input sequence.
      used for asynch use
      @param vecDevAlias, sequence of strings with device TaN alias
      **/
//      int initCalibUnitStart(sharknir::SeqString vecDevAlias);

      /**
      Wait for initialization of calibration unit devices from input sequence
      to finish. Used for asynch use.
      @param vecDevAlias, sequence of strings with device TaN alias
      @param time, long optional time to wait
      **/
//      int initCalibUnitWait (sharknir::SeqString vecDevAlias, optional(1) long time);

      /**
      Initialize all calibration unit devices
      **/
      int initCalibUnitAll();

      /**
      Start initialization of all calibration unit devices.
      used for asynch use.
      **/
//      int initCalibUnitAllStart();

      /**
      Wait for initialization of all calibration unit devices
      to finish. Used for asynch use.
      @param time, long optional time to wait
      **/
//      int initCalibUnitAllWait(optional(1) long time);

      /**
      Setup desired calibration unit devices to position
      @param dSetupPos: string, double dictionary with TaN alias name of devices
                        and the corresponding position  in steps.
      **/
      int setupCalibUnitDict(sharknir::dictSetupPos dSetupPos);

      /////////////////
      // MOTION CTRL //
      /////////////////
      /**
      Initialize motion unit devices from input sequence
      @param vecDevAlias, sequence of strings with device TaN alias
      **/
      int initMotion     (sharknir::SeqString vecDevAlias);

      /**
      Start initialization of motion unit devices from input sequence.
      used for asynch use
      @param vecDevAlias, sequence of strings with device TaN alias
      **/
//      int initMotionStart(sharknir::SeqString vecDevAlias);

      /**
      Wait for initialization of motion unit devices from input sequence
      to finish. Used for asynch use.
      @param vecDevAlias, sequence of strings with device TaN alias
      @param time, long optional time to wait
      **/
//      int initMotionWait (sharknir::SeqString vecDevAlias, optional(1) long time);

      /**
      Initialize all motion unit devices
      **/
      int initMotionAll();

      /**
      Start initialization of all motion unit devices.
      used for asynch use.
      **/
//      int initMotionAllStart();

      /**
      Wait for initialization of all motion unit devices
      to finish. Used for asynch use.
      @param time, long optional time to wait
      **/
//      int initMotionAllWait(optional(1) long time);

      /**
      Setup desired calibration unit devices to position
      @param dSetupPos: string, double dictionary with TaN alias name of devices
                        and the corresponding position  in steps.
      **/
//      int setupMotionDict(sharknir::dictSetupPos dSetupPos);

      int moveDeviceToNegativeLimit(sharknir::SeqString vecDevAlias);
      int moveDeviceToPositiveLimit(sharknir::SeqString vecDevAlias);
      ////////////////
      // TRACK CTRL //
      ////////////////
      /**
      Initialize tracking unit devices from input sequence
      @param vecDevAlias, sequence of strings with device TaN alias
      **/
      int initTracking     (sharknir::SeqString vecDevAlias);

      /**
      Start initialization of tracking unit devices from input sequence.
      used for asynch use
      @param vecDevAlias, sequence of strings with device TaN alias
      **/
//      int initTrackingStart(sharknir::SeqString vecDevAlias);

      /**
      Wait for initialization of tracking unit devices from input sequence
      to finish. Used for asynch use.
      @param vecDevAlias, sequence of strings with device TaN alias
      @param time, long optional time to wait
      **/
//      int initTrackingWait (sharknir::SeqString vecDevAlias, optional(1) long time);

      /**
      Initialize all tracking unit devices
      **/
      int initTrackingAll();

      /**
      Start initialization of all tracking unit devices.
      used for asynch use.
      **/
//      int initTrackingAllStart();

      /**
      Wait for initialization of all tracking unit devices
      to finish. Used for asynch use.
      @param time, long optional time to wait
      **/
//      int initTrackingAllWait(optional(1) long time);

      /**
      Make tracking devices to start tracking
      @param secondsToStart: optional long, time interval in seconds after which tracking have to start
      @param position: optional double, starting position for tracking
      @param unit: optional string, unir for position parameter
      **/
//      int trackingStart(optional(1) long secondsToStart, optional(2) dictSetupPos position, optional(3) dictDevUnit unit);
      int trackingStart2(double dateMjd, double position);
      int trackingStart();
      int trackingTestStart(double startPosDegree, double endPosDegree, double speedDegreeSec);
      int resetPosition(string devAlias);


      /**
      Make trac devices to start tracking for the present position
      **/
//      int trackingStartHere();

      /**
      Wait tracking devices for specified time
      @param time: optional long, time to wait in seconds
      **/
      int trackingWait(optional(1) long time);

      /**
      Stop motion of tracking devices
      **/
      int trackingStop();

      /**
      Abort motion of tracking devices. To be used in emergency
      **/
      int trackingAbort();

      /**
      Setup desired tracking unit devices to position
      @param dSetupPos: string, double dictionary with TaN alias name of devices
                        and the corresponding position  in steps.
      **/
      int setupTracking(sharknir::dictTrackingMode dTrackingModes);

      /**
      Provide information on motion state for specified tracking devices:
      true if moving, false otherwise
      @param mapDev: out string, bool dictionary with TaN alias as key
      **/
      int trackingIsMoving(out sharknir::dictIsMoving mapDev);


      int setDerotationParameters1(int numPolynomials, double samplingRate, double frequency);
      int setDerotationParameters2(int polynomialOrder, int faultTolerance, int samplesPerSegment);
      int setDerotationParameters3(double debug1, double debug2, double debug3);
      int setDerotationParameters4(double debug1, double debug2, double debug3);
      int sharkDerotatorBacklashProcedure();
      int setAdcCorrectionParameters(double co, double p0, double p1, double t0, double t1);
      int setAdcCoRotationOffset(double corotation);
      int setAdcCounterRotationOffset(double counterrotation);


      /////////////////////
      // INSTRUMENT WIDE //
      /////////////////////
      int changeState(string state, optional(1) sharknir::SeqString vecDevAlias);

      int initInstrument();
//      int initInstrumentStart();
//      int initInstrumentWait(optional(1) long time);

      int moveDevices(sharknir::dictSetupNamedPos dSetupNamedPos);
      int moveDevicesStart(sharknir::dictSetupNamedPos dSetupNamedPos);
      int moveDevicesWait();

      int setupInstrument(sharknir::dictSetupNamedPos dSetupNamedPos);

//      int setupInstrumentRelativePosition      (sharknir::dictSetupPos dSetupPos, optional(1) sharknir::dictDevUnit dUnit);

      int parkInstrument(optional(1) sharknir::dictSetupPos dSetupPos, optional(2) sharknir::dictDevUnit dUnit);

      ///////////////////////
      // REAL-TIME TIPTILT //
      ///////////////////////
      int RTCTTInit(sharknir::dictTipTiltSetup dictTipTiltSetup);
      int RTCTTSetup();
      int RTCTTStart();
      int RTCTTSwitchCcdMode(sharknir::dictTipTiltSetup dtiptiltSetup);
      int RTCTTResetBCU();
      int RTCTTIsInit(out bool isInit);
      int RTCTTSetCentroidPos(float centroidX, float centroidY);
      int RTCTTStop();
      int RTCTTModeUpload(sharknir::SeqFloat modes, bool absolute);
      int RTCTTConfigCamera(sharknir::dictTipTiltSetup dictTipTiltSetup);
      int RTCTTEnableLoop(sharknir::dictTipTiltSetup dictTipTiltSetup);
      int RTCTTCloseLoop();
      int RTCTTOpenLoop();
      int RTCTTEnableDiagnostic(sharknir::dictTipTiltSetup dictTipTiltSetup);
      int RTCTTGetDiagnostics(int nMaxRecords, out sharknir::obsControl::SeqDiagnosticRecord diagnosticRecord);
      int RTCTTTeccamExpose(sharknir::dictDetSetup dSashaSetup, out string fileName);
      int RTCTTExecuteSetup(sharknir::dictTipTiltSetup execSetup);

      ///////////////////////
      // RTC - LOW LEVEL //
      ///////////////////////
      int RTCTTSendCameraCommand(string command, out string reply);
      int RTCTTRead(int address, int size, string memory, out sharknir::SeqInt readData);
      int RTCTTReadSingle(int address, int size, string memory, out sharknir::SeqFloat readData);
      int RTCTTWrite(sharknir::SeqInt command, int address, string memory);
      int RTCTTWriteSingle(sharknir::SeqFloat command, int address, string memory);


      /* Time History related */
      int RTCTTWriteTimeHistory(sharknir::dictTipTiltSetup dictTipTiltSetup);
      int RTCTTEnableTimeHistory(sharknir::dictTipTiltSetup dictTipTiltSetup);


      ////////////////////
      // STOP AND ABORT //
      ////////////////////
      // emergency abort all devices in motion
      int emergencyAbortAll();

      int stopMotion(sharknir::SeqString vecDevAlias);
      int abortMotion(sharknir::SeqString vecDevAlias);
      ////////////////
      // SASHA CTRL //
      ////////////////
      // scientific camera related operations

      int sashaSetup(sharknir::dictDetSetup dSashaSetup);
      int sashaSetFrequency(sharknir::dictDetSetup dSashaSetup);
      int sashaExpose(out sharknir::SeqString outFiles);
      int sashaAbortExposure();
      int sashaEnableSave(sharknir::dictDetSetup dSashaSetup);
      int sashaGetFitsFileSync(sharknir::dictDetSetup dSashaSetup, string remotePathToWatch, out string fileName);
      ["amd"] int sashaGetFitsFile(sharknir::dictDetSetup dSashaSetup, string remotePathToWatch, out string fileName) throws SashaTimeoutException;

      int sashaGetIndiMsges(sharknir::dictDetSetup dSashaSetup);

      //////////////////
      // DATA MANAGER //
      //////////////////
      int datamgrCreateEmptyFile(string infileName, out string outFilename);
      int datamgrPrintFITS(string key,
                           string value,
                           optional(1) string comment,
                           optional(2) string filename);

      int datamgrMergeHeaders(optional(1) string filenameOrig,
                              optional(2) string filenameNew);
      idempotent int datamgrArchiveFITS(optional(1) string fitsFileAbsName);

      ///////////////
      // TELESCOPE //
      ///////////////

      idempotent int BinocularControl(string flag);

      int OffsetPointing(sharknir::dictTelescopeSetup dTelSup);

      int PresetTelescope(sharknir::dictTelescopeSetup dTelSup);
      int RunAO(sharknir::dictTelescopeSetup dTelSup);
      // int RunAO(string mode);

      // SendWavefront
      // input:
      // - Zernike polynomial coefficients (vector of double)
      // - optical element (string)
      int SendWavefront(lbto::SeqWF polynom, string ope);

      /* MoveFocus
       * input:
       * - focus absolute position (mm)
       * - optical element (string)
       */
      int MoveFocus(double absPos, string ope);


      /* Offset AO */
      int OffsetZAO(double deltaz, string side);
      int OffsetXYAO(double DeltaX, double DeltaY, string  side);


      int ApplyWaffleAO(sharknir::dictTelescopeSetup dTelSup);

      int pointingCorrectionStart(float freq, out int thrdID);
      int pointingCorrectionStop(int thrdID);

      int setDdParameters(sharknir::dictTelescopeSetup DdEntries, out sharknir::SeqString outFiles);
      int getDdParameters(sharknir::SeqString seqEntries, out sharknir::SeqString outFiles);
    };

    interface engineer
    {
      int abort();
      idempotent int setupMotion(
        sharknir::dictNonSciAssembly dictNonSci,
        string strSetup
        );
      idempotent int setupTracking(
        string strSetup
        );
      idempotent int setupCalibration(
        sharknir::dictNonSciAssembly dictNonSci,
        string strSetup
        );
    };

//    interface Sensors
//    {
//      idempotent int sashaGetTemperature(out double temperature1, out double temperature2);
//      idempotent int sashaGetTemperature2(out sharknir::dictTemperatures dTemp); //, optional(1) string readSensor);
//    };
  };
};

#endif
