/** \file
 *
 *  Contains the InternalSim class declaration.
 *
 *  InternalSim.h should only be included by InternalSim.cpp
 *  Other classes should include InternalSimIF.h
 *
 *  Copyright (c) 2007,2008,2009 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 */

#ifndef INTERNALSIM_H_
#define INTERNALSIM_H_

#include "component/SyncComponent.h"
#include "data/Location.h"
#include "data/Matrix6x6.h"
#include "data/Point3D.h"
#include "data/Point6D.h"
#include "Simulator.h"
#include "utils/AuvMath.h"
#include "utils/Datum.h"

class UniversalDataReader;
class UniversalDataWriter;

/**
 *  This simulation initializes whenever a location fix is obtained,
 *  and simulates the vehicle's trajectory and the output of
 *  navigation sensors over an entire dive.
 *  \todo The first X seconds of each dive are used to tune the
 *  settings of mass zero position and buoyancy zero gain.
 *
 *  InternalSim.h should only be included by InternalSim.cpp
 *  Other classes should include InternalSimIF.h
 *
 *  \ingroup modules_simulator
 */
class InternalSim : public SyncSimulatorComponent
{

public:
    /// Constructor.
    InternalSim( const Module* module );

    /// Destructor.
    virtual ~InternalSim();

    /// Initialize the simulator
    virtual void initialize( void );

    /// Run the simulation
    virtual void run( void );

    /// Uninitialize the simulation
    virtual void uninitialize( void );


private:
    // Note that the copy constructor below is private and not given a body.
    // Any attempt to call it will return a compiler error.
    InternalSim( const InternalSim& old ); // disallow copy constructor

    /// The actual dynamic simulator
    Simulator simulator_;

    /// Indicates whether the internal sim is running
    bool ok_;

    /// Indicates whether we have an initial position fix
    bool haveFix_;

    // Got a fix once (the first time through)
    bool gotFirstFix_;

    // Depth we call "at the surface"
    float surfaceThreshold_;

    // write State to Slate
    virtual void publishState();

    bool loadParams( void );

    //*------------------- slate variables -----------------------*/

    // Environmental parameters:
    UniversalDataReader* densityReader_;

    // AHRS specific parameters:
    UniversalDataReader* headingReader_;
    UniversalDataReader* pitchReader_;
    UniversalDataReader* rollReader_;
    UniversalDataWriter* headingWriter_;
    UniversalDataWriter* pitchWriter_;
    UniversalDataWriter* rollWriter_;

    //----------------------------------------------------------------
    // Depth specific parameters:
    UniversalDataReader *depthReader_;
    UniversalDataWriter *depthWriter_;

    //----------------------------------------------------------------
    // Gps specific parameters:
    UniversalDataReader *latitudeFixReader_;
    UniversalDataReader *longitudeFixReader_;
    UniversalDataReader *latitudeReader_;
    UniversalDataReader *longitudeReader_;
    UniversalDataWriter *latitudeWriter_;
    UniversalDataWriter *longitudeWriter_;

    //----------------------------------------------------------------
    // Tailcone specific parameters:
    DataReader* propOmegaActionReader_;
    DataReader* elevatorAngleActionReader_;
    DataReader* rudderAngleActionReader_;
    DataReader* massPositionActionReader_;
    UniversalDataWriter* propOmegaWriter_;
    UniversalDataWriter* elevatorAngleWriter_;
    UniversalDataWriter* rudderAngleWriter_;
    UniversalDataWriter* massPositionWriter_;

    //----------------------------------------------------------------
    /// Configuration readers
    ConfigReader* surfaceThresholdCfgReader_;

    //----------------------------------------------------------------
    // Communications
    SimRunStruct runParams_;
    SimResultStruct results_;

};

#endif /*INTERNALSIM_H_*/
