#ifndef COMMON_H
#define COMMON_H

#include <QImage>
#include <QString>

#include <map>
#include <vector>
using namespace std;

typedef vector<QString> RowData;
#define SendListFilename RowData

#include <QImage>
#include <QString>
#include <QDate>
#include <QDateTime>
#include <QDebug>

#define SAFE_DELETE(x) { if(x!=NULL) { delete x; x = NULL; }}
#define SAFE_ARRAY_DELETE(x) { if(x!=NULL) { delete[] x; x = NULL; }}

#define MOVIE_FILE_EXTENSION ".mp4"

enum SMENU
{
    SMENU_WORKLIST = 0x01,
    SMENU_HISTORY = 0x02,
    SMENU_SETTING = 0x04,
    SMENU_CAPTURE = 0x10,
    SMENU_VIEWER = 0x20
};

enum SWIDGET
{
    SWIDGET_WORKLIST = 0,
    SWIDGET_HISTORY,
    SWIDGET_SETTING,
    SWIDGET_CAPTURE,
    SWIDGET_VIEWER
};

#ifndef __SDCM_DISPLAY_INDEX
#define __SDCM_DISPLAY_INDEX
typedef enum _SDCM_DISPLAY_INDEX
{
    SDI_PATIENT_ID = 0,
    SDI_PATIENT_NAME,
    SDI_PATIENT_SEX,
    SDI_PATIENT_WEIGHT,
    SDI_PATIENT_BIRTH_DATE,
    SDI_PATIENT_AGE,
    SDI_PATIENT_LOCATION,

    SDI_STUDY_INSTANCE_UID,
    SDI_STUDY_DESCRIPTION,
    SDI_STUDY_DATE,
    SDI_STUDY_TIME,
    SDI_STUDY_CREATE_DATE,
    SDI_STUDY_REFERRING_PHYSICIAN_NAME,

    SDI_SERIES_INSTANCE_UID,
    SDI_SERIES_OPERATOR,
    SDI_SERIES_MODALITY,
    SDI_SERIES_BODYPART,
    SDI_SERIES_DESCRIPTION,

    SDI_IMAGE_INSTANCE_UID,
    SDI_IMAGE_CREATE_DATE,
    SDI_IMAGE_CREATE_TIME,

    SDI_SCHEDULED_DATE,
    SDI_SCHEDULED_TIME,
    SDI_SCHEDULED_PROCEDURE_STEP_ID,
    SDI_SCHEDULED_PROCEDURE_ID,


    SDI_REQUESTED_PROCEDURE_COMMENTS,

    SDI_INDEX,
    SDI_SAVE_IMAGE_COUNT,
    SDI_SEND_IMAGE_COUNT,
    SDI_SAVE_MOVIE_COUNT,
    SDI_SAVE_TOTAL_COUNT,
    SDI_ACCESSION_NUMBER,
    SDI_SCHEDULED_PERFORMING_PHYSICIAN_NAME,
    SDI_SCHEDULED_CODE_VALUE,

    SDI_TOTAL, // No use!!, this is end tag!!

}SDCM_DISPLAY_INDEX;
#endif

#ifndef __SDCM_HISTORY_DISPLAY_INDEX
#define __SDCM_HISTORY_DISPLAY_INDEX
typedef enum _SDCM_HISTORY_DISPLAY_INDEX
{
    HDI_INDEX = 0,
    HDI_PATIENT_INDEX,
    HDI_PATIENT_ID,
    HDI_PATIENT_NAME,
    HDI_PATIENT_AGE,
    HDI_PATIENT_SEX,
    HDI_PATIENT_BIRTH_DATE,
    HDI_PATIENT_WEIGHT,
    HDI_STUDY_CREATE_DATE_TIME,
    HDI_STUDY_DATE,
    HDI_STUDY_TIME,
    HDI_SCHEDULED_CODE_VALUE,
    HDI_PATIENT_LOCATION,
    HDI_ACCESSION_NUMBER,
    HDI_STUDY_REFERRING_PHYSICIAN_NAME,
    HDI_STUDY_INSTANCE_UID,
    HDI_SERIES_INSTANCE_UID,
    HDI_STUDY_DESCRIPTION,
    HDI_SERIES_DESCRIPTION,
    HDI_SERIES_OPERATOR,
    HDI_SAVE_IMAGE_COUNT,
    HDI_SEND_IMAGE_COUNT,
    HDI_SERIES_MODALITY,
    HDI_SERIES_DATE,
    HDI_SERIES_TIME,
    HDI_SERIES_NUMBER,
    HDI_SAVE_MOVIE_COUNT,


    HDI_TOTAL, // No use!!, this is end tag!!

}SDCM_HISTORY_DISPLAY_INDEX;
#endif


