#include "modulecomm.h"
#include <iostream>

#include "modulecomm_shm.h"

#include "modulecomm_inter.h"
#ifdef USE_FASTRTPS
#include "modulecomm_fastrtps_shm.h"
#include "modulecomm_fastrtps_tcp.h"
#endif

#include <QtXml>
#include <QFile>

namespace iv {
namespace modulecomm {

struct ModeduleInfo
{
    modulecomm_base * mphandle;
    ModuleComm_TYPE mmctype;
};

static ModuleComm_TYPE getdefmodulecommtype()
{
#ifdef  ANDROID
    return ModuleComm_INTERIOR;
#endif
    ModuleComm_TYPE xrtn = ModuleComm_SHAREMEM;
    QDomDocument xdoc;
    QFile file("./modulecomm.xml");
    if (!file.open(QIODevice::ReadOnly))
    {
        return xrtn;
    }
    if (!xdoc.setContent(&file)) {
        file.close();
        return xrtn;
    }
    file.close();
    QDomElement docElem = xdoc.documentElement();

    QDomNode n = docElem.firstChild();
    while(!n.isNull())
    {
    QDomElement e = n.toElement();
    if(e.nodeName() == "commtype")
    {
        QString strvalue = e.attribute("value","0");
        if(strvalue == "0")
        {
            xrtn = ModuleComm_SHAREMEM;
        }
        if(strvalue == "1")
        {
            xrtn = ModuleComm_INTERIOR;
        }
#ifdef USE_FASTRTPS
        if(strvalue == "2")
        {
            xrtn = ModuleComm_FASTRTPS;
        }
#endif
        break;
    }
        n = n.nextSibling();
    }

    return xrtn;
}


void *  RegisterSend(const char * strcommname)
{
    return RegisterSend(strcommname,1000,1);
}

void *  RegisterSend(const char * strcommname,const unsigned int nBufSize,const unsigned int nMsgBufCount,
                     ModuleComm_TYPE xmctype,const unsigned short nport)
{

    iv::modulecomm::ModeduleInfo * pmi = new iv::modulecomm::ModeduleInfo;
    pmi->mmctype = xmctype;
    pmi->mphandle = 0;
    ModuleComm_TYPE mctype = xmctype;
    if(mctype == ModuleComm_UNDEFINE)
    {
        mctype = getdefmodulecommtype();
    }
    switch (mctype) {
    case ModuleComm_SHAREMEM:
    {
        iv::modulecomm_shm * p = new iv::modulecomm_shm();
        p->RegisterSend(strcommname,nBufSize,nMsgBufCount);
        pmi->mphandle = (iv::modulecomm_base *)p;
    }
        break;
    case ModuleComm_INTERIOR:
    {
        iv::modulecomm_inter * p = new iv::modulecomm_inter();
        p->RegisterSend(strcommname,nBufSize,nMsgBufCount);
        pmi->mphandle = (iv::modulecomm_base *)p;
    }
        break;

#ifdef USE_FASTRTPS
    case ModuleComm_FASTRTPS:
    {
        iv::modulecomm_fastrtps_shm * p = new iv::modulecomm_fastrtps_shm();
        p->RegisterSend(strcommname,nBufSize,nMsgBufCount);
        pmi->mphandle = (iv::modulecomm_base *)p;
    }
        break;

    case ModuleComm_FASTRTPS_TCP:
    {
        iv::modulecomm_fastrtps_tcp * p = new iv::modulecomm_fastrtps_tcp();
        p->RegisterSend(strcommname,nBufSize,nMsgBufCount,nport);
        pmi->mphandle = (iv::modulecomm_base *)p;
    }
        break;
#endif
    default:
        break;
    }
    return pmi;
}


void  *  RegisterRecv(const char * strcommname,SMCallBack pCall,ModuleComm_TYPE xmctype,const char * strip,
                      const unsigned short nPort)
{
    iv::modulecomm::ModeduleInfo * pmi = new iv::modulecomm::ModeduleInfo;
    pmi->mmctype = xmctype;
    pmi->mphandle = 0;
    ModuleComm_TYPE mctype = xmctype;
    if(mctype == ModuleComm_UNDEFINE)
    {
        mctype = getdefmodulecommtype();
    }
    switch (mctype) {
    case ModuleComm_SHAREMEM:
    {
        iv::modulecomm_shm * p = new iv::modulecomm_shm();
        p->RegisterRecv(strcommname,pCall);
        pmi->mphandle = (iv::modulecomm_base *)p;
    }
        break;
    case ModuleComm_INTERIOR:
    {
        iv::modulecomm_inter * p = new iv::modulecomm_inter();
        p->RegisterRecv(strcommname,pCall);
        pmi->mphandle = (iv::modulecomm_base *)p;
    }
        break;

#ifdef USE_FASTRTPS
    case ModuleComm_FASTRTPS:
    {
        iv::modulecomm_fastrtps_shm * p = new iv::modulecomm_fastrtps_shm();
        p->RegisterRecv(strcommname,pCall);
        pmi->mphandle = (iv::modulecomm_base *)p;
    }
        break;

    case ModuleComm_FASTRTPS_TCP:
    {
        iv::modulecomm_fastrtps_tcp * p = new iv::modulecomm_fastrtps_tcp();
        p->RegisterRecv(strcommname,pCall,strip,nPort);
        pmi->mphandle = (iv::modulecomm_base *)p;
    }
        break;
#endif
    default:
        break;
    }
    return pmi;
}

void *  RegisterRecvPlus(const char * strcommname,ModuleFun xFun,
                                                ModuleComm_TYPE xmctype,const char * strip,
                         const unsigned short nPort)
{
    iv::modulecomm::ModeduleInfo * pmi = new iv::modulecomm::ModeduleInfo;
    pmi->mmctype = xmctype;
    pmi->mphandle = 0;
    ModuleComm_TYPE mctype = xmctype;
    if(mctype == ModuleComm_UNDEFINE)
    {
        mctype = getdefmodulecommtype();
    }
    switch (mctype) {
    case ModuleComm_SHAREMEM:
    {
        iv::modulecomm_shm * p = new iv::modulecomm_shm();
        p->RegisterRecvPlus(strcommname,xFun);
        pmi->mphandle = (iv::modulecomm_base *)p;
    }
        break;
    case ModuleComm_INTERIOR:
    {
        iv::modulecomm_inter * p = new iv::modulecomm_inter();
        p->RegisterRecvPlus(strcommname,xFun);
        pmi->mphandle = (iv::modulecomm_base *)p;
    }
        break;
#ifdef USE_FASTRTPS
    case ModuleComm_FASTRTPS:
    {
        iv::modulecomm_fastrtps_shm * p = new iv::modulecomm_fastrtps_shm();
        p->RegisterRecvPlus(strcommname,xFun);
        pmi->mphandle = (iv::modulecomm_base *)p;
    }
        break;

    case ModuleComm_FASTRTPS_TCP:
    {
        iv::modulecomm_fastrtps_tcp * p = new iv::modulecomm_fastrtps_tcp();
        p->RegisterRecvPlus(strcommname,xFun,strip,nPort);
        pmi->mphandle = (iv::modulecomm_base *)p;
    }
        break;
#endif
    default:
        break;
    }
    return pmi;
}

void  ModuleSendMsg(void * pHandle,const char * strdata,const unsigned int nDataLen)
{
    iv::modulecomm::ModeduleInfo * pmi = (iv::modulecomm::ModeduleInfo  * )pHandle;
    if(pmi->mphandle == 0)
    {
        qDebug("handler error. use fastrtps but not define.");
        return;
    }
    pmi->mphandle->ModuleSendMsg(strdata,nDataLen);
}

void  Unregister(void * pHandle)
{
    iv::modulecomm::ModeduleInfo * pmi = (iv::modulecomm::ModeduleInfo  * )pHandle;
    if(pmi->mphandle == 0)
    {
        qDebug("handler error. use fastrtps but not define.");
        return;
    }
    pmi->mphandle->Unregister();
}

void PauseComm(void *pHandle)
{
    iv::modulecomm::ModeduleInfo * pmi = (iv::modulecomm::ModeduleInfo  * )pHandle;
    if(pmi->mphandle == 0)
    {
        qDebug("handler error. use fastrtps but not define.");
        return;
    }
    pmi->mphandle->PauseComm();
}

void ContintuComm(void *pHandle)
{
    iv::modulecomm::ModeduleInfo * pmi = (iv::modulecomm::ModeduleInfo  * )pHandle;
    if(pmi->mphandle == 0)
    {
        qDebug("handler error. use fastrtps but not define.");
        return;
    }
    pmi->mphandle->ContintuComm();
}

}
}