#ifndef _COMMOM_H_
#define _COMMOM_H_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
#include <stdbool.h>
#include <sys/time.h>


#define NUM_SHADER 4
#define POLY_DEGREE                    4    //Taylor('s) series
#define INVERSE_MAPPING_PARAM_MAX    30
#define INTRINSIC_PARAM_COUNT        5    //intrinsic parameters count
#define CHECK_ERROR


typedef unsigned char UChar;
typedef unsigned int  UInt;

#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif


#define LUTS_PATH           "/opt/vision_sdk/etc/luts/"
#define LUTS_TEMP           "/tmp/luts/"

#define LUTS_BOLW           "3DLUTS.BIN"
#define LUTS_UNDIST         "UNDISTLUTS.BIN"
#define LUTS_UNDIST_LR      "UNDISTLRLUTS.BIN"
#define LUTS_THREEMOSAIC    "THREEMOSAICLUTS.BIN"
#define LUTS_LDWVIEW        "LDWVIEWLUTS.BIN"
#define LUTS_CAMERA_EXT     "CAMERAEXT.BIN"
#define LUTS_CAMERA_INT     "CAMERAINT.BIN"
#define LUTS_CALIED         "CALIED.BIN"
#define LUTS_CORNERS        "SALECALICORNERS.BIN"


typedef struct _BowlVerTexParam
{
    int iBottomLayerNum;
    int iWallLayerNum;
    int iPointNum;
    int iPointNumLR;
    int iRatio;
    float k;
    float b;
    float fLowX;
    float fHighX;
    float fLowY;
    float fHighY;
}BowlVerTexParam;


typedef struct _CameraParamINT
{
    int iHeight;
    int iWidth;
    int iDirectMappingCount;
    int iInverseMappingCount;
    double daDirectMapping[POLY_DEGREE+1];
    double daInverseMapping[INVERSE_MAPPING_PARAM_MAX];
    double daIntParam[INTRINSIC_PARAM_COUNT];
    double daValidRange[4];
}CameraParamINT;


typedef struct _CameraParamEXT
{
    int iCamPosition;
    double daExtParam[6];
    double daExtMtxV2C[9];
    double daExtMtxC2V[9];

}CameraParamEXT;

typedef struct _UndistViewParam
{
    int iRangeWidth[2];     // Undistorted range width
    int iRangeHeight[2];    // Undistorted range height
    int iImgWidth;     // output Undistorted image width
    int iImgHeight;    // output Undistorted image height
    int iaViewAngle[4]; //unit: degree, 150 as default
    float faRangeOffsetRatio[4];    //0.20,0.00 front and rear undistorted image, vertical and horizontal range offset ratio
    // 0.20 0.00
    float faVirCamFOVandDIR[4][4];    // the FOV angle of the front right wheel image
    // the orientation of the virtual camera ( rotating degree around x,y,z axis )
    // TOTAL 3 virtual cameras: front right wheel, front left wheel, front large view , and rear large view
    double daVirtCamExtParam[4][9]; //virtual ext parameter for the 3 virtual cameras

}UndistViewParam;

//vehicle parameters, need to be set only when tracks are required.
typedef struct _VechicleParam
{
    int iVehicleWidth;        // actual width of the vehicle
    int iVehicleLength;        // unit: mm
    int iaTread[2];            // width of the wheel distance, left to right
    int iWheelBase;            // wheel base
    int iFrontOverhang;        // distance between the front axis and the front end of the vehicle area
    int iRearOverhang;        // distance between the rear axis and the rear end of the vehicle area
    int iWheelWidth;

    float fAckermanCoe;        // Ackerman Coefficient
    float fMaxLeftAngle;    // the maximum counter-clockwise degree which the steering wheel can get , deg -
    float fMaxRightAngle;    // the maximum clockwise degree which the steering wheel can get , deg +

}VehicleParam;

typedef struct _TracksAndAssist
{
    int iDynaTrackLen;                // length of the dynamic reverse tracks, unit: mm
    int iaDynaTrackStartDist[2];    // the distance from the starting point of the reverse track to the end of vehicle (area) in the longitudinal and lateral direction
    int iStartToFrontWheel;
    int iStartToRearWheel;

}TracksAndAssist;


typedef struct _OVSBasicInfo
{
    BowlVerTexParam stBowlVerTexParam;
    CameraParamINT  stCameraParamINT[4];
    CameraParamEXT  stCameraParamEXT[4];
    UndistViewParam stUndistView;
    VehicleParam    stVehicle;
    TracksAndAssist stTracksAndAssist;
//    BirdViewParam   stBirdView;
//    LDW_InputPara stLdwParam;

}OVSBasicInfo;

