#include "entitywidget.h"
#include "lightpoint.h"
#include "switchbutton.h"
#include "tcpsocket.h"
#include "global.h"

#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QLineEdit>
#include <QTreeView>
#include <QMessageBox>
#include <QToolButton>
#include <QTextCodec>
#include <QMenu>
#include <QAction>
#include <QDebug>

#include "treemodel.h"
#include "treeitem.h"

EntityWidget::EntityWidget(QWidget *parent)
    : QWidget(parent)
{
    initUI();
    connects();
}

void EntityWidget::initUI()
{
    mMainVLayout = new QVBoxLayout;

    QHBoxLayout* hlayout1 = new QHBoxLayout;
    QVBoxLayout* vlayout1 = new QVBoxLayout;

    mHostHLayout = new QHBoxLayout;
    mLabelHost = new QLabel("主机:");
    mLineEditHost = new QLineEdit;
    mHostHLayout->addWidget(mLabelHost);
    mHostHLayout->addWidget(mLineEditHost);

    mPortHLayout = new QHBoxLayout;
    mLabelPort = new QLabel("端口:");
    mLineEditPort = new QLineEdit;
    mPortHLayout->addWidget(mLabelPort);
    mPortHLayout->addWidget(mLineEditPort);

    vlayout1->addLayout(mHostHLayout);
    vlayout1->addLayout(mPortHLayout);
    hlayout1->addLayout(vlayout1);

    mLightPoint = new LightPoint;
    mLightPoint->setBgColor(Qt::red);
    mLightPoint->setFixedSize(80, 80);

    hlayout1->addWidget(mLightPoint);

    mControlHLayout = new QHBoxLayout;
    mSwitchButton = new SwitchButton;
    mSwitchButton->setFixedHeight(50);
    mUpdateEntityButton = new QToolButton;
    mUpdateEntityButton->setIcon(QIcon(":/images/refresh.png"));
    mUpdateEntityButton->setIconSize(QSize(40, 40));
    mUpdateEntityButton->setEnabled(false);
    mControlHLayout->addWidget(mSwitchButton);
    mControlHLayout->addWidget(mUpdateEntityButton);

    mMainVLayout->addLayout(hlayout1);
    mMainVLayout->addLayout(mControlHLayout);

    mEntityTreeView = new QTreeView;
    mEntityTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
    const QStringList headers({ "实体节点" });
    mEntityTreeModel = new TreeModel(headers, "");
    QString title = "实体节点";
    QVector<QVariant> rootData;
    rootData << title;
    mEntityTreeRootItem = new TreeItem(rootData);
    mEntityTreeView->setModel(mEntityTreeModel);
    mEntityTreeModel->setRootItem(mEntityTreeRootItem);

    mMainVLayout->addWidget(mEntityTreeView);

    mTcpSocket = new TcpSocket(this);

    ServerParam p = Global::Instance()->serverParam();
    mLineEditHost->setText(p.host);
    mLineEditPort->setText(QString::number(p.port));

    mEntityContentMenu = new QMenu(mEntityTreeView);
    mEntityLocationAction = new QAction("定位");
    mEntityRouteVisibleAction = new QAction("航线显示/隐藏");
    mEntityNameVisibleAction = new QAction("名称显示/隐藏");
    mEntityFocusingAction = new QAction("聚焦");
    mEntityContentMenu->addAction(mEntityLocationAction);
    mEntityContentMenu->addAction(mEntityRouteVisibleAction);
    mEntityContentMenu->addAction(mEntityNameVisibleAction);
    mEntityContentMenu->addAction(mEntityFocusingAction);

    this->setLayout(mMainVLayout);
}

