#pragma once

#ifndef SDCM_COMMON_STRUCTURE_H
#define SDCM_COMMON_STRUCTURE_H

#include "dcmtk/ofstd/ofstring.h"
#include "dcmtk/dcmdata/dcdeftag.h"
#include "dcmtk/dcmdata/dctag.h"

#include "csdcm.h"
#include "common.h"

typedef enum _SDCM_SCU_STATE
{
	NONE = 0,
	INITIALIZE_NETWORK,
	CREATE_ASSOCIATION_PARAMETERS,
	SET_AP_TITLES,
	SET_TRANSPORT_LAYER_TYPE,
	SET_PRESENTATION_ADDRESSES,
	REQUEST_ASSOCIATION,
	COUNT_ACCEPTED_PRESENTATION_CONTEXTS,
	CHECK_USER_IDENTITY_RESPONSE,
	RELEASE_ASSOCIATION,
	DESTROY_ASSOCIATION,
	DROP_NETWORK,
	COMPLETED,
	COMPLETE,
	ADD_PRESENTATION_CONTEXT,
	ABORT_ASSOCIATION,
	REJECTED_ASSOCIATION,
	UNKNOWN_ERROR_ASSOCIATION,
	PEER_REQUESTED_RELEASE,
	PEER_ABORTED_ASSOCIATION,
	CONNECTION_ERROR,
	CREATE_ASSOCIATION,
	TRY_FINDSCU,
	SET_APTITLES,
	ADD_STORAGE_PRESENTATION_CONTEXTS,
	TRY_STORE_SCU,
	SDCM_ERROR=0x1000,
}SDCM_SCU_STATE;

struct SDATA_SCHEDULED_DATA
{
public:
    QString strScheduledStationAETitle;
    QString strScheduledProcedureStepStartDate;
    QString strScheduledProcedureStepStartTime;
    QString strScheduledPerformingPhysicianName;
    QString strScheduledStepDescription;
    QString strScheduledCodeValue;

    SDATA_SCHEDULED_DATA()
    {
        Init();
    }

    void Init()
    {
        strScheduledStationAETitle = "";
        strScheduledProcedureStepStartDate = "";
        strScheduledProcedureStepStartTime = "";
        strScheduledPerformingPhysicianName = "";
        strScheduledStepDescription = "";
    }

    void InsertData(DcmTag tag, OFString strData)
    {
        if (tag == DCM_ScheduledProcedureStepDescription)
        {
            SetData(strScheduledStepDescription, strData);
        }
        else if (tag == DCM_ScheduledStationAETitle)
        {
            SetData(strScheduledStationAETitle, strData);
        }
        else if (tag == DCM_PerformedProcedureStepStartDate)// || tag==DCM_ScheduledProcedureStepStartDate)
        {
            SetData(strScheduledProcedureStepStartDate, strData);
        }
        else if (tag == DCM_PerformedProcedureStepStartTime)
        {
            SetData(strScheduledProcedureStepStartTime, strData);
        }
        else if (tag == DCM_ScheduledPerformingPhysicianName)
        {
            SetData(strScheduledPerformingPhysicianName, strData);
        }
        else if (tag == DCM_ScheduledProcedureStepStartDate)
        {
            SetData(strScheduledProcedureStepStartDate, strData);
        }
        else if (tag == DCM_ScheduledProcedureStepStartTime)
        {
            SetData(strScheduledProcedureStepStartTime, strData);
        }
        else if (tag == DCM_CodeValue)
        {
            SetData(strScheduledCodeValue, strData);
        }
    }

    void SetData(QString& strTagData, OFString strData)
    {
        if(strData.size()>0)
        {
            strTagData = strData.c_str();
        }
    }

};

struct SDATA_PATIENT
{
public:
    QString strPatientID;
    QString strPatientName;
    QString strPatientSex;
    QString strPatientAge;

    //Database New
    QString strPatientBirthDate;
    QString strPatientBirthTime;
    QString strPatientWeight;
    QString strPatientComments;
    QString strPatientLocation; //외래, 입원 구분

    QString m_strTestString;

    SDATA_PATIENT()
    {
        Init();
    }

    void Init()
    {
        strPatientID = "";
        strPatientName = "";
        strPatientSex = "";
        strPatientBirthDate = "";
        strPatientBirthTime = "";
        strPatientWeight = "";
        strPatientComments = "";
        strPatientAge = "";
        strPatientLocation = "";
    }