enum SDISPLAY_TYPE
{
    SDISPLAY_1920X1080 = 0,
    SDISPLAY_1280X1024
};

struct SearchDate
{
    QDate m_DateStart;
    QDate m_DateEnd;
};

enum DISPLAY_TYPE
{
    DISPLAY_NONE = 0,
    DISPLAY_IMAGE = 1,
    DISPLAY_VIDEO = 2
};

struct TableHeader
{
    bool m_bSelect;
    int m_nIndexDefault;
    int m_nIndex;
    int m_nWidth;
    QString m_strText;
};

struct RGB_Data
{
    uint8_t r;
    uint8_t g;
    uint8_t b;
};

struct RGBA_Data
{
    uint8_t r;
    uint8_t g;
    uint8_t b;
    uint8_t a;
};

struct NetworkShareInfo
{
    QString m_strIP;
    QString m_strShareFolder;
    QString m_strID;
    QString m_strPassword;
    QString m_strVersion;
    bool m_bEnable;
    bool m_bAutoSend;
};

struct ImageSelect
{
    ImageSelect()
    {
        m_bSelect = false;
        m_bSend = false;
        m_bDelete = false;
        m_pImageData = NULL;
        //m_pImage = NULL;
        m_strFile = "";
        m_nType = DISPLAY_NONE;
        m_strDate = "";
        m_strTime = "";

        m_strStudyInstanceUID = "";
        m_strSeriesInstanceUID = "";
        m_strImageInstanceUID = "";
        m_strPatientAge = "";
        m_nIndexStudy = 0;
        m_nIndexSeries = 0;
        m_nIndexImage = 0;
        m_nIndexPatient = 0;

        m_nSeriesNumber = 0;
        m_nImageNumber = 0;

#ifdef _4K
        m_nImageWidth = 3840;
        m_nImageHeight = 2160;
#else
        m_nImageWidth = 1920;
        m_nImageHeight = 1080;
#endif
    }

    void CreateImage(int nImageWidth, int nImageHeight, int nImageFormat)
    {
        m_nImageWidth = nImageWidth;
        m_nImageHeight = nImageHeight;
        m_nImageFormat = nImageFormat;

        m_pImageData = new uint8_t[m_nImageWidth*m_nImageHeight*3];
    }

    int GetWidth()
    {
        return m_nImageWidth;
    }

    int GetHeight()
    {
        return m_nImageHeight;
    }

    int GetFormat()
    {
        return m_nImageFormat;
    }

    void DeleteImageData()
    {
        SAFE_ARRAY_DELETE(m_pImageData);
        m_bDelete = true;
    }

    ~ImageSelect()
    {
        SAFE_ARRAY_DELETE(m_pImageData);
        //SAFE_DELETE(m_pImage);
        m_bSelect = false;
        m_bSend = false;
        m_bDelete = false;
        m_strFile = "";
        m_nType = DISPLAY_NONE;
        m_strDate = "";
        m_strTime = "";

        m_strStudyInstanceUID = "";
        m_strSeriesInstanceUID = "";
        m_strImageInstanceUID = "";
        m_strPatientAge = "";
        m_nIndexStudy = 0;
        m_nIndexSeries = 0;
        m_nIndexImage = 0;
        m_nIndexPatient = 0;

        m_nSeriesNumber = 0;
        m_nImageNumber = 0;
    }
    bool m_bSelect;
    bool m_bSend;
    bool m_bDelete;
    //QImage* m_pImage;
    uint8_t* m_pImageData;
    QString m_strFile;    
    DISPLAY_TYPE m_nType;
    QString m_strDate;
    QString m_strTime;
    QString m_strStudyInstanceUID;
    QString m_strSeriesInstanceUID;
    QString m_strImageInstanceUID;
    QString m_strPatientAge;
    int m_nIndexStudy;
    int m_nIndexSeries;
    int m_nIndexImage;
    int m_nIndexPatient;

    int m_nSeriesNumber;
    int m_nImageNumber;

    int m_nImageWidth;
    int m_nImageHeight;

    int m_nImageFormat;
};

struct DisplayImage
{
    DisplayImage()
    {
        m_pImage = NULL;
        m_strFilename = "";
        m_bCheck = false;
        m_nType = DISPLAY_IMAGE;
    }

