#ifndef FMTOOL
#define FMTOOL

#include <windows.h>
#include <QString>
#include <QDebug>
#include "requestmodel.h"
#include "global.h"

class FMTool
{
public:
    static int GBKToUTF8(unsigned char * lpGBKStr,int gbkLen, unsigned char * lpUTF8Str,int nUTF8StrLen)
    {
        wchar_t * lpUnicodeStr = NULL;
        int nRetLen = 0;

        if(!lpGBKStr)  //如果GBK字符串为NULL则出错退出
            return 0;

        nRetLen = MultiByteToWideChar(CP_ACP,0,(char *)lpGBKStr,gbkLen,NULL,NULL);  //获取转换到Unicode编码后所需要的字符空间长度
        //lpUnicodeStr = new WCHAR[nRetLen + 1];  //为Unicode字符串空间
        lpUnicodeStr = (WCHAR*)malloc( sizeof(WCHAR)*(nRetLen + 1));

        nRetLen = MultiByteToWideChar(CP_ACP,0,(char *)lpGBKStr,gbkLen,lpUnicodeStr,nRetLen);  //转换到Unicode编码
        if(!nRetLen)  //转换失败则出错退出
            return 0;

        nRetLen = WideCharToMultiByte(CP_UTF8,0,lpUnicodeStr,nRetLen,NULL,0,NULL,NULL);  //获取转换到UTF8编码后所需要的字符空间长度

        if(!lpUTF8Str)  //输出缓冲区为空则返回转换后需要的空间大小
        {
            if(lpUnicodeStr)
                free(lpUnicodeStr);
            return nRetLen;
        }

        if(nUTF8StrLen < nRetLen)  //如果输出缓冲区长度不够则退出
        {
            if(lpUnicodeStr)
                free(lpUnicodeStr);
            return 0;
        }

        nRetLen = WideCharToMultiByte(CP_UTF8,0,lpUnicodeStr,nRetLen,(char *)lpUTF8Str,nUTF8StrLen,NULL,NULL);  //转换到UTF8编码

        if(lpUnicodeStr)
            free(lpUnicodeStr);

        return nRetLen;
    }

    static int UTF8ToGBK(unsigned char * lpUTF8Str,unsigned char * lpGBKStr,int nGBKStrLen)
    {
        wchar_t * lpUnicodeStr = NULL;
        int nRetLen = 0;

        if(!lpUTF8Str)  //如果UTF8字符串为NULL则出错退出
            return 0;

        nRetLen = MultiByteToWideChar(CP_UTF8,0,(char *)lpUTF8Str,-1,NULL,NULL);  //获取转换到Unicode编码后所需要的字符空间长度
        //lpUnicodeStr = new WCHAR[nRetLen + 1];  //为Unicode字符串空间
        lpUnicodeStr = (WCHAR*)malloc( sizeof(WCHAR)*(nRetLen + 1));
        nRetLen = MultiByteToWideChar(CP_UTF8,0,(char *)lpUTF8Str,-1,lpUnicodeStr,nRetLen);  //转换到Unicode编码
        if(!nRetLen)  //转换失败则出错退出
            return 0;

        nRetLen = WideCharToMultiByte(CP_ACP,0,lpUnicodeStr,-1,NULL,NULL,NULL,NULL);  //获取转换到GBK编码后所需要的字符空间长度

        if(!lpGBKStr)  //输出缓冲区为空则返回转换后需要的空间大小
        {
            if(lpUnicodeStr)
                free(lpUnicodeStr);
            return nRetLen;
        }

        if(nGBKStrLen < nRetLen)  //如果输出缓冲区长度不够则退出
        {
            if(lpUnicodeStr)
                free(lpUnicodeStr);
            return 0;
        }

        nRetLen = WideCharToMultiByte(CP_ACP,0,lpUnicodeStr,-1,(char *)lpGBKStr,nRetLen,NULL,NULL);  //转换到GBK编码

        if(lpUnicodeStr)
            free(lpUnicodeStr);

        return nRetLen;
    }

    //获取AlipayRequest中的值并过滤空格并进行编码转换
    static QString GetString(const void *beginptr, int size)
    {

        QString tmp = "";

        char buf[MAX_CHILED_LEN] = { 0 };
        char tmpbuf[MAX_CHILED_LEN] = { 0 };

        strncpy(buf, (char *)beginptr, size);

        //qDebug() << buf;

        for(int i = strlen(buf) - 1; i >= 0; --i )
        {
            if(buf[i] == ' ')
                buf[i] = 0;
            else
                break;
        }

        strcpy(tmpbuf, buf);

        int len = GBKToUTF8((unsigned char *)tmpbuf, strlen(tmpbuf), NULL, 0);

        char *utfbuf = (char *)malloc(sizeof(char) * (len + 2));
        memset(utfbuf, 0, len + 2);

        if(GBKToUTF8((unsigned char *)tmpbuf, strlen(tmpbuf), (unsigned char *)utfbuf, len + 1) > 0)
            tmp = QString(utfbuf);

        //qDebug() << tmp.toLatin1().data();

        return QString(tmpbuf);
    }


    static void SetString(void *beginptr, int size, const QString &in)
    {
        char buf[MAX_PRINT_LEN] = { 0 };
        char tmpbuf[MAX_PRINT_LEN] = { 0 };

        memset(beginptr, ' ', size);

        if(in.isEmpty())
            return ;

        strcpy(buf, in.toUtf8().data());

        int len = UTF8ToGBK((unsigned char *)buf, (unsigned char *)tmpbuf, MAX_PRINT_LEN);

        memcpy((char *)beginptr, tmpbuf, len - 1);

        //qDebug() << tmpbuf;

    }

    static void SetStringWith(void *beginptr, int size, const QString &in)
    {
        char buf[MAX_PRINT_LEN] = { 0 };
        char tmpbuf[MAX_PRINT_LEN] = { 0 };

        if(in.isEmpty())
            return ;

        strcpy(buf, in.toUtf8().data());

        int len = UTF8ToGBK((unsigned char *)buf, (unsigned char *)tmpbuf, MAX_PRINT_LEN);

        memcpy((char *)beginptr, tmpbuf, len - 1);

        //qDebug() << tmpbuf;

    }
	
    static QJsonValue GetJsonValue(const QJsonObject &jsonObj, const QString &key)
    {
        if(jsonObj.contains(key)) {
            return jsonObj[key];
        } else {
            foreach(QString k, jsonObj.keys()) {
                if(jsonObj[k].isObject()) {
                    QJsonObject ob = jsonObj[k].toObject();
                    QJsonValue value = GetJsonValue(ob, key);
                    if(!value.isNull()){
                        return value;
                    }
                }
            }
        }
        return QJsonValue();
    }


    static bool SearchXMLNodeString(const QString &xmlStr, const QString &nodeName, QString &nodeStr)
    {
        QRegularExpression regExp(QString("<%1>([\\s\\S]+)</%1>").arg(nodeName));
        int index = 0;
        QRegularExpressionMatch match;
        do {
            match = regExp.match(xmlStr, index);
            if(match.hasMatch()) {
                index = match.capturedEnd();
                nodeStr = match.captured(1).trimmed();
                return true;
            } else {
                break;
            }
        } while(index < xmlStr.length());
        return false;
    }
};


#endif // FMTOOL

