#include "mainwindow.h"
#include "ui_mainwindow.h"

iv::Ivlog *givlog;
unsigned int gv2xEn = true;

void ListenV2xStEn(const char * strdata,const unsigned int nSize,const unsigned int index,const QDateTime * dt,const char * strmemname)
{
//    if(nSize < sizeof(iv::v2x::v2xStEn))
//    {
//        givlog->error("v2x","ListenV2xStEn size error %d",nSize,sizeof(iv::v2x::v2xStEn));
//        return;
//    }

    iv::v2x::v2xStEn xv2xStEnMsg;
    if(!xv2xStEnMsg.ParseFromArray(strdata,nSize))
    {
        givlog->error("iv::v2x::v2xStEn::ListenV2xStEn parse error");
        return;
    }
    gv2xEn = xv2xStEnMsg.v2xsten();

    givlog->info("v2x", "v2x enable st: %d", gv2xEn);
}

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    socket=new QTcpSocket();    
    ui->lineEdit_ip->setText("47.95.196.28");
    ui->lineEdit_port->setText("12123");
    ui->pushButton_connect->setEnabled(false);
    //连接信号槽

    givlog = new iv::Ivlog("v2x");
    connect(socket, &QTcpSocket::readyRead, this, &MainWindow::socket_Read_Data);
    connect(socket, &QTcpSocket::disconnected, this, &MainWindow::socket_Disconnected);

    mp_v2xSend = iv::modulecomm::RegisterSend("v2x",1000,3);
    iv::modulecomm::RegisterRecv("v2xStEn", ListenV2xStEn);
    mp_v2xStSend = iv::modulecomm::RegisterSend("v2xStReq",1000,1);
    shareV2xStReqMsg();
    //heart beat,jiaolili,20210207
    m_bEnablePlatform=false;
    m_bIsConnect=false;
    QTimer *timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),SLOT(heartBeat()));
    timer->start(1000);
    ///////////////////////////////////////////

}

MainWindow::~MainWindow()
{
    delete this->socket;
    delete ui;
}
void MainWindow::heartBeat()
{
    if(gv2xEn) {
        if(!m_bEnablePlatform) {
            connectPlatform();
        }
        if(m_bIsConnect) {
            upDataStream();
        } else {
            connectPlatform();
        }

    } else {
        if(m_bEnablePlatform) {
            disconnectPlatform();
        }
    }
    m_bEnablePlatform = gv2xEn;
}
void MainWindow::upDataStream()
{
//    upVehicleStatus();
//    upHardwareStatus();
//   upObstacleDataStatus();
    upSoftwareStatus();
}
void MainWindow::socket_Read_Data()
{
    QByteArray buffer;
    //读取缓冲区数据
    buffer = socket->readAll();

    if(!buffer.isEmpty())
    {
        //QString str = QString::fromLocal8Bit(buffer);
        QString str = QString(buffer);

//        ui->textEdit_messages->insertPlainText("服务器消息:"+str+"\n");
        QStringList list = str.split(",");
        int length=list.size();
//        if(str.contains("FFCC")) {
//            QString len=QString::number(length);
//            ui->textEdit_messages->insertPlainText("服务器消息:"+str+"\n");
//            ui->textEdit_messages->insertPlainText("服务器消息:"+len+"\n");

//        }
        if(length>=4) {
            if(checkVehicle(list[2])) {
                ui->textEdit_messages->insertPlainText("服务器消息:"+str+"\n");
                ui->textEdit_messages->insertPlainText("服务器消息:vehicle id is ok!\n");
                int downstream_id =getDownStreamId(list[0]);
                switch (downstream_id) {
                    case StopCommand:
                        ProStopCommand(list[3]);
                        break;
                    case AutoPilotControl:
                        if(length>4) {
                            ProAutoPilotControl(list);
                        }
                        break;
                    case StationCommand:
                        ProStationCommand(list[3]);
                        break;
                    default:
                        break;


                }
            } else {
                ui->textEdit_messages->insertPlainText("服务器消息:vehicle id is wrong!\n");
            }

        }
    }
}
//云平台急停指令
void MainWindow::ProStopCommand(QString str)
{
    int tmp;
    iv::v2x::v2x msgV2xProto;
    msgV2xProto.Clear();
    QStringList list=str.split("]");
    if(list.size()>0) {
        tmp = list[0].toInt();
        if(tmp==0) {
            msgV2xProto.set_emergencystop(0);
            ui->textEdit_messages->insertPlainText("服务器消息:vehicle emergency stop cancel!\n");
            shareV2xProtoMsg(msgV2xProto);
        }
        else if(tmp==1) {
            msgV2xProto.set_emergencystop(1);
            ui->textEdit_messages->insertPlainText("服务器消息:vehicle emergency stop enable!\n");
            shareV2xProtoMsg(msgV2xProto);
        }
    }
}
//云平台工作模式&坐标索引指令
void MainWindow::ProAutoPilotControl(QStringList list)
{
    iv::v2x::v2x msgV2xProto;
    iv::v2x::stationsGPS *stGps;
    msgV2xProto.Clear();
    int tmp = list[3].toInt();
    int length=list.size();
    int stationId;
    if(tmp==1) {
        msgV2xProto.set_carmode(1);
        if(length>5) {
            QStringList tmp_list0=list[4].split("[");
            list[4]=tmp_list0[1];
            QStringList tmp_list1=list[length-1].split("]]");
            list[length-1]=tmp_list1[0];
            for(int i=4;i<length;i++) {
                stationId = list[i].toInt();
                msgV2xProto.add_stationid(stationId);

                stGps=msgV2xProto.add_stgps();
                stGps->set_lat(0);
                stGps->set_lon(0);
                ui->textEdit_messages->insertPlainText("服务器消息:car station has "+list[i]+"\n");
            }
        } else {
            ui->textEdit_messages->insertPlainText("服务器消息:car station at least 2!\n");
        }

    } else {
        msgV2xProto.set_carmode(0);
        ui->textEdit_messages->insertPlainText("服务器消息:car autoDrive mode cancle!\n");
    }
    shareV2xProtoMsg(msgV2xProto);
}
//云平台站点停止指令
void MainWindow::ProStationCommand(QString str)
{
    int tmp;
    iv::v2x::v2x msgV2xProto;
    msgV2xProto.Clear();
    QStringList list=str.split("]");
    if(list.size()>0) {
        tmp = list[0].toInt();
        if(tmp==0) {
            msgV2xProto.set_stationstop(1);//站点启动
            shareV2xProtoMsg(msgV2xProto);
            ui->textEdit_messages->insertPlainText("服务器消息:vehicle station start!\n");
        }
        else if(tmp==1) {
            msgV2xProto.set_stationstop(0);//下一站停车
            shareV2xProtoMsg(msgV2xProto);
            ui->textEdit_messages->insertPlainText("服务器消息:vehicle station top!\n");
        }
    }
}