    void InsertData(DcmTag tag, OFString strData)
    {
        if (tag == DCM_PatientID)
        {
            strPatientID = strData.c_str();
        }
        else if (tag == DCM_PatientName)
        {
            strPatientName = strData.c_str();
        }
        else if (tag == DCM_PatientAge)
        {
            strPatientAge = strData.c_str();
        }
        else if (tag == DCM_ScheduledProcedureStepLocation)
        {
            strPatientLocation = strData.c_str();
        }
        else if (tag == DCM_PatientSex)
        {
            OFString strTmp;
            strTmp = strData.c_str();

            if(strTmp.size()>0)
            {
                if (strTmp.at(0) == 'M')
                {
                    strPatientSex = "M";
                }
                else if (strTmp.at(0) == 'F')
                {
                    strPatientSex = "F";
                }
                else if (strTmp.at(0) == 'O')
                {
                    strPatientSex = "O";
                }
                else
                {
                    strPatientSex = strData.c_str();
                }
            }
        }
        else if (tag == DCM_PatientBirthDate)
        {
            strPatientBirthDate = strData.c_str();
        }
        else if (tag == DCM_PatientBirthTime)
        {
            strPatientBirthTime = strData.c_str();
        }
        else if (tag == DCM_PatientWeight)
        {
            strPatientWeight = strData.c_str();
        }
        else if (tag == DCM_PatientComments)
        {
            strPatientComments = strData.c_str();
        }
    }
};

struct SDATA_STUDY
{
public:
    int nPatientIndex;
    QString strStudyInstanceUID;
    QString strStudyDate;
    QString strStudyTime;

    //Database New
    QString strAccessionNumber;
    QString strStudyDescription;
    QString strReferringPhysiciansName;

    SDATA_STUDY()
    {
        Init();
    }

    void Init()
    {
        strAccessionNumber = "";
        strStudyInstanceUID = "";
        strStudyDate = "";
        strStudyTime = "";
        strStudyDescription = "";
        strReferringPhysiciansName = "";
        nPatientIndex = 0;
    }

    void InsertData(DcmTag tag, OFString strData)
    {
        if (tag == DCM_AccessionNumber)
        {
            strAccessionNumber = strData.c_str();
        }
        else if (tag == DCM_StudyInstanceUID)
        {
            strStudyInstanceUID = strData.c_str();
        }
        else if (tag == DCM_ScheduledProcedureStepDescription)
        {
            strStudyDescription = strData.c_str();
        }
        else if (tag == DCM_StudyDate)
        {
            strStudyDate = strData.c_str();
        }
        else if (tag == DCM_StudyTime)
        {
            strStudyTime = strData.c_str();
        }
    }



};

struct SDATA_SERIES
{
public:
    int nStudyIndex;
    int nSeriesNumber;
    QString strSeriesInstanceUID;
    QString strModality;
    QString strLaterality;
    QString strSeriesDate;
    QString strSeriesTime;

    //Database New
    QString strBodyPartExamined;
    QString strSeriesDescription;
    QString strOperatorsName;

    SDATA_SERIES()
    {
        Init();
    }

    void Init()
    {
        nStudyIndex = 0;
        nSeriesNumber = 0;
        strBodyPartExamined = "";
        strSeriesInstanceUID = "";
        strSeriesDescription = "";
        strModality = "";
        strOperatorsName = "";
        strLaterality = "";
        strSeriesDate = "";
        strSeriesTime = "";
    }

    void InsertData(DcmTag tag, OFString strData)
    {
        if (tag == DCM_RequestedProcedureDescription)
        {
            strSeriesDescription = strData.c_str();
        }
        else if (tag == DCM_BodyPartExamined)
        {
            strBodyPartExamined = strData.c_str();
        }
        else if (tag == DCM_Modality)
        {
            strModality = strData.c_str();
        }
        else if (tag == DCM_OperatorsName)
        {
            strOperatorsName = strData.c_str();
        }
        else if (tag == DCM_Laterality)
        {
            strLaterality = strData.c_str();
        }
        else if(tag == DCM_SeriesDate)
        {
            strSeriesDate = strData.c_str();
        }
        else if(tag == DCM_SeriesTime)
        {
            strSeriesTime = strData.c_str();
        }
    }
};

