#include "sdcmfindscudatacallback.h"

#include <dcmtk/dcmdata/dcelem.h>
#include <dcmtk/dcmdata/dcsequen.h>
#include <dcmtk/dcmdata/dctagkey.h>
#include <dcmtk/dcmdata/dcvr.h>

#include <QByteArray>
#include <QTextCodec>
#include <QString>

#include "mainwindow.h"
#include "charconvert.h"

/*
SDCMFindSCUDataCallback::SDCMFindSCUDataCallback()
{
    m_pDCMViewList = NULL;
    m_pDCMDumpList = NULL;
}
*/


SDCMFindSCUDataCallback::SDCMFindSCUDataCallback(DcmFindSCUExtractMode extractResponses,
                                                 int cancelAfterNResponses,
                                                 const char *outputDirectory,
                                                 STD_NAMESPACE ofstream *outputStream,
                                                 const unsigned int limitOutput)//:DcmFindSCUCallback()//DcmFindSCUDefaultCallback(extractResponses, cancelAfterNResponses, outputDirectory, outputStream)//, limitOutput)
{
    m_pDCMViewList = NULL;

    m_pDCMDumpList = NULL;
}


SDCMFindSCUDataCallback::~SDCMFindSCUDataCallback()
{
    if(m_pDCMViewList!=NULL)
    {
        Clear();
    }

    if(m_pDCMDumpList!=NULL)
    {

    }
}


void SDCMFindSCUDataCallback::callback(T_DIMSE_C_FindRQ *request,
                                       int& responseCount,
                                       T_DIMSE_C_FindRSP *rsp,
                                       DcmDataset *responseIdentifiers)
{
    //OFString temp_str;
    //DIMSE_dumpMessage(temp_str, *rsp, DIMSE_INCOMING);

    CommonData* pCommonData = MainWindow::GetCommonData();
    QString strEnc = pCommonData->GetDICOMCharacterSet();

    unsigned long i = 0;
    OFString tagValue;

    int nCount = 0;
    DcmTag tag;
    DcmItem* pSubItem = NULL;
    DcmElement* pElement = NULL;

    OFString strData;
    DcmTagKey dcmKey;



    //responseIdentifiers->saveFile("worklist.dcm");

    WorklistResponseData wrd;

    WorklistResponseData* wr = &wrd;

    /*
    OFString strEnc = FindCharacterSet(responseIdentifiers);
    //responseIdentifiers->findAndGetOFStringArray(DCM_SpecificCharacterSet, strEnc);
    if (strEnc.length()==0)
    {
        //if(CSDCM)
        strEnc = "ISO_IR 192";
    }
    CharacterSetConversion(responseIdentifiers, strEnc);
    */

#ifdef DCMTK_ENABLE_CHARSET_CONVERSION

                        //OFCondition cond1 = responseIdentifiers->convertToUTF8();
#endif    

    //CSDCM test1;


    for (i = 0; i<responseIdentifiers->card(); i++)
    {
        strData.clear();

        pElement = NULL;
        pElement = responseIdentifiers->getElement(i);

        int nGroup = pElement->getGTag();
        int nElement = pElement->getETag();

        DcmTag tag(nGroup, nElement);

        DcmEVR vr;


        DcmTagKey tagKey;
        pElement->getTagVal(tagKey);

        vr = pElement->getVR();



        if(vr==EVR_SQ)
        {
            ReadSequence(pElement, wr);
        }
        else
        {
            pElement->getOFStringArray(strData);
            DcmEVR vrChild = pElement->getVR();

            if(vrChild==EVR_PN || vrChild==EVR_LO)
            {
                //strData = CharConvert::EUCKRtoUTF8(strData.data()).toStdString().c_str();
                if(strEnc=="EUC-KR")
                {
                    strData = CharConvert::Convert(strData.data(), "UTF-8").toStdString().c_str();
                }
            }
            wr->InsertData(tag, strData);

            //test1.InsertTagValue(tag, strData);

        }

        if (tag == DCM_PatientName)
        {
            //char* pTest123 = new char[1024];
            //ZeroMemory(pTest123, 1024);
            //pElement->getString(pTest123);
            wr->InsertData(tag, strData);
        }

        if(tag==DCM_Modality)
        {

        }


    }



    if (wr->m_Study.strStudyDate.length() == 0)
    {
        wr->m_Study.strStudyDate = wr->m_ScheduledData.strScheduledProcedureStepStartDate;
    }

    if (wr->m_Study.strStudyTime.length() == 0)
    {
        wr->m_Study.strStudyTime = wr->m_ScheduledData.strScheduledProcedureStepStartTime;
    }

    //m_pDCMViewList->Add(wr);
    //m_pDCMViewList->push_back(wrd);

    if(wr->m_ScheduledData.strScheduledStepDescription.length()>0)
    {
        wr->m_Study.strStudyDescription = wr->m_ScheduledData.strScheduledStepDescription;

        //QString strTest1 = CharConvert::EUCKRtoUTF8(wr->m_ScheduledData.strScheduledStepDescription.c_str());

        if(strEnc=="EUC-KR")
        {
            //QString strTest1 = CharConvert::Convert(wr->m_ScheduledData.strScheduledStepDescription.c_str(), strEnc);
            //wr->m_Study.strStudyDescription = strTest1.toStdString().c_str();
        }
    }

    if(wr->m_Series.strSeriesDescription.length()==0)
    {
        wr->m_Series.strSeriesDescription = wr->m_Study.strStudyDescription;
    }
    else
    {
        //QString strTest1 = CharConvert::EUCKRtoUTF8(wr->m_ScheduledData.strScheduledStepDescription.c_str());

        if(strEnc=="EUC-KR")
        {
            //QString strTest1 = CharConvert::Convert(wr->m_Series.strSeriesDescription.c_str(), strEnc);
            //wr->m_Series.strSeriesDescription = strTest1.toStdString().c_str();
        }
    }

    m_pDCMViewList->push_back(wrd);



}


