#ifndef SDATAGROUP
#define SDATAGROUP
#include <QVector>
#include <QSet>
#include <QMap>
#include <QList>
#include "../common.h"
class SInitializer;
class QString;
class QStringList;
class QSqlDatabase;

QString sqlString(QString _str);
QString UniCodeToEucKr(const QString& _strData);

class SDatagroup
{
public:
    enum E_ARTICLE
    {
        E_ARTICLE_BODY = 0,
        E_ARTICLE_REPLY,
        E_ARTICLE_MAX,
    };
    struct stBody
    {
        int num;
        int id_num;
        QString id_id;
        int nickname_num;
        int community_num;
        int platformname_num;
        int platformform_num;
        QString* title;
        QString* data;
        QString url;
        int view;
        QString date;
        int replystartnum;
        int replyendnum;
        int replycount;
        QVector<int> realbycategorynum;


        QString lastupdate;
        QString community_title;
        QString community_url;
        QString community_id;
        QString community_exid;
        QString platformname_name;
        QString platformform_form;
        QString nickname_nickname;
        QString nickname_exnickname;

        //QSet<int> realbycategorynum;
        stBody():replyendnum(-1), replystartnum(-1), replycount(0) {}
    };

    struct stReply
    {
        int num;
        int id_num;
        QString id_id;
        int nickname_num;
        int community_num;
        int body_num;
        QString parent;
        QString* data;
        QString date;
        QVector<int> realbycategorynum;


        int platformname_num;
        int platformform_num;
        QString platformname_name;
        QString platformform_form;
        QString nickname_nickname;
        QString nickname_exnickname;
        QString body_date;
        //QSet<int> realbycategorynum;
        stReply():num(0),id_num(0),nickname_num(0),community_num(0),body_num(0),platformname_num(0),platformform_num(0){}
    };
    struct stCommunity
    {
        int num;
        QString id;
        QString exid;
        QString title;
        QString url;
        int platformname_num;
        int platformform_num;
        stCommunity():num(0), platformform_num(1), platformname_num(1), title("(none)"), url(" "), id(" "), exid(" ") {}
    };
    struct stId
    {
        int num;
        QString id;
        int community_num;
        int platformname_num;
        stId():num(0), id("(none)"), community_num(0), platformname_num(1) {}
    };
    struct stNickname
    {
        int num;
        QString nickname;
        int id_num;
        stNickname():num(0) {}
    };
    struct stProfileurlKey
    {
        int m_nPlatformForm;
        QString m_strId;
        stProfileurlKey(int _nPlatform, const QString& _strId):m_nPlatformForm(_nPlatform), m_strId(_strId) {}
        bool operator<(const stProfileurlKey& other) const
        {
            if (m_nPlatformForm < other.m_nPlatformForm)
            {
                return true;
            }
            else if ((m_nPlatformForm == other.m_nPlatformForm) && (m_strId < other.m_strId))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        bool operator==(const stProfileurlKey &other) const
        {
            if ((m_nPlatformForm == other.m_nPlatformForm) && (m_strId == other.m_strId))
                return true;
            else
                return false;
        }
    };

    class SBody
    {
    private:
        //QList<stBody> m_listBody;
        SInitializer *m_pSInitializer;
        QMap<QString, stBody> m_mapBody;
    public:
        void put(const QString& _url, const stBody& _stbody);
        bool putCategory(const QString& _url, const int& _nCategory);
        bool uploadData(QSqlDatabase &_db, const int& _nCompany, const QStringList& _order);
        bool changeTable(QSqlDatabase &_db, const int& nCompany);
        int getBodyNum(const QString& _url);
        QString vecToString(const QVector<int>& _realbycategorynum);
        QString vecToString(const QSet<int> &_realbycategorynum);
        void setInitializer(SInitializer &initializer){ m_pSInitializer = &initializer; }
        stBody* get(const QString& _url);
        void clear();
    };

