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

#ifndef HFRCMRECONSTRUCTEDINTERPOLATOR_H_
#define HFRCMRECONSTRUCTEDINTERPOLATOR_H_

#include "component/SyncComponent.h"
#include "data/Mtx.h"
#include "HFRadarCompactModelForecasterIF.h" // for MAX_EOFS, etc.

class UniversalDataReader;
class BlobReader;
class ConfigReader;

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

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

    /// Initialize function
    void initialize( void );

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

    /// Return the singleton
    static HFRCMReconstructedInterpolator* Instance()
    {
        return Instance_;
    }

    /// look up the surface current at a specified location and time
    bool lookupSurfaceCurrent( float& eastVelocity, float& northVelocity, const double epoch, const float latDeg, const float lonDeg );

protected:
    const bool debug_;
    int verbosity_;
    const Mtx eofs_;
    const Mtx ensMean_;
    const Mtx gridIdxRev_;
    const Mtx gridLon_;
    const Mtx gridLat_;
    const Mtx scalingFactors_;
    Mtx gridIdx_;
    int numLocations_;
    int numModes_;
    int numTimes_;
    double forecastEpochSeconds_[ HFRadarCompactModelForecasterIF::TOTAL_HOURS ];
    Timestamp forecastStart_;
    Timestamp forecastEnd_;
    Mtx expansionCoefficients_;
    Mtx currentField_;
    float eastVelocity_;
    float northVelocity_;
    float velocityAccuracy_;
    bool haveValidForecast_;

    // readers & writers
    UniversalDataReader* latitudeReader_;
    UniversalDataReader* longitudeReader_;
    BlobReader* expansionCoefficientsReader_;
    BlobReader* forecastTimesReader_;
    UniversalDataWriter* eastVelocityWriter_;
    UniversalDataWriter* northVelocityWriter_;
    // Configuration readers
    ConfigReader* verbosityLevelConfigReader_;
    ConfigReader* velocityAccuracyConfigReader_;

    void updateExpansionCoefficients( void );

    void reproject( void );

    /// publish the surface current at the present location of the vehicle
    void publishSurfaceCurrentAtVehicleLocation( void );

    bool getPreviousTimeIndex( int &time_index, double es );

    bool getLowerLeftCorner( int &latitude_index, int &longitude_index, const float latitude_degrees, const float longitude_degrees );

    float interpolateRaveledThreeDimensionalGrid( const Mtx z, const float epoch, const float latitude_degrees, const float longitude_degrees, const int time_index, const int latitude_index, const int longitude_index, const int starting_offset = 0 );

    static HFRCMReconstructedInterpolator* Instance_;

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

};

#endif /* HFRCMRECONSTRUCTEDINTERPOLATOR_H_ */