void SDCMFindSCUDataCallback::AddView(WORD wGroup, WORD wElement)
{
    /*
    SDCM_GROUP_ELEMENT* pNewGroupElement = NULL;
    SDCM_GROUP_ELEMENT* pGroupElement = NULL;
    SDCM_GROUP_ELEMENT nGroupElement(wGroup, wElement);

    POSITION pos = NULL;
    BOOL bExist = FALSE;
    pos = m_pViewReservedList->GetHeadPosition();

    while(pos!=NULL)
    {
        pGroupElement = m_pViewReservedList->GetNext(pos)->GetData();
        if(nGroupElement==*pGroupElement)
        {
            bExist = TRUE;
            break;
        }
    }

    if(bExist==FALSE)
    {
        pNewGroupElement = new SDCM_GROUP_ELEMENT(wGroup, wElement);
        m_pViewReservedList->Add(pNewGroupElement);
    }
    */
}


int SDCMFindSCUDataCallback::GetWorklistSize()
{
    return m_pDCMViewList->size();
    //return m_pDCMViewList->GetCount();
}

void SDCMFindSCUDataCallback::SetWorklistData(vector<WorklistResponseData>* pWorklistData)
{
    m_pDCMViewList = pWorklistData;
}

void SDCMFindSCUDataCallback::SetWorklistDump(vector<CSDCM*>* pDCMDump)
{
    m_pDCMDumpList = pDCMDump;
}

/*
vector<WorklistResponseData>* SDCMFindSCUDataCallback::GetWorklistData()
{
    return m_pDCMViewList;
}
*/

vector<CSDCM*>* SDCMFindSCUDataCallback::GetDCMDumpList()
{
    return m_pDCMDumpList;
}