void EntityWidget::connects()
{
    connect(mSwitchButton, &SwitchButton::setupOn, this, &EntityWidget::connectServer);
    connect(mSwitchButton, &SwitchButton::setupOff, this, &EntityWidget::disConnectServer);

    connect(mTcpSocket, SIGNAL(error(QAbstractSocket::SocketError)),
            this, SLOT(displaySocketError(QAbstractSocket::SocketError)));
    connect(mTcpSocket, &QTcpSocket::connected, this, [=](){
        mLightPoint->setBgColor(Qt::green);
        mUpdateEntityButton->setEnabled(true);
        mSwitchButton->setChecked(true);
    });

    connect(mTcpSocket, &QTcpSocket::disconnected, this, [=](){
        mLightPoint->setBgColor(Qt::red);
        mUpdateEntityButton->setEnabled(false);
        mSwitchButton->setChecked(false);
    });
    connect(mTcpSocket, &QTcpSocket::readyRead, this, &EntityWidget::readMessage);
    connect(mUpdateEntityButton, &QToolButton::clicked, this, &EntityWidget::updateEntity);

    connect(mEntityTreeModel, &QAbstractItemModel::dataChanged,
            this, &EntityWidget::onTreeDataChanged);

    connect(mEntityTreeView, &QTreeView::customContextMenuRequested, this, &EntityWidget::showMenu);
    connect(mEntityContentMenu, &QMenu::triggered, this, &EntityWidget::actionTriggered);
}

bool EntityWidget::connectServerConditionJudge()
{
    QString host = mLineEditHost->text();
    if(host.isEmpty())
    {
        QMessageBox msgBox;
        msgBox.setWindowTitle("提示");
        msgBox.setText("服务器主机为空，请填写主机的ip.");
        msgBox.exec();
        return false;
    }

    QString strport = mLineEditPort->text();
    if(strport.isEmpty())
    {
        QMessageBox msgBox;
        msgBox.setWindowTitle("提示");
        msgBox.setText("服务器端口为空，请填写主机的端口.");
        msgBox.exec();
        return false;
    }
    else if(strport.toInt() <= 0)
    {
        QMessageBox msgBox;
        msgBox.setWindowTitle("提示");
        msgBox.setText("服务器端口必须为大于0的正整数.");
        msgBox.exec();
        return false;
    }

    return true;
}

void EntityWidget::connectServer()
{
    if(!connectServerConditionJudge())
    {
        mSwitchButton->setChecked(false);
        return;
    }
    QString host = mLineEditHost->text();
    QString strport = mLineEditPort->text();

    ServerParam p = {host, strport.toInt()};
    Global::Instance()->setServerParam(p);

    mTcpSocket->abort();
    mTcpSocket->connectToHost(host, strport.toInt());
}

void EntityWidget::disConnectServer()
{
    mTcpSocket->disconnectFromHost();
}

void EntityWidget::readMessage()
{
    QByteArray data = mTcpSocket->readAll();
    QString utf8data = QString::fromUtf8(data);
    parsingData(utf8data);
}

void EntityWidget::displaySocketError(QAbstractSocket::SocketError)
{
    qDebug() << mTcpSocket->errorString();
    mLightPoint->setBgColor(Qt::red);
    mUpdateEntityButton->setEnabled(false);
    mSwitchButton->setChecked(false);
}

void EntityWidget::updateEntity()
{
    QByteArray data = "all_entity;";
    mTcpSocket->write(data);
}