    DisplayImage(QString strFilename, QImage* pImage, DISPLAY_TYPE nType, bool bCheck)
    {
        m_strFilename = strFilename;
        m_pImage = pImage;
        m_nType = nType;
        m_bCheck = bCheck;
    }



    QImage* m_pImage;
    QString m_strFilename;
    bool m_bCheck;
    DISPLAY_TYPE m_nType;
};

struct CAPTURE_IMAGE
{
    CAPTURE_IMAGE()
    {
        m_pImage = NULL;
        m_pImageSmall = NULL;
        m_strImageFilename = "";
        m_strVideoFilename = "";
        m_pImageCaptureRaw = NULL;
        m_pImageCaptureColor = NULL;
        m_nType = DISPLAY_NONE;
        m_nIndex = -1;
        m_bCheck = false;
        m_bSaveFile = false;
        m_bDelete = false;
        m_bSend = false;
        m_pImageData = NULL;
        m_nImageWidth = 0;
        m_nImageHeight = 0;
        m_nImageFormat = 0;
        m_nAcquisitionNumber = 0;
        m_bBackup = false;
    }

    ~CAPTURE_IMAGE()
    {
        SAFE_DELETE(m_pImage);
        SAFE_DELETE(m_pImageSmall);
        SAFE_ARRAY_DELETE(m_pImageCaptureRaw);
        SAFE_ARRAY_DELETE(m_pImageCaptureColor);
        m_strImageFilename = "";
        m_nType = DISPLAY_NONE;
        m_nIndex = -1;
        m_bCheck = false;
        m_bDelete = false;
        m_bSend = false;
    }

    void CreateImage(int nImageWidth, int nImageHeight, int nImageFormat)
    {
        m_nImageWidth = nImageWidth;
        m_nImageHeight = nImageHeight;
        m_nImageFormat = nImageFormat;

        m_pImageData = new uint8_t[m_nImageWidth*m_nImageHeight*3];
    }

    int GetWidth()
    {
        return m_nImageWidth;
    }

    int GetHeight()
    {
        return m_nImageHeight;
    }

    int GetFormat()
    {
        return m_nImageFormat;
    }

    void DeleteImageData()
    {
        SAFE_ARRAY_DELETE(m_pImageData);
        m_bDelete = true;
    }

    bool IsBackup()
    {
        return m_bBackup;
    }

    QImage* m_pImage;
    QImage* m_pImageSmall;
    QString m_strImageFilename;
    QString m_strVideoFilename;
    QDateTime m_DateTime;
    bool m_bSaveFile;
    uint8_t* m_pImageCaptureRaw;
    RGB_Data* m_pImageCaptureColor;
    bool m_bCheck;
    bool m_bDelete;
    DISPLAY_TYPE m_nType;
    int m_nIndex;
    int m_nAcquisitionNumber;
    bool m_bSend;
    bool m_bBackup;

    uint8_t* m_pImageData;
    int m_nImageWidth;
    int m_nImageHeight;
    int m_nImageFormat;
};

struct SEARCH_ITEM
{
    SEARCH_ITEM()
    {
        Clear();
    }

    void Clear()
    {
        m_strStudyDate.clear();
        m_strPatientName.clear();
        m_strPatientID.clear();
    }

    QString m_strStudyDate;
    QString m_strPatientName;
    QString m_strPatientID;
};



struct LOCAL_DATA
{

};


struct NETWORK_DIRECTORY
{
    QString m_strNetworkDirectory;
    QString m_strID;
    QString m_strPassword;
};


struct HISTORY_STUDY
{
    QString* pStrStudyIndex;
    QString* pStrPatientIndex;
    QString* pStrPatientID;
    QString* pStrPatientName;
    QString* pStrPatientAge;
    QString* pStrPatientSex;
    QString* pStrPatientBirthDate;
    QString* pStrPatientWeight;
    QString* pStrCreateDateTime;
    QString* pStrStudyDate;
    QString* pStrStudyTime;
    QString* pStrStudyCodeValue;
    QString* pStrPatientLocation;
    QString* pStrAccessionNumber;
    QString* pStrReferringPhysiciansName;
    QString* pStrStudyInstanceUID;
    QString* pStrSeriesInstanceUID;
    QString* pStrStudyDescription;
    QString* pStrSeriesDescription;
    QString* pStrOperatorsName;
    QString* pStrImageCount;
    QString* pStrImageSend;
    QString* pStrModality;
    QString* pStrSeriesDate;
    QString* pStrSeriesTime;
    QString* pStrSeriesNumber;
    QString* pStrMovieCount;