    class SReply
    {
    private:
        //QList<stReply> m_listReply;
        SInitializer *m_pSInitializer;
        QMap<QString, QMap<int, stReply> > m_mapReply;
    public:
        void put(const QString& _url, const int& _order, const stReply& _streply);
        bool putCategory(const QString &_url, const int &_order, int& _nCategory);
        bool uploadData(QSqlDatabase &_db, const int& _nCompany, QStringList& _order);
        bool changeTable(QSqlDatabase &_db, const int& _nCompany);
        int getReplyNum(const QString &_url, const int& _order);
        stReply* get(const QString& _url, const int& _order);
        QMap<int, stReply>* get(const QString& _url);
        QString vecToString(const QVector<int>& _realbycategorynum);
        void setInitializer(SInitializer &initializer){ m_pSInitializer = &initializer; }
        void clear();
    };
    class SId
    {
    private:
        QMap<QString, stId> m_mapId;
        SInitializer *m_pSInitializer;
    public:
        bool contains(const QString& _strKey);
        void put(const QString& _strKey, const stId& _stid);
        void put(const stId& _stid);
        QString getIdKey(const QStringList& _strlist);
        stId* get(const QString &_strKey);
        bool changeTable(QSqlDatabase &_db, const int& _nCompany);
        bool uploadData(QSqlDatabase &_db, const int& _nCompany);
        void setInitializer(SInitializer &initializer){ m_pSInitializer = &initializer; }
        void clear();
    };
    class SNickname
    {
    private:
        QMap<QString, stNickname> m_mapNickname;
        SInitializer *m_pSInitializer;
    public:
        //QString getNicknameKey(const QStringList& _strlist);
        stNickname* get(const QString &_strKey);
        bool changeTable(QSqlDatabase &_db, const int& _nCompany);
        bool uploadData(QSqlDatabase &_db, const int& _nCompany);
        void put(const QString& _strKey, const stNickname& _stnickname);
        void put(const stNickname& _nickname);
        bool contains(const QString& _strKey);
        void setInitializer(SInitializer &initializer){ m_pSInitializer = &initializer; }
        void clear();
    };
    class SCommunity
    {
    private:
        QMap<QString, stCommunity> m_mapCommunity;
        SInitializer *m_pSInitializer;
    public:
        QString getCommunityKey(const QStringList& _strlist);
        stCommunity* get(const QString &_strKey);
        bool changeTable(QSqlDatabase &_db, const int& _nCompany);
        bool uploadData(QSqlDatabase &_db, const int& _nCompany);
        void put(const QString& _strKey, const stCommunity& _stcommunity);
        bool contains(const QString& _strKey);
        void clear();
        void setInitializer(SInitializer &initializer){ m_pSInitializer = &initializer; }
    };
    struct stBodyReplyCount
    {
        int m_nAllBodyCount;
        int m_nAllReplyCount;
        int m_nFilterBodyCount;
        int m_nFilterReplyCount;
        stBodyReplyCount():m_nAllBodyCount(0), m_nAllReplyCount(0), m_nFilterBodyCount(0), m_nFilterReplyCount(0){}
    };
    struct stDate
    {
        QString m_strMindate;
        QString m_strMaxdate;
        QString m_strLastupdate;
        stDate():m_strMindate("2100-12-31 23:59:59"), m_strMaxdate("1900-01-01 00:00:00"), m_strLastupdate("1900-01-01 00:00:00"){}
    };

private:
    SInitializer* m_pSInitializer;
    QSet<QString> m_setFilteredUrl;

    QStringList m_slOrderedBodyUrl;
    QMap<QString, QMap<int, QStringList> > m_mapReply;
    QMap<QString, QStringList> m_mapBody;
    QMap<stProfileurlKey, QStringList*> m_mapProfile;


    SBody m_SBody;
    SReply m_SReply;
    SCommunity m_SCommunity;
    SId m_SId;
    SNickname m_SNickname;
    stBodyReplyCount m_stBodyReplyCount;
    stDate m_stDate;

public:
    void setInitializer(SInitializer &initializer);
    bool loadData(const int& _nDatagroupNumber);
    bool uploadData(const int& _nCompany);
    bool changeTable(const int& _nCompany);
    bool makeTable();
    void addRealUrl(const QString& _strUrl);
    void copyData(QVector<QStringList> *_data);
    const QMap<QString, QStringList>* getmapBody();
    const QStringList* getmapBody(const stProfileurlKey& _stprofileurlkey);
    const QMap<QString, QMap<int, QStringList> >* getmapReply();
    const stBody* getstBody(const QString& _strUrl);
    const stReply* getstReply(const QString& _strUrl, const int &_order);
    const QMap<int, stReply>* getstReply(const QString& _strUrl);
    int getstBodyNum(const QString& _strUrl);
    int getstReplyNum(const QString& _strUrl, const int &_order);
    const QStringList* getOrderedUrl();
    void addRealBodyCategory(const QString& _strUrl, const int _nCategory);
    void addRealReplyCategory(const QString& _strUrl, const int& _order, int _nCategory);
    const stCommunity* getstCommunity(const QStringList& _sl);
    const stBodyReplyCount* getCounts();
    const stDate* getstDate();

private:
    void init();
    void setloadQuery(QString _astrQuery[], int _nDatagroupNumber);
    void makeProfile(const QStringList& _strList);
};


#endif // SDATAGROUP

