/* 
 * File:   CRF.h
 * Author: carlos
 *
 * Created on 6 de noviembre de 2012, 15:47
 */

#ifndef CRF_H
#define	CRF_H

#include <opencv2/core/core.hpp>
#include <CpuTime.h>

using namespace std;

class CRF {
public:
    typedef cv::Vec<float, 8> Vec8f;

    CRF();
    CRF(int neighbor, int gridRows, int gridCols, int priorSatVal, int likeSatValue, string logFile, int labelCnt, int scale);
    CRF(const CRF& orig);
    ~CRF();
    void freeData();

    int fromValueToLabel(int value); //OK
    int fromLabelToValue(int label); //OK
    
//    int fromValueToLabel(float value); //OK
//    float fromLabelToValue(int label); //OK
    
    void updateMeasurements(cv::Mat meas); //OK
    int computeMessages();
    void computeBeliefs(); //OK
    void computePriors(); //OK
    void computeLikelihoods(); //OK

    void setLikeSatVal(int likeSatVal) {
        this->m_likeSatVal = likeSatVal;
    }

    int getLikeSatVal() const {
        return m_likeSatVal;
    }

    void setPriorSatVal(int priorSatVal) {
        this->m_priorSatVal = priorSatVal;
    }

    int getPriorSatVal() const {
        return m_priorSatVal;
    }

    int getPrior(int p, int q) {        
        return m_prior[p][q];
    }

    int getLikelihood(int r, int c, int label) {        
        return m_like[r][c][label];
    }

    cv::Mat getMeasurements() {
        return m_meas;
    }

    cv::Mat getResult() const {
        return m_result;
    }

    int belief(int qr, int qc, int labelQ);

    void setLabelCnt(int labelCnt) {
        this->m_labelCnt = labelCnt;
    }

    int getLabelCnt() const {
        return m_labelCnt;
    }
    
    
    
    void init_M_H(); 
    void twoPassAlgorith(int r, int c);
    

private:
    static const bool OPTIMIZED = true;
    const float Z_VALID_MIN = -10.0;
    const float Z_VALID_MAX = 10.0;
    
    int calcLineEqu(int u1, int v1, int u2, int v2, float *m, float *n);
    void calcMeanStd(int r, int c, int windSize, int u1, int v1, int u2, int v2, float *meanA, float *meanB, float *meanC, float *stdA, float *stdB, float *stdC, vector<float> *ptsA, vector<float> *ptsB, vector<float> *ptsC);
    float corrExpectedCurb(vector<float> ptsC,float meanA, float meanB);
    float corrExpectedNonCurb(vector<float> ptsC, float meanC, float stdC, float precision, float meanA, float meanB);
    
    int calcH(int pr, int pc, int labelP);
    int prior(float dcp, float sigmaDC, float slope, int p, int q, int d, int s); //OK
    int prior1(float dcp, float sigmaDC, float slope);
    int prior2(int p, int q, int d, int s);
    int likelihood(int r, int c, int windSize, int u1, int v1, int u2, int v2, float precision); //OK

    int getMinBelief(int qr, int qc);

    int msgSumAllMinusQ_T_1(int pr, int pc, int qr, int qc, int label, int policy);
    int msgSumAll_T(int qr, int qc, int label, int policy); //OK
    int msgSumAll_T_1(int qr, int qc, int label, int policy); //OK
    int neighborIndex(int pr, int pc, int qr, int qc, int policy, vector<int> *neighbors); //OK
    int neighborPos(int pr, int pc, int policy, vector<int> *neigR, vector<int> *neigC); //OK

    int computeMessage(int pr, int pc, int qr, int qc, int labelQ);
    
    

    int m_satValueLow;
    int m_satValueHigh;
    int m_resolution;
    int m_labelCnt;
    int m_scale;
    
    bool m_memReserved;

    int m_likeSatVal;
    int m_priorSatVal;

    cv::Mat m_meas;
    cv::Mat m_result;


    int m_neigPolicy;
    int m_rows, m_cols;


    int ***m_like;
    int **m_prior;
    int ****m_msg, ****m_msgT_1, ****m_msgData1, ****m_msgData2;
    int ***m_m, ***m_h;    
    int **m_minH;




};

#endif	/* CRF_H */