    vector<QString*> m_List;

    map<int, int> m_ListTableHistoryViewMap;

    vector<int> m_ListEnableHeader;



    HISTORY_STUDY()
    {
        if(m_ListTableHistoryViewMap.empty()==true)
        {
            InitMap();

        }
        QString* pStrData = NULL;
        pStrData = new QString; m_List.push_back(pStrData); pStrStudyIndex = pStrData; //0
        pStrData = new QString; m_List.push_back(pStrData); pStrPatientIndex = pStrData; //1
        pStrData = new QString; m_List.push_back(pStrData); pStrPatientID = pStrData;//2
        pStrData = new QString; m_List.push_back(pStrData); pStrPatientName = pStrData;//3
        pStrData = new QString; m_List.push_back(pStrData); pStrPatientAge = pStrData;//4
        pStrData = new QString; m_List.push_back(pStrData); pStrPatientSex = pStrData;//5
        pStrData = new QString; m_List.push_back(pStrData); pStrPatientBirthDate = pStrData;//6
        pStrData = new QString; m_List.push_back(pStrData); pStrPatientWeight = pStrData;//7
        pStrData = new QString; m_List.push_back(pStrData); pStrCreateDateTime = pStrData;//8
        pStrData = new QString; m_List.push_back(pStrData); pStrStudyDate = pStrData;//9
        pStrData = new QString; m_List.push_back(pStrData); pStrStudyTime = pStrData;//10
        pStrData = new QString; m_List.push_back(pStrData); pStrStudyCodeValue = pStrData;//11
        pStrData = new QString; m_List.push_back(pStrData); pStrPatientLocation = pStrData;//12
        pStrData = new QString; m_List.push_back(pStrData); pStrAccessionNumber = pStrData;//13
        pStrData = new QString; m_List.push_back(pStrData); pStrReferringPhysiciansName = pStrData;//14
        pStrData = new QString; m_List.push_back(pStrData); pStrStudyInstanceUID = pStrData;//15
        pStrData = new QString; m_List.push_back(pStrData); pStrSeriesInstanceUID = pStrData;//16
        pStrData = new QString; m_List.push_back(pStrData); pStrStudyDescription = pStrData;//17
        pStrData = new QString; m_List.push_back(pStrData); pStrSeriesDescription = pStrData;//18
        pStrData = new QString; m_List.push_back(pStrData); pStrOperatorsName = pStrData;//19
        pStrData = new QString; m_List.push_back(pStrData); pStrImageCount = pStrData;//20
        pStrData = new QString; m_List.push_back(pStrData); pStrImageSend = pStrData;//21
        pStrData = new QString; m_List.push_back(pStrData); pStrModality = pStrData;//22
        pStrData = new QString; m_List.push_back(pStrData); pStrSeriesDate = pStrData;//23
        pStrData = new QString; m_List.push_back(pStrData); pStrSeriesTime = pStrData;//24
        pStrData = new QString; m_List.push_back(pStrData); pStrSeriesNumber = pStrData;//25
        pStrData = new QString; m_List.push_back(pStrData); pStrMovieCount = pStrData;//26
    }

    ~HISTORY_STUDY()
    {
        Clear();
    }