void SDCMFindSCUDataCallback::Clear()
{
    //m_pDCMViewList->DeleteAll();

    if(m_pDCMViewList==NULL)
    {
        return;
    }

    int i=0;

    for(i=0 ; i<m_pDCMViewList->size() ; i++)
    {
        //WorklistResponseData
    }

    m_pDCMViewList->clear();


    if(m_pDCMDumpList==NULL)
    {
        return;
    }



    for(i=0 ; i<m_pDCMDumpList->size() ; i++)
    {
        CSDCM* pDCM = (*m_pDCMDumpList)[i];
        delete pDCM;
    }

    m_pDCMDumpList->clear();
}

int SDCMFindSCUDataCallback::CharacterSetConversion(DcmItem* pDcmItem, OFString strEnc)
{

    int nConv = 0;
    int i = 0;
    OFString strData;

    /*

    CStringA strConv;
    if (strEnc == "ISO_IR 192")
    {
        strConv = "UTF-8";
    }
    else if (strEnc == "ISO_IR 100")
    {
        strConv = "ASCII";
    }
    else if (strEnc == "ISO 2022 IR 149")
    {
        strConv = "ISO-2022-KR";
    }

    strConv = "EUC-KR";

    for (i = 0; i < pDcmItem->card(); i++)
    {
        strData.empty();
        DcmElement* pElement = NULL;

        pElement = pDcmItem->getElement(i);

        DcmTag tag;
        tag = pElement->getTag();
        int nGroup = tag.getGroup();
        int nElement = tag.getElement();

        DcmEVR vr;
        vr = pElement->getVR();

        if (tag == DCM_ScheduledProcedureStepSequence)
        {
            DcmSequenceOfItems* seq = NULL;
            seq = (DcmSequenceOfItems*)pElement;

            if (seq != NULL)
            {
                int j = 0;
                int nSubData = seq->card();
                DcmItem* pItem = seq->getItem(0);

                if (pItem != NULL)
                {
                    DcmElement* pSubElement = NULL;
                    nSubData = pItem->card();
                    for (j = 0; j<nSubData; j++)
                    {
                        pSubElement = NULL;
                        pSubElement = pItem->getElement(j);

                        if (pSubElement->getVR() == EVR_PN)
                        {
                            int nRet = 0;
                            nRet = ConvertPatientName(pSubElement, strConv);
                            pSubElement->getOFStringArray(strData);

                            if (nRet>=0)
                            {
                                nConv++;
                            }
                            else
                            {

                            }
                        }

                        if (pSubElement != NULL)
                        {
                            tag = pSubElement->getTag();
                            pSubElement->getOFStringArray(strData);
                        }
                    }

                }
            }
        }
        else
        {
            pElement->getOFStringArray(strData);
        }

        if (vr == EVR_PN)
        {
            int nRet = 0;
            nRet = ConvertPatientName(pElement, strConv);
            pElement->getOFStringArray(strData);

            if (nRet >= 0)
            {
                nConv++;
            }
            else
            {

            }


        }
    }
    */

    return nConv;
}

int SDCMFindSCUDataCallback::ConvertPatientName(DcmElement* pElement, OFString strEncDICOM)
{
    int nRet = 0;
    /*

    CStringA strEncSystem = CSDCMStringEncoder::GetStringEncSystem();

    OFString strData;
    pElement->getOFStringArray(strData);

    OFString strConv;
    nRet = CSDCMStringEncoder::ConvertString(strData, strConv, strEncDICOM, strEncSystem);

    if (nRet >= 0)
    {
        pElement->putOFStringArray(strConv);

        pElement->getOFStringArray(strData);
    }
    */

    return nRet;
}

