#ifndef __RANGEPREDICTOR_H
#define __RANGEPREDICTOR_H

/*@@@**************************************************************************
 ** \file  rangePredictor.h
 * \date   Mon Jun 22 14:55:16 EDT 2009
 * \author Hernan Badino
 * \notes  
*******************************************************************************
******************************************************************************/

/* INCLUDES */

#include <math.h>

#include "operator.h"
#include "image.h"
#include "sphericalRangeImage.h"
#include "uShortImage.h"


/* CONSTANTS */

namespace VIC
{
    /* CLASS DEFINITION */
    class CRangePredictorOp: public VIC::COperator
    {
        /// Constructor, Desctructors
    public:    
        
        /// Constructors.
        CRangePredictorOp ( COperator * const f_parent_p = NULL );
        
        /// Virtual destructor.
        virtual ~CRangePredictorOp ();

        /// Cycle event.
        virtual bool cycle();
    
        /// Show event.
        virtual bool show();
    
        /// Init event.
        virtual bool initialize();
    
        /// Reset event.
        virtual bool reset();
    
        /// Exit event.
        virtual bool exit();

    /// User Operation Events
    public:
        /// Key pressed in display.
        virtual void keyPressed (     CKeyEvent * f_event_p );

        /// Mouse moved.
        virtual void mouseMoved (     CMouseEvent * f_event_p );


    /// Set/Gets (Parameters)
    public:

        ADD_PARAM_ACCESS (S2D<int>,     m_minMaxSriKernelSize,   MinMaxSriKernelSize );
        ADD_PARAM_ACCESS (S2D<int>,     m_minMaxDispKernelSize,  MinMaxDispKernelSize );
        ADD_PARAM_ACCESS (S2D<double>,  m_sriDeltas,             SriDeltas );
        ADD_PARAM_ACCESS (bool,         m_applyStrategy1_b,      ApplyStrategy1 );
        ADD_PARAM_ACCESS (bool,         m_maskMinMaxFilter_b,    MaskMinMaxFilter );
        ADD_PARAM_ACCESS (bool,         m_interpRightImg_b,      InterpRightImg );
        ADD_PARAM_ACCESS (bool,         m_remapRightImg_b,       RemapRightImg );
        ADD_PARAM_ACCESS (int,          m_dispOffset_i,          DispOffset );
        ADD_PARAM_ACCESS (bool,         m_predict4RightImg_b,    Predict4RightImg );
    protected:
        void         allocateSRIs();
        void         registerDrawingLists();
        void         predictDisparityImage( const CSphericalRangeImage &f_sri, 
                                            CFloatImage                &fr_predDispImg,
                                            double                      f_rangeDelta_d = 0. );
        
        void         predictDisparityImages ( const CSphericalRangeImage &f_sri, 
                                              CFloatImage                &fr_predMinDispImg,
                                              CFloatImage                &fr_predMaxDispImg,
                                              double                      f_deltaMin_d,
                                              double                      f_deltaMax_d );
        
        void         computeDisparityReduction();

        void         computeMinMaxDisparityImages();

        bool         predictDisparityImage2 ( const CSphericalRangeImage &f_sri,
                                              CFloatImage                &fr_predDispImg );

        void         recreateLuts();

        bool         remapRightImage ( );

        void         predict4RightImg();
        
    /// Protected Data Types
    protected:

        /// Velodyne generated depth image.
        CSphericalRangeImage    m_minRangeImage;

        /// Velodyne generated depth image.
        CSphericalRangeImage    m_maxRangeImage;

        /// Predicted min disp image.
        CFloatImage             m_predMinDispImg;

        /// Predicted max disp image.
        CFloatImage             m_predMaxDispImg;

        /// Auxiliar float image.
        CFloatImage             m_auxDispImg1;

        /// Auxiliar float image.
        CFloatImage             m_auxDispImg2;

        /// Kernel Size for SRI MinMax filters.
        S2D<int>                m_minMaxSriKernelSize;

        /// Mask the output of the min/max filter with the invalid values.
        bool                    m_maskMinMaxFilter_b;

        /// Kernel Size for SRI Disparity prediction.
        S2D<int>                m_minMaxDispKernelSize;
        
        /// Deltas to apply to SRIs images.
        S2D<double>             m_sriDeltas;
        
        /// Use strategy 1?
        bool                    m_applyStrategy1_b;
        
        /// Look-up table for transforming sri to disp img.
        CFloatImage             m_lutU;

        /// Look-up table for transforming sri to disp img.
        CFloatImage             m_lutV;

        /// Look-up table for transforming sri to disp img.
        CSphericalRangeImage    m_copiedSri;

        /// Temporal buffer for converting double into float image.
        CFloatImage             m_sriFImage;

        /// Predicted disp img.
        CFloatImage             m_predDispImg;

        /// Predicted float right disp img.
        CFloatImage             m_remappedFRImage;

        /// remapped right image.
        CUShortImage            m_remappedRImage;

        /// Interpolate right image?
        bool                    m_remapRightImg_b;

        /// Interpolate right image?
        bool                    m_interpRightImg_b;
        
        /// Disparity Offset for remapped right image.
        int                     m_dispOffset_i;

        /// Predicted min right disp image.
        CFloatImage             m_predMinRightDispImg;

        /// Predicted max right disp image.
        CFloatImage             m_predMaxRightDispImg;

        /// Predicted disp img.
        CFloatImage             m_predRightDispImg;

        /// Shoud the prediction be performed for the right image?
        bool                    m_predict4RightImg_b;

    private:
        
   };
}

#endif // __RANGEPREDICTOR_H
