/***************************************************************\
 *  Authors: 
 *      Marco Buttu <mbuttu@oa-cagliari.inaf.it>
 *      Andrea Orlati <a.orlati@ira.inaf.it>
\***************************************************************/

#ifndef __GENERICDEROTATOR__IDL__ 
#define __GENERICDEROTATOR__IDL__

#include <baci.idl>
#include <DerotatorErrors.idl>
#include <ComponentErrors.idl>
#include <ManagmentDefinitions.idl>

#pragma prefix "alma"


module Receivers {

    /**
     * <h2>Derotator Interface</h2>
     *
     * <p>This module defines a generic <em>derotator</em> interface.</p>
     * @author <a href=mailto:mbuttu@oa-cagliari.inaf.it>Marco Buttu</a>
     * @author <a href=mailto:a.orlati@ira.inaf.it>Andrea Orlati</a>
     *  
     * <h3>Properties</h3>:
     * <p>The derotator has the following properties:</p>
     * <ul>
     *     <li>actPosition: sensor encoder position (ROdouble, degrees)</li>
     *     <li>cmdPosition: commanded position (RWdouble, degrees)</li>
     *     <li>positionDiff: difference between the actual and the commanded
     *     position</li>
     *     <li>tracking: it is true when the positionDiff value is less or 
     *     equal to a given threshold</li>
     *     <li>status: a generic ROPattern status</li>
     * </ul> 
     * <p>The position properties represent the derotator position in the user
     * reference system. That means each property value is a degree angle,
     * obteined by subtracting (or by adding when write) a "zero reference" 
     * from the plain angle value got from the device.</p> 
     *
     * <h3>Methods</h3>:
     * <ul>
     *     <li>setup(): allow the derotator to be ready to move</li>
     *     <li>setPosition(): set the derotator position</li>
     *     <li>getActPosition(): return the actPosition value</li>
     *     <li>getCmdPosition(): return the cmdPosition value</li>
     *     <li>getPositionFromHistory(t): return the the derotator position at
     *     the time t</li>
     *     <li>getMaxLimit(): return the biggest position allowed,
     *     in the URS</li>
     *     <li>getMinLimit(): return the lowerst position allowed, 
     *     in the URS</li>
     *     <li>getStep(): return the angle (in degrees) between two feeds</li>
     *     <li>isTracking(): return the tracking property value</li>
     *     <li>isReady(): return true when the derotator is ready to move</li>
     *     <li>isSlewing(): return true when the derotator is moving</li>
     * </ul> 
     */
    interface GenericDerotator
    {
       
        /** 
         * This property returns the sensor encoder position in the user
         * reference system. In case the derotator has not a sensor device,
         * it returns the engine encoder position.
         * That means its value is a degree angle,
         * obtained by subtracting a "zero reference" from the plain value
         * (in case converted as angle) got from the encoder.
         *
         * @return the sensor position as degree angle, in the URS
         */
        readonly attribute ACS::ROdouble actPosition;

 
        /** 
         * This property allows us to set a derotator position and to read the
         * last commanded position. The value to set must be a degree angle, 
         * in the user reference system. 
         *
         * @return the last commanded position
         */
        readonly attribute ACS::RWdouble cmdPosition;

  
        /** 
         * @return the difference between the actual and the commanded position
         */
        readonly attribute ACS::ROdouble positionDiff;
 

        /** 
         * @return true when the positionDiff value is less or equal to a 
         * given threshold
         */
        readonly attribute Management::ROTBoolean tracking;


        /** 
         * This property reports the current derotator summary status. The 
         * returned pattern is a 6 bits field, with the following meaning:
         *
         *  @arg \c 0 power off
         *  @arg \c 1 failure (something is broken)
         *  @arg \c 2 communication error 
         *  @arg \c 3 not ready
         *  @arg \c 4 slewing 
         *  @arg \c 5 warning
         */
         readonly attribute ACS::ROpattern status;


        /**
         * Enable the derotator to move
         * @throw CORBA::SystemException
         * @throw DerotatorErrors::DerotatorErrorsEx
         * @throw ComponentErrors::ComponentErrorsEx
         */
        void setup() raises (
            DerotatorErrors::DerotatorErrorsEx, 
            ComponentErrors::ComponentErrorsEx
        );


        /** 
         * @return the actPosition property value
         *
         * @throw ComponentErrors::ComponentErrorsEx,
	     * @throw DerotatorErrors::DerotatorErrorsEx
	     * @throw DerotatorErrors::OutOfRangeErrorEx
         */
        void setPosition(in double position) raises (
            ComponentErrors::ComponentErrorsEx,
            DerotatorErrors::DerotatorErrorsEx,
            DerotatorErrors::OutOfRangeErrorEx
        );


        /**
         * This method loads a position that has to be tracked by the derotator
         * @param point_time an ACS::Time object indicating the time associated with the coordinates to be tracked.
         *        Only the start time is sent to the derotator and the points after are always spaced by the same amount of time from one another.
         *        It is still necessary to fill this field in order to associate a time to the coordinates inside the component.
         * @param position the position to track at the given time
         * @param restart flag that says the given point is the first of a new trajectory
         */
        void loadTrackingPoint(in ACS::Time point_time, in double position, in boolean restart) raises (DerotatorErrors::DerotatorErrorsEx);


        /**
         * @return the cmdPosition property value
         *
         * @throw CORBA::SystemException
         */
        double getCmdPosition();


        /** 
         * @return the actPosition property value
         *
         * @throw ComponentErrors::ComponentErrorsEx,
         * @throw DerotatorErrors::DerotatorErrorsEx
         */
        double getActPosition() raises (
            ComponentErrors::ComponentErrorsEx,
	        DerotatorErrors::DerotatorErrorsEx
        );


        /** Return the derotator position at a given time.
         *  If the time is lesser the the older one stored in the queue,
         *  then it returns oldest position.
         *  If the time is in advance or 0, it returns the latest position.
         *  @arg t the time related to the position we want to get
         *  @return the position
         *  @throw ComponentError::ComponentErrorsEx
         */
         double getPositionFromHistory(in ACS::Time t) raises (ComponentErrors::ComponentErrorsEx);


        /**
         * Return the maximum position value allowed.
         * @throw CORBA::SystemException
         */
        double getMaxLimit();


        /**
         * Return the minimum position value allowed.
         * @throw CORBA::SystemException
         */
        double getMinLimit();


        /**
         * @return the angle (in degrees) between two feeds</li>
         *
         * @throw CORBA::SystemException
         */
        double getStep();


        /**
         * Return the tracking property value
         * @throw CORBA::SystemException
         */
        boolean isTracking();


        /**
         * Return true when the derotator is ready for moving
         * @throw CORBA::SystemException
         */
        boolean isReady();
     

        /**
         * Return true when the derotator is moving
         * @throw CORBA::SystemException
         */
        boolean isSlewing();
    };
};

#endif