OFString SDCMFindSCUDataCallback::FindCharacterSet(DcmItem* pDcmItem)
{
    int i = 0;
    OFString strData = "";

    /*
    for (i = 0; i < pDcmItem->card(); i++)
    {
        strData.clear();

        DcmElement* pElement = NULL;
        pElement = pDcmItem->getElement(i);
        DcmTag tag = pElement->getTag();
        int nGroup = tag.getGroup();
        int nElement = tag.getElement();

        DcmEVR vr;
        vr = pElement->getVR();

        if (tag == DCM_ScheduledProcedureStepSequence)
        {
            DcmSequenceOfItems* seq = NULL;
            seq = (DcmSequenceOfItems*)pElement;

            if (seq != NULL)
            {
                int j = 0;
                int nSubData = seq->card();
                DcmItem* pItem = seq->getItem(0);

                if (pItem != NULL)
                {
                    DcmElement* pSubElement = NULL;
                    nSubData = pItem->card();
                    for (j = 0; j < nSubData; j++)
                    {
                        pSubElement = NULL;
                        pSubElement = pItem->getElement(j);



                        if (pSubElement != NULL)
                        {
                            tag = pSubElement->getTag();

                            if (tag == DCM_SpecificCharacterSet)
                            {
                                pSubElement->getOFStringArray(strData);
                                return strData;
                            }


                        }
                    }

                }
            }
        }
        else if(tag==DCM_SpecificCharacterSet)
        {
            pElement->getOFStringArray(strData);
            return strData;

        }
    }
    */

    return "";
}

void SDCMFindSCUDataCallback::ReadSequence(DcmElement* pElement, WorklistResponseData* wr)
{
    CommonData* pCommonData = MainWindow::GetCommonData();
    QString strEnc = pCommonData->GetDICOMCharacterSet();

    DcmSequenceOfItems* seq = NULL;
    seq = (DcmSequenceOfItems*)pElement;

    //CSDCM test1;
    DcmTag tag;
    DcmItem* pSubItem = NULL;


    OFString strData;
    DcmTagKey dcmKey;

    DcmEVR vr;


    DcmTagKey tagKey;
    pElement->getTagVal(tagKey);

    vr = pElement->getVR();


    if (seq != NULL)
    {
        //CSDCM* pChild = test1.InsertSequence(tag);
        int j = 0;

        int nSubData = seq->card();
        DcmItem* pItem = seq->getItem(0);

        if (pItem != NULL)
        {
            DcmElement* pSubElement = NULL;
            nSubData = pItem->card();
            for (j = 0; j<nSubData; j++)
            {
                pSubElement = NULL;
                pSubElement = pItem->getElement(j);

                if (pSubElement != NULL)
                {
                    tag = pSubElement->getTag();
                    pSubElement->getOFStringArray(strData);

                    DcmEVR vrChild = pSubElement->getVR();

                    if(vrChild==EVR_SQ)
                    {

                        ReadSequence(pSubElement, wr);
                    }

                    if(vrChild==EVR_PN || vrChild==EVR_LO)
                    {
                        //strData = CharConvert::EUCKRtoUTF8(strData.data()).toStdString().c_str();
                        if(strEnc=="EUC-KR")
                        {
                            strData = CharConvert::Convert(strData.data(), "UTF-8").toStdString().c_str();
                        }


                    }
                    wr->InsertData(tag, strData);

                    //pChild->InsertTagValue(tag, strData);
                }
            }

        }
    }


    /*
    if (tag == DCM_ScheduledProcedureStepSequence)
    {
        DcmSequenceOfItems* seq = NULL;
        seq = (DcmSequenceOfItems*)pElement;

        if (seq != NULL)
        {
            int j = 0;

            int nSubData = seq->card();
            DcmItem* pItem = seq->getItem(0);

            if (pItem != NULL)
            {
                DcmElement* pSubElement = NULL;
                nSubData = pItem->card();
                for (j = 0; j<nSubData; j++)
                {
                    pSubElement = NULL;
                    pSubElement = pItem->getElement(j);

                    if (pSubElement != NULL)
                    {
                        tag = pSubElement->getTag();
                        pSubElement->getOFStringArray(strData);

                        if(tag==DCM_PatientName)
                        {
                            strData = MainWindow::EUCKRtoUTF8(strData.data()).toStdString();
                        }
                        wr->InsertData(tag, strData);
                    }
                }

            }
        }
    }
    */
}