struct SDATA_IMAGE
{
public:
    int nSeriesIndex;
    int nImageIndex;
    int nImageNumber;
    int bDelete;
    int nFileType;
    QString strFileLocation;
    QString strInstanceUID;

    //Database New
    QString strImageType;
    QString strAcquisitionDate;
    QString strAcquisitionTime;
    QString strContentDate; // Pixel Creation Date
    QString strContentTime; // Pixel Creation Time
    int nAcquisitionNumber;
    int nInstanceNumber;
    QString strPatientOrientation;
    QString strImageLaterality;
    QString strImageComments; // Option
    //(0088, 0200) Icon Image Sequence : usage or not
    //Burned In Annotation

    SDATA_IMAGE()
    {
        Init();
    }

    void Init()
    {
        nImageIndex = 0;
        nSeriesIndex = 0;
        nImageNumber = 0;
        bDelete = 0;
        nFileType = 0;
        strFileLocation = "";
        strInstanceUID = "";
        {
            strImageType = "DERIVED";
            strImageType += char(0x5c);
            strImageType += "PRIMARY";
        }

        strAcquisitionDate = "";
        strAcquisitionTime = "";
        strContentDate = ""; // Pixel Creation Date
        strContentTime = ""; // Pixel Creation Time
        nAcquisitionNumber = 0;
        nInstanceNumber = 0;
        strPatientOrientation = "";
        strImageLaterality = "";
        strImageComments = ""; // Option
        //(0088, 0200) Icon Image Sequence : usage or not
        //Burned In Annotation
    }

    void InsertData(DcmTag tag, OFString strData)
    {
        if (tag == DCM_ImageLaterality)
        {
            strImageLaterality = strData.c_str();
        }
        else if (tag == DCM_ImageType)
        {
            strImageType = strData.c_str();
        }
    }
};

class WorklistResponseData
{
public:
	WorklistResponseData()
    {
		strRequestedProcedureID = "";
		strReferringPhysicianName = "";
		strRequestingPhysician = "";
		strRequestedProcedureDescription = "";
        strAdmissionID = "";
		strEnc = "";

        m_Study.Init();
        m_Series.Init();
        m_Image.Init();
        m_Patient.Init();        
        m_ScheduledData.Init();

        strPatientOrientation = "";
	}


	void InsertData(DcmTag tag, OFString strData)
    {
        //Uint16 nGroup = tag.getGroup();
        //Uint16 nElement = tag.getElement();

        m_Study.InsertData(tag, strData);
        m_Series.InsertData(tag, strData);
        m_Image.InsertData(tag, strData);
        m_Patient.InsertData(tag, strData);
        m_ScheduledData.InsertData(tag, strData);

        if(tag==DCM_RequestedProcedureID)
        {

        }
		if (tag.getEVR() == EVR_DA)
		{
            OFString strTmp;
            strTmp = strData.c_str();

            /*
			int nFind = strTmp.Find("-");
			if (nFind > 0)
			{
				strTmp = strTmp.Left(nFind);
			}
            */
            strData = strTmp.c_str();
		}

		else if (tag == DCM_SpecificCharacterSet)
		{
            strEnc = strData.c_str();
        }
        else if (tag == DCM_RequestedProcedureDescription)
        {
            strRequestedProcedureDescription = strData.c_str();
        }
        else if (tag == DCM_RequestingPhysician)
		{
            strRequestingPhysician = strData.c_str();
		}

        else if (tag == DCM_RequestedProcedureID)
		{
            strRequestedProcedureID = strData.c_str();
        }
        else if (tag == DCM_ReferringPhysicianName)
		{
            strReferringPhysicianName = strData.c_str();
		}
        else if (tag == DCM_AdmissionID)
		{
            strAdmissionID = strData.c_str();
        }
        else if (tag == DCM_PatientOrientation)
        {
            strPatientOrientation = strData.c_str();
        }
    }

    QString strPatientOrientation;
    QString strRequestingPhysician;
    QString strRequestedProcedureID;
    QString strRequestedProcedureDescription;
    QString strReferringPhysicianName;
    QString strAdmissionID;
    QString strEnc;

    SDATA_PATIENT m_Patient;
    SDATA_STUDY m_Study;
    SDATA_SERIES m_Series;
    SDATA_IMAGE m_Image;
    SDATA_SCHEDULED_DATA m_ScheduledData;


};