    void InitMap()
    {
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_INDEX, HDI_INDEX));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_PATIENT_ID, HDI_PATIENT_ID));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_PATIENT_NAME, HDI_PATIENT_NAME));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_PATIENT_AGE, HDI_PATIENT_AGE));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_PATIENT_SEX, HDI_PATIENT_SEX));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_PATIENT_BIRTH_DATE, HDI_PATIENT_BIRTH_DATE));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_PATIENT_WEIGHT, HDI_PATIENT_WEIGHT));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_STUDY_CREATE_DATE, HDI_STUDY_CREATE_DATE_TIME));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_STUDY_DATE, HDI_STUDY_DATE));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_STUDY_TIME, HDI_STUDY_TIME));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_SCHEDULED_CODE_VALUE, HDI_SCHEDULED_CODE_VALUE));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_PATIENT_LOCATION, HDI_PATIENT_LOCATION));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_ACCESSION_NUMBER, HDI_ACCESSION_NUMBER));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_STUDY_REFERRING_PHYSICIAN_NAME, HDI_STUDY_REFERRING_PHYSICIAN_NAME));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_STUDY_INSTANCE_UID, HDI_STUDY_INSTANCE_UID));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_SERIES_INSTANCE_UID, HDI_SERIES_INSTANCE_UID));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_STUDY_DESCRIPTION, HDI_STUDY_DESCRIPTION));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_SERIES_DESCRIPTION, HDI_SERIES_DESCRIPTION));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_SERIES_OPERATOR, HDI_SERIES_OPERATOR));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_SAVE_IMAGE_COUNT, HDI_SAVE_IMAGE_COUNT));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_SEND_IMAGE_COUNT, HDI_SEND_IMAGE_COUNT));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_SERIES_MODALITY, HDI_SERIES_MODALITY));
        m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_SAVE_MOVIE_COUNT, HDI_SAVE_MOVIE_COUNT));
        //m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_SERIES_DATE, HDI_SERIES_DATE)); //Not Display
        //m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_SERIES_TIME, HDI_SERIES_TIME)); //Not Display

        //m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_SCHEDULED_PERFORMING_PHYSICIAN_NAME, nIndex)); nIndex++;
        //m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_SCHEDULED_CODE_VALUE, nIndex)); nIndex++;

        //skip
        //m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_PATIENT_LOCATION, -1));
        //m_ListTableHistoryViewMap.insert(map<int, int>::value_type(SDI_PATIENT_LOCATION, -1));

        map<int, int>::iterator it;
        for(it=m_ListTableHistoryViewMap.begin() ; it!=m_ListTableHistoryViewMap.end() ; ++it)
        {
            int nIDEnable = (*it).first;
            m_ListEnableHeader.push_back(nIDEnable);
        }

    }

    int GetHDIWithSDI(int nDisplayIndex)
    {
        int nIndex = -1;
        map<int, int>::iterator it = m_ListTableHistoryViewMap.find(nDisplayIndex);
        nIndex = it->second;

        return nIndex;
    }

    QString GetData(int nDisplayIndex)
    {
        if(nDisplayIndex==SDI_SCHEDULED_CODE_VALUE)
        {

        }
        int i=0;
        bool bEnable = false;
        for(i=0 ; i<m_ListEnableHeader.size() ; i++)
        {
            int nIDEnable = m_ListEnableHeader[i];
            if(nIDEnable==nDisplayIndex)
            {
                bEnable = true;
            }
        }

        if(bEnable==false)
        {
            return "";
        }
        map<int, int>::iterator it = m_ListTableHistoryViewMap.find(nDisplayIndex);
        int nIndex = it->second;
        if(nIndex>=0)
        {
            return *m_List[nIndex];
        }
        return "";
    }

    void Clear()
    {
        int i=0;
        for(i=0 ; i<m_List.size() ; i++)
        {
            QString* pStrData = m_List[i];
            SAFE_DELETE(pStrData);
        }
        m_List.clear();
        m_ListTableHistoryViewMap.clear();
    }
};

#ifndef _WORD
#define _WORD
typedef unsigned short WORD;
#endif

#ifndef _DWORD
#define _DWORD
typedef unsigned int DWORD;
#endif

#ifndef _BOOL
#define _BOOL
typedef bool BOOL;
#endif

#ifndef _TRUE
#define _TRUE
#define TRUE true
#endif

#ifndef _FALSE
#define _FLASE
#define FALSE false
#endif

struct __attribute__((packed)) BITMAPFILEHADER
{
    __attribute__((aligned(2))) WORD bfType;
    __attribute__((aligned(2))) DWORD bfSize;
    __attribute__((aligned(2))) WORD bfReserved1;
    __attribute__((aligned(2))) WORD bfReserved2;
    __attribute__((aligned(2))) DWORD bfOffBits;
};

struct __attribute__((packed)) BITMAPINFOHEADER
{

    DWORD biSize;
    DWORD biWidth;
    DWORD biHeight;
    WORD biPlanes;
    WORD biBitCount;
    DWORD biCompression;
    DWORD biSizeImage;
    DWORD biXPelsPerMeter;
    DWORD biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;

};

typedef enum _TYPE_SEARCH_DURATION
{
    SEARCH_TODAY = 0,
    SEARCH_3DAY,
    SEARCH_WEEK,
    SEARCH_2WEEK,
    SEARCH_3WEEK,
    SEARCH_1MONTH,
    SEARCH_2MONTH,
    SEARCH_USER_DEFINED,
}TYPE_SEARCH_DURATION;




#endif // COMMON_H