bool MainWindow::checkVehicle(QString str)
{
    return true;
}
int MainWindow::getDownStreamId(QString str)
{
    int downstream_id=-1;
    if(str.contains("FFAA")) {
        ui->textEdit_messages->insertPlainText("服务器消息:StopCommand!\n");
        downstream_id=1;
        return downstream_id;
    }
    if(str.contains("FFCC")) {
        ui->textEdit_messages->insertPlainText("服务器消息:AutoPilotControl!\n");
        downstream_id=2;
        return downstream_id;
    }
    if(str.contains("FFBB")) {
        ui->textEdit_messages->insertPlainText("服务器消息:StationCommand!\n");
        downstream_id=3;
        return downstream_id;
    }
    return downstream_id;
}
void MainWindow::socket_Disconnected()
{

    //修改按键文字
    ui->pushButton_connect->setText("connect");
    ui->textEdit_messages->insertPlainText("服务器消息:Disconnected");
}
void MainWindow::connectPlatform()
{
    QString IP;
    int port;
    //获取IP地址
    IP = ui->lineEdit_ip->text();
    //获取端口号
    port = ui->lineEdit_port->text().toInt();
    ui->textEdit_messages->setText("");
    ui->textEdit_messages->insertPlainText("正在连接"+ui->lineEdit_ip->text()+":"+ui->lineEdit_port->text()+"\n");
    //取消已有的连接
    socket->abort();
    //连接服务器
    socket->connectToHost(IP, port);
    //等待连接成功
    if(!socket->waitForConnected(30000)) {
        ui->textEdit_messages->insertPlainText("连接失败\n");
        return;
    }
    m_bIsConnect = true;
    ui->textEdit_messages->insertPlainText("连接成功\n");
    //修改按键文字
    ui->pushButton_connect->setText("disconnect");
}