struct MPPSRequestData
{
	MPPSRequestData()
	{
		m_strPatientID.clear();
		m_strPatientName.clear();
		m_strPatientBirthDate.clear();
		m_strPatientSex.clear();
		m_strAccessionNumber.clear();
		m_strReferencedSOPClassUID.clear();
		m_strReferencedSOPInstanceUID.clear();
	}

	MPPSRequestData(const WorklistResponseData& wr, OFString strReferencedSOPClassUID="")
	{
        m_strPatientID = wr.m_Patient.strPatientID.toStdString().c_str();
        m_strPatientName = wr.m_Patient.strPatientName.toStdString().c_str();
        m_strPatientBirthDate = wr.m_Patient.strPatientBirthDate.toStdString().c_str();
        m_strPatientSex = wr.m_Patient.strPatientSex.toStdString().c_str();
        m_strAccessionNumber = wr.m_Study.strAccessionNumber.toStdString().c_str();
        m_strReferencedSOPClassUID = strReferencedSOPClassUID;
        m_strReferencedSOPInstanceUID = wr.m_Study.strStudyInstanceUID.toStdString().c_str();
	}

	OFString m_strPatientID;
	OFString m_strPatientName;
	OFString m_strPatientBirthDate;
	OFString m_strPatientSex;
	OFString m_strAccessionNumber;
	OFString m_strReferencedSOPClassUID;
	OFString m_strReferencedSOPInstanceUID;
};

typedef enum _STRENC_TYPE
{
	STRENC_ANSI = 0,
	STRENC_KOR,
	STRENC_UTF8
}STRENC_TYPE;

typedef struct _SDCM_AGE
{
	_SDCM_AGE()
	{
		m_nYears = -1;
		m_nMonths = -1;
		m_nDays = -1;
	}
	int m_nYears;
	int m_nMonths;
	int m_nDays;
}SDCM_AGE;

typedef struct _SDCM_SERVER_INFO
{
    QString m_strServer_IP;
    int m_nServer_Port;
    QString m_strServer_AETitle;
    QString m_strClient_AETitle;
}SDCM_SERVER_INFO;

typedef struct _ImageFormat
{
	_ImageFormat()
	{
		m_pData = NULL;
		m_nWidth = -1;
		m_nHeight = -1;
	}

	_ImageFormat(int** pData, int nWidth, int nHeight)
	{
		m_pData = new int*;
		*m_pData = (int*)*pData;
		m_pData = pData;
		m_nWidth = nWidth;
		m_nHeight = nHeight;
	}

	_ImageFormat(unsigned char** pData, int nWidth, int nHeight)
	{
		m_pData = new int*;
		*m_pData = (int*)*pData;
		m_nWidth = nWidth;
		m_nHeight = nHeight;
	}

	_ImageFormat(void** pData, int nWidth, int nHeight)
	{
		m_pData = new int*;
		*m_pData = (int*)*pData;
		m_nWidth = nWidth;
		m_nHeight = nHeight;
	}

	~_ImageFormat()
	{
		if (m_pData != NULL)
		{
			if (*m_pData != NULL)
			{
				delete[] * m_pData;
				*m_pData = NULL;
			}


			//			delete m_pData;
			m_pData = NULL;
		}
		m_nWidth = 0;
		m_nHeight = 0;
	}
	int** m_pData;
	int m_nWidth;
	int m_nHeight;
}ImageFormat, *PImageFormat;



typedef struct _SDCM_GROUP_ELEMENT
{
#pragma pack(push)
#pragma pack(2)
    WORD m_wGroup;
    WORD m_wElement;

    _SDCM_GROUP_ELEMENT()
    {
        m_wGroup = 0;
        m_wElement = 0;
    }
    _SDCM_GROUP_ELEMENT(WORD wGroup, WORD wElement)
    {
        m_wGroup = wGroup;
        m_wElement = wElement;
    }

    BOOL operator==(const _SDCM_GROUP_ELEMENT& rhs)
    {
        BOOL bSame = FALSE;
        if(m_wGroup==rhs.m_wGroup && m_wElement==rhs.m_wElement)
        {
            bSame = TRUE;
        }
        return bSame;
    }
#pragma pack(pop)
}SDCM_GROUP_ELEMENT, *PSDCM_GROUP_ELEMENT;


#endif