void EntityWidget::parsingData(const QString& data)
{
    QStringList dataList = data.split(";");
    if(!dataList.size())
        return;
    QString commond = dataList.at(0);
    //"all_entity;1,FighterAircraft,战斗机1,2400_23.5141_120.31_0;2,boat,小船1,3000_23.3452_119.828_0"
    if(commond == "all_entity")
    {
        QList<Entity> entityList;
        mEntityTreeRootItem->clear();
        for(int i = 1; i < dataList.size(); i++)
        {
            Entity entity;
            QString str = dataList.at(i);
            QStringList strList = str.split(",");
            if(strList.size() >= 4)
            {
                entity.id = strList.at(0);
                entity.type = strList.at(1);
                entity.name = strList.at(2);
                entity.department = strList.at(3);
                for(int j = 4; j < strList.size(); j++)
                {
                    QString strCoor = strList.at(j);
                    QStringList strCoorList = strCoor.split("_");
                    if(strCoorList.size() >= 7)
                    {
                        CPoint p;
                        p.time = strCoorList.at(0).toInt();
                        p.longitude = strCoorList.at(1).toFloat();
                        p.latitude = strCoorList.at(2).toFloat();
                        p.altitude = strCoorList.at(3).toFloat();
                        p.pitch = strCoorList.at(4).toFloat();
                        p.yaw = strCoorList.at(5).toFloat();
                        p.roll = strCoorList.at(6).toFloat();

                        entity.route.insert(j - 4, p);
                    }

                }
            }

            QVector<QVariant> itemdata = {entity.name};
            TreeItem* entityItem = new TreeItem(itemdata);
            QVariantMap attr;
            attr["ID"] = entity.id;
            attr["Type"] = entity.type;
            attr["Name"] = entity.name;
            attr["Department"] = entity.department;
            entityItem->setAttributes(attr);
            mEntityTreeRootItem->addChildren(entityItem);
            mEntityTreeModel->updateData();
            entityList.append(entity);
        }

        // setEntityList(entityList);
        emit allEntityInfo(entityList);
    }
    else if(commond == "all_lla")
    {
        QList<MoveEntity> moveEntityList;
        //all_lla;1,23.4586,116.452,16.6667;2,22.6399,116.879,0
        for(int i = 1; i < dataList.size(); i++)
        {
            QString str = dataList.at(i);
            QStringList strList = str.split(",");
            if(strList.size() >= 7)
            {
                MoveEntity moveEntity;
                moveEntity.id = strList.at(0);
                moveEntity.longitude = strList.at(1).toFloat();
                moveEntity.latitude = strList.at(2).toFloat();
                moveEntity.altitude = strList.at(3).toFloat();
                moveEntity.pitch = strList.at(4).toFloat();
                moveEntity.yaw = strList.at(5).toFloat();
                moveEntity.roll = strList.at(6).toFloat();
                moveEntityList.append(moveEntity);
            }
        }
        //moveEntityList(list);
        emit allLongitudeLatitudeAltitude(moveEntityList);
    }
}

void EntityWidget::onTreeDataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight)
{
    TreeItem *item = static_cast<TreeItem*>(topLeft.internalPointer());
    if (item->checkable(topLeft.column()))
    {
        // QString name = item->data(0).toString();
        QString entityId = item->attributes()["ID"].toString();
        emit entityVisible(entityId, item->isChecked());
    }
}

void EntityWidget::showMenu(const QPoint &point)
{
    TreeItem* item = mEntityTreeModel->getItem(mEntityTreeView->currentIndex());
    if(item)
    {
        QPoint pos = QCursor::pos();
        //    QPoint parentPos = ui->treeViewNode->pos();
        //    QPoint pos = mapToGlobal(parentPos);
        //    pos += point;
        //    pos.setY(pos.y() + mMenu->height());
        mEntityContentMenu->move(pos);
        mEntityContentMenu->show();
    }
}

void EntityWidget::actionTriggered(QAction *action)
{
    TreeItem* item = mEntityTreeModel->getItem(mEntityTreeView->currentIndex());
    if(!item)
        return;
    QString id = item->attributes()["ID"].toString();
    if(action == mEntityLocationAction)
    {
        emit entityLocation(id);
    }
    else if(action == mEntityRouteVisibleAction)
    {
        emit entityRouteVisible(id);
    }
    else if(action == mEntityNameVisibleAction)
    {
        emit entityNameVisible(id);
    }
    else if(action == mEntityFocusingAction)
    {
        emit entityFocusing(id);
    }
}