typedef struct _BowlVerTex
{
    float  pfVerF[1800];
    float  pfVerB[1800];
    float  pfVerL[3600];
    float  pfVerR[3600];
    float  pfTexF[1200];
    float  pfTexB[1200];
    float  pfTexL[2400];
    float  pfTexR[2400];
    float  pfVerBlendA[216];
    float  pfTexBlendAF[144];
    float  pfTexBlendAL[144];
    float  pfVerBlendB[216];
    float  pfTexBlendBL[144];
    float  pfTexBlendBB[144];
    float  pfVerBlendC[216];
    float  pfTexBlendCB[144];
    float  pfTexBlendCR[144];
    float  pfVerBlendD[216];
    float  pfTexBlendDF[144];
    float  pfTexBlendDR[144];
}BowlVerTex;

typedef struct _UndistGPUData
{
    float VerAll[2542];         //change:11-21   old=3922
    float FrontTexAll[2542];
    float RearTexAll[2542];
    float LeftTexAll[2542];
    float RightTexAll[2542];
    float Ltrack[10];
    float Rtrack[10];
    int iStartU;
    int iStartV;
    int iWidth;
    int iHeight;
    int iWNumber;
    int iHNumber;
}UndistGPUData;

typedef struct _UndistLRGPUData
{
    float BLVerAll[1302];        //11-23        old=1998
    float BLTexAll[1302];
    float BRVerAll[1302];
    float BRTexAll[1302];
    float BLtrack[10];
    float BRtrack[10];
    float LVerAll[1302];
    float LTexAll[1302];
    float RVerAll[1302];
    float RTexAll[1302];
    float Ltrack[10];
    float Rtrack[10];
    int iStartU;
    int iStartV;
    int iWidth;
    int iHeight;
    int iWNumber;
    int iHNumber;
} UndistLRGPUData;

typedef struct _ThreeMosaicGPUData
{
    int iStartU;
    int iStartV;
    int iWidth_F;
    int iHeight_F;
    int iWNumber_F;
    int iHNumber_F;
    float VerAll_F[5022];// 53*37*2=3922 //77*37*2=5698 //110*37*2=8140 // 79 *30 *2 = 4740//87 *31 *2 = 5394
    float FrontTexAll[5022];
    int iWidth_R;
    int iHeight_R;
    int iWNumber_R;
    int iHNumber_R;
    float VerAll_R[5022];//65 * 31 *2 = 4030
    float RearTexAll[5022];
}ThreeMosaicGPUData;

typedef struct _BirdviewGPUData
{
    float carLTx, carLTy, carRTx, carRTy, carLBx, carLBy, carRBx, carRBy;
    float VerFL[1064],VerF[560],VerFR[1064],VerL[836],VerR[836],VerLT[1064],VerT[560],VerRT[1064];
    float TexFLF[1064],TexF[560],TexFRF[1064],TexL[836],TexR[836],TexLTT[1064],TexT[560],TexRTT[1064];
    float TexFLL[1064],TexFRR[1064],TexLTL[1064], TexRTR[1064],factorFL[532],factorFR[532],factorLT[532],factorRT[532];
}BirdviewGPUData;


void Init_OES_State();

void esLoadShader(const char **verSrc, const char **frgSrc, GLuint *verShader, GLuint *frgShader);

GLuint esLoadProgram ( const char *vertShaderSrc, const char *fragShaderSrc );

int esApplyAttribHandle(int num, GLuint *attribHandle);

int esDelAttribHandle(int num, GLuint *attribHandle);

unsigned int fReadFileData(char *filePath, UChar **fileData, int bufsize);

int LoadFile(char *dirpath, const char *fileName, UChar **DataBuf, int bufsize);

bool loadTexture(GLuint *idTextures, void *picData, unsigned int picWidth, unsigned int picHeight, UChar isAlpha);

void tmpTexBufMalloc();

void tmpTexBufFree();

int loadPicFile(const char *picFilePath[], int picCount, GLuint *texPic);

bool updateLuts();

bool CheckGlError(const char* op, ...);

void ScreenCoordConvert(int screenWidth, int screenHeight, int *screenCoord, float *openglCoord, int numCoord);

int WriteDatatoFile(const char *filename, void *data, int datasize);

#ifdef CHECK_ERROR
#define AVM_GL_CHECK(fmt, ...)         CheckGlError("[INVO_AVM][GLError]:%s:%d:   after " fmt, __func__, __LINE__, ##__VA_ARGS__)
#else
#define AVM_GL_CHECK(fmt, ...)         (TRUE)
#endif

#endif  /* _COMMOM_H_ */