void MainWindow::disconnectPlatform()
{
    //断开连接
    ui->textEdit_messages->setText("断开连接\n");
    socket->disconnectFromHost();
    //修改按键文字
    ui->pushButton_connect->setText("connect");
    m_bIsConnect=false;
}
void MainWindow::on_pushButton_connect_clicked()
{
    if(ui->pushButton_connect->text() == tr("connect"))
    {
        QString IP;
        int port;

        //获取IP地址
        IP = ui->lineEdit_ip->text();
        //获取端口号
        port = ui->lineEdit_port->text().toInt();
        ui->textEdit_messages->setText("");
        ui->textEdit_messages->insertPlainText("正在连接"+ui->lineEdit_ip->text()+":"+ui->lineEdit_port->text()+"\n");
        //取消已有的连接
        socket->abort();
        //连接服务器
        socket->connectToHost(IP, port);
        //等待连接成功
        if(!socket->waitForConnected(30000))
        {
            QMessageBox::warning(this,tr("消息"),tr("连接失败!请重新连接"),QMessageBox::Yes);
            ui->textEdit_messages->insertPlainText("连接失败\n");
            return;
        }
        ui->textEdit_messages->insertPlainText("连接成功\n");
        QMessageBox::information(this,tr("消息"),tr("连接成功"),QMessageBox::Yes);


        //修改按键文字
        ui->pushButton_connect->setText("disconnect");
    }
    else
    {
        //断开连接
        ui->textEdit_messages->setText("断开连接\n");
        socket->disconnectFromHost();
        //修改按键文字
        ui->pushButton_connect->setText("connect");
    }
}


void MainWindow::on_textEdit_messages_textChanged()
{
    ui->textEdit_messages->moveCursor(QTextCursor::End);
}

QString MainWindow::getTimeStamp()
{
    QDateTime time = QDateTime::currentDateTime();
    int current_timestamp=time.toTime_t();
    QString str=QString::number(current_timestamp);
    return  str;
}

void MainWindow::shareV2xProtoMsg(iv::v2x::v2x msgV2xProto)
{
    int nsize = msgV2xProto.ByteSize();
    char * strdata = new char[msgV2xProto.ByteSize()];
    if(msgV2xProto.SerializePartialToArray(strdata,nsize))
    {
        iv::modulecomm::ModuleSendMsg(mp_v2xSend,strdata,nsize);
    }
    givlog->info("v2x","share v2x controll Msg");
    delete strdata;
}
//请求v2状态,是否接收v2x的控制,由ui发送
void MainWindow::shareV2xStReqMsg()
{
    iv::v2x::v2xStReq x;
    x.set_v2xstreq(1);
    int nsize = x.ByteSize();
    char * str = new char[nsize];
    if(x.SerializeToArray(str,nsize))
    {
        iv::modulecomm::ModuleSendMsg(mp_v2xStSend,str,nsize);
    }
    else
    {
        givlog->error("v2x","send require error");
    }
    givlog->info("v2x","send st req");
    delete str;
}
//void MainWindow::on_pushButton_sendVehicle_clicked()
//{
//    QString head= "[";
//    QString packageID="'DDFF'";
//    QString time_stamp=getTimeStamp();
//    QString test="['DDFF',"+time_stamp+",[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[2,0]]";
//    //QByteArray bytes = test.toUtf8();
//    QByteArray bytes = test.toLatin1();
//    socket->write(bytes);
//}

void MainWindow::upVehicleStatus()
{
    QString time_stamp=getTimeStamp();
    QString test="['CCFF',"+time_stamp+",'catarc001',1,0,0,100,0,0,0,0,0]";
    //QByteArray bytes = test.toUtf8();
    QByteArray bytes = test.toLatin1();
    socket->write(bytes);
}
void MainWindow::upHardwareStatus()
{
    QString time_stamp=getTimeStamp();
    QString test="['DDFF',"+time_stamp+",[0,0],[0,0],[0,0],[0,0],[0,0],[0,0],[[0,0],[0,0]],[2,0]]";
    //QByteArray bytes = test.toUtf8();
    QByteArray bytes = test.toLatin1();
    socket->write(bytes);
}
void MainWindow::upObstacleDataStatus()
{
    QString time_stamp=getTimeStamp();
    QString test="['EEFF',"+time_stamp+",[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]]";
    //QByteArray bytes = test.toUtf8();
    QByteArray bytes = test.toLatin1();
    socket->write(bytes);
}
void MainWindow::upSoftwareStatus()
{
    QString time_stamp=getTimeStamp();
    QString test="['FFFF',"+time_stamp+",[1,10,1,10,1,10,1,10],[0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0]]";
    //QByteArray bytes = test.toUtf8();
    QByteArray bytes = test.toLatin1();
    socket->write(bytes);
}