/** \file
 *
 *  Specifies the interface details for the HFRCMVirtualSurfaceDrifter
 *  component in the EstimationModule.
 *
 *  HFRCMVirtualSurfaceDrifter.h should only be included by
 *  HFRCMVirtualSurfaceDrifter.cpp
 *  Other classes should include HFRCMVirtualSurfaceDrifterIF.h
 *
 *  Copyright (c) 2013, 2014 MBARI
 *  MBARI Proprietary Information.  All Rights Reserved
 */

#ifndef HFRCMVIRTUALSURFACEDRIFTER_H_
#define HFRCMVIRTUALSURFACEDRIFTER_H_

#include "data/Mtx.h"

#include "HFRadarCompactModelForecaster.h" // for TOTAL_HOURS, etc.

class BlobReader;
class ConfigReader;

/**
 *  Specifies the interface details for the HFRCMVirtualSurfaceDrifter
 *  component in the EstimationModule.
 *
 *  HFRCMVirtualSurfaceDrifter.h should only be included by
 *  HFRCMVirtualSurfaceDrifter.cpp
 *  Other classes should include HFRCMVirtualSurfaceDrifter.h
 *
 *  \ingroup modules_estimation
 */

class HFRCMVirtualSurfaceDrifter : public SyncEstimationComponent
{
public:
    HFRCMVirtualSurfaceDrifter( const Module* module );
    virtual ~HFRCMVirtualSurfaceDrifter();

    /// Initialize function
    void initialize( void );

    /// Reinitialize function (used by ReinitializeHFRCMVirtualSurfaceDrifter behavior to set/reset the initial location of the drifter)
    static bool Reinitialize( double latitude0rad, double longitude0rad );

    /// The actual "payload" of the component
    void run();

protected:
    int verbosity_;
    // space components
    Mtx eastEmpiricalOrthogonalFunctionsHere_;
    Mtx northEmpiricalOrthogonalFunctionsHere_;
    float eastEnsembleMeanHere_;
    float northEnsembleMeanHere_;
    float eastScalingFactor_;
    float northScalingFactor_;
    // time components
    Mtx expansionCoefficientsNow_;
    Timestamp calculationTime_;
    // results
    double elapsedTime_, eastVelocity_, northVelocity_, velocityAccuracy_, easting_, northing_, course_, horizontalDisplacement_, latitude_, longitude_, locationAccuracy_;
    // readers & writers
    DataWriter* eastVelocityWriter_;
    DataWriter* northVelocityWriter_;
    DataWriter* latitudeWriter_;
    DataWriter* longitudeWriter_;
    DataWriter* initialLatitudeWriter_;
    DataWriter* initialLongitudeWriter_;
    // Configuration readers
    ConfigReader* velocityAccuracyConfigReader_;

    /// Pointer to the singleton-like instance of this component
    static HFRCMVirtualSurfaceDrifter* Instance_;

    /// set the location of the drifter
    bool setLocation( double latitude0rad, double longitude0rad );

    /// Look up the expansion coefficients at the current time.
    bool lookupExpansionCoefficients( void );

    /// Look up the empirical orthogonal functions at the specified location.
    bool lookupEmpiricalOrthogonalFunctions( void );

    /// Calculate the estimated velocities at the specified location and time.
    void reproject( void );

    /// Calculate the new location of the drifter.
    void advect( void );

    /// Write the pertinent data out to the slate.
    void writeData( 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.
    HFRCMVirtualSurfaceDrifter( const HFRCMVirtualSurfaceDrifter& old ); // disallow copy constructor

};

#endif /* HFRCMVIRTUALSURFACEDRIFTER_H_ */
