/******************************motorcontroll.cpp文件说明**********************************
* Descript	:源文件，包含主窗口的页面设计、函数的实现、信号的连接
* Author    :caitiancheng
* Date      :2021_12_19
*******************************************************************************/


/***********************************头文件****************************************/
#include "motorcontroll.h"
#include "ui_motorcontroll.h"
#include<QDateTime>
#include <QCloseEvent>


/***********************************类的声明和继承****************************************/
MotorControll::MotorControll(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MotorControll)
{
    ui->setupUi(this);


    //从站连接状态定时器
    StatuTimer=new QTimer;
    //时间显示定时器
    TimeShow=new QTimer;
    //监视栏定时器
    Monitor=new QTimer;


    //控件连接的信号和槽函数
    InitConnect();
    //状态栏界面设置初始化函数
    InitBarStatus();
    //监视栏舒适化函数
    InitMonitor();

    //未进行通信连接时设置按钮不可按
    //基础配置的按钮（3个）
    ui->pushButton_2->setEnabled(false);
    ui->pushButton_3->setEnabled(false);
    ui->pushButton_4->setEnabled(false);
    //点动的按钮（6个）
    ui->DotKeepRunBtn->setEnabled(false);
    ui->DotPositiveBtn->setEnabled(false);
    ui->DotReverseBtn->setEnabled(false);
    ui->DotSpeedUpdataBtn->setEnabled(false);
    ui->DotStepUpdataBtn->setEnabled(false);
    ui->DotStopRunBtn->setEnabled(false);
    //基础运动的按钮（8个）
    ui->RunKeepBtn->setEnabled(false);
    ui->RunPlaceUpdataBtn->setEnabled(false);
    ui->RunSpeedUpdataBtn->setEnabled(false);
    ui->RunStartAbsolutBtn->setEnabled(false);
    ui->RunStartPlaceModifyBtn->setEnabled(false);
    ui->RunStartRelativeBtn->setEnabled(false);
    ui->RunStopBtn->setEnabled(false);
    ui->RunTimeUpdataBtn->setEnabled(false);
    //多段运动的按钮（5个）+1个多选框
    ui->RunMoreAddRunBtn->setEnabled(false);
    ui->RunMoreDataUpdataBtn->setEnabled(false);
    ui->RunMoreKeepBtn->setEnabled(false);
    ui->RunMoreModelBox->setEnabled(false);
    ui->RunMoreStartBtn->setEnabled(false);
    ui->RunMoreStopBtn->setEnabled(false);

}



/******************************************************析构函数*****************************************************/
MotorControll::~MotorControll()
{
    //销毁状态栏显示相关
    delete ConStatusText;
    delete ConStatusImg;
    delete SalveStatusText;
    delete SalveStatusShow;

    //销毁定时器
    delete StatuTimer;
    delete TimeShow;
    delete Monitor;


    //销毁监视栏的监视对象
    int MonitorLogsLen=MonitorLogs.length();
    for(int i=0;i<MonitorLogsLen;i++)
    {
       delete MonitorLogs.at(i);
    }
    delete MonitorSM2001;
    delete MonitorSM2010;
    delete MonitorSM2011;
    delete MonitorSM2012;
    delete MonitorSD2042;
    delete MonitorSD2040;
    delete MonitorSD2001;
    delete MonitorSD2010;
    delete MonitorSD2008;
    delete MonitorSD2030;
    delete MonitorSD2032;
    delete MonitorSD2034;
    delete MonitorSD2036;


    delete ui;
}


/****************************InitBarStatus函数*********************************
Function    :初始化界面状态栏，进行相应的设置
Output      :
*********************************************************************/
void MotorControll::InitBarStatus()
{
    ui->statusBar->setStyleSheet(QString("QStatusBar::item{border:0px}"));
    ConStatusText=new QLabel;
    ConStatusText->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    ConStatusText->setText(QStringLiteral("通信状态："));
    ui->statusBar->addPermanentWidget(ConStatusText);

    ConStatusImg=new QLabel;
    ConStatusImg->setStyleSheet(m_red_SheetStyle);
    ConStatusImg->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    ui->statusBar->addPermanentWidget(ConStatusImg);

    SalveStatusText=new QLabel;
    SalveStatusText->setMinimumWidth(100);
    SalveStatusText->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    SalveStatusText->setText(QStringLiteral("从站状态："));
    ui->statusBar->addPermanentWidget(SalveStatusText);

    SalveStatusShow=new QLabel;
    SalveStatusShow->setMinimumWidth(60);
    SalveStatusShow->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    SalveStatusShow->setText(QStringLiteral("其它"));
    ui->statusBar->addPermanentWidget(SalveStatusShow);
}


/****************************InitConnect函数*********************************
Function    :主窗口界面涉及的槽函数和信号的连接
Output      :
*********************************************************************/
void MotorControll::InitConnect()
{
    connect(&Xcon,SIGNAL(CloseWin()),this,SLOT(Slot_ShowWin()));
    connect(&Apar,SIGNAL(CloseWin()),this,SLOT(Slot_ShowWin()));
    connect(&Movement,SIGNAL(CloseWin()),this,SLOT(Slot_ShowWin()));
    connect(StatuTimer,SIGNAL(timeout()),this,SLOT(Slot_Status()));
    connect(Monitor,SIGNAL(timeout()),this,SLOT(Slot_Monitor()));

    //开启从站连接状态定时器
    StatuTimer->start(1000);
    //开启监视栏定时器
    Monitor->start(500);
    //开启时间显示定时器
    TimeShow->start(1000);
    //连接定时器和timeout信号
    connect(TimeShow,&QTimer::timeout,[=](){
        ui->statusBar->showMessage(QDateTime::currentDateTime().toString( "yyyy年MM月dd日 hh:mm:ss"));
    });
    //多段运动启动与停止绑定
    connect(ui->RunMoreStopBtn,SIGNAL(clicked()),this,SLOT(on_RunStopBtn_clicked()));
    connect(ui->RunMoreKeepBtn,SIGNAL(clicked()),this,SLOT(on_RunKeepBtn_clicked()));
}



/****************************Slot_Status函数*********************************
Function    :从站状态显示函数
Output      :
*********************************************************************/
void MotorControll::Slot_Status()
{
    //如果从站连接成功，变为绿色，开启按钮；否则是红色，关闭按钮
    if(ConStatus())
    {
         ConStatusImg->setStyleSheet(m_green_SheetStyle);
         //基础配置的按钮（3个）
         ui->pushButton_2->setEnabled(true);
         ui->pushButton_3->setEnabled(true);
         ui->pushButton_4->setEnabled(true);
         //点动的按钮（6个）
         ui->DotKeepRunBtn->setEnabled(true);
         ui->DotPositiveBtn->setEnabled(true);
         ui->DotReverseBtn->setEnabled(true);
         ui->DotSpeedUpdataBtn->setEnabled(true);
         ui->DotStepUpdataBtn->setEnabled(true);
         ui->DotStopRunBtn->setEnabled(true);
         //基础运动的按钮（8个）
         ui->RunKeepBtn->setEnabled(true);
         ui->RunPlaceUpdataBtn->setEnabled(true);
         ui->RunSpeedUpdataBtn->setEnabled(true);
         ui->RunStartAbsolutBtn->setEnabled(true);
         ui->RunStartPlaceModifyBtn->setEnabled(true);
         ui->RunStartRelativeBtn->setEnabled(true);
         ui->RunStopBtn->setEnabled(true);
         ui->RunTimeUpdataBtn->setEnabled(true);
         //多段运动的按钮（5个）+1个多选框
         ui->RunMoreAddRunBtn->setEnabled(true);
         ui->RunMoreDataUpdataBtn->setEnabled(true);
         ui->RunMoreKeepBtn->setEnabled(true);
         ui->RunMoreModelBox->setEnabled(true);
         ui->RunMoreStartBtn->setEnabled(true);
         ui->RunMoreStopBtn->setEnabled(true);
    }
    else
    {
         ConStatusImg->setStyleSheet(m_red_SheetStyle);
         //基础配置的按钮（3个）
         ui->pushButton_2->setEnabled(false);
         ui->pushButton_3->setEnabled(false);
         ui->pushButton_4->setEnabled(false);
         //点动的按钮（6个）
         ui->DotKeepRunBtn->setEnabled(false);
         ui->DotPositiveBtn->setEnabled(false);
         ui->DotReverseBtn->setEnabled(false);
         ui->DotSpeedUpdataBtn->setEnabled(false);
         ui->DotStepUpdataBtn->setEnabled(false);
         ui->DotStopRunBtn->setEnabled(false);
         //基础运动的按钮（8个）
         ui->RunKeepBtn->setEnabled(false);
         ui->RunPlaceUpdataBtn->setEnabled(false);
         ui->RunSpeedUpdataBtn->setEnabled(false);
         ui->RunStartAbsolutBtn->setEnabled(false);
         ui->RunStartPlaceModifyBtn->setEnabled(false);
         ui->RunStartRelativeBtn->setEnabled(false);
         ui->RunStopBtn->setEnabled(false);
         ui->RunTimeUpdataBtn->setEnabled(false);
         //多段运动的按钮（5个）+1个多选框
         ui->RunMoreAddRunBtn->setEnabled(false);
         ui->RunMoreDataUpdataBtn->setEnabled(false);
         ui->RunMoreKeepBtn->setEnabled(false);
         ui->RunMoreModelBox->setEnabled(false);
         ui->RunMoreStartBtn->setEnabled(false);
         ui->RunMoreStopBtn->setEnabled(false);
    }
    //显示对应的从站状态
    switch (SalveStatus()) {
    case 1:
    {
        SalveStatusShow->setText(QStringLiteral("INIT"));
        break;
    }
    case 2:
    {
        SalveStatusShow->setText(QStringLiteral("PreOP"));
        break;
    }
    case 4:
    {
        SalveStatusShow->setText(QStringLiteral("SafeOP"));
        break;
    }
    case 8:
    {
        SalveStatusShow->setText(QStringLiteral("OP"));
        break;
    }
    default:
        SalveStatusShow->setText(QStringLiteral("其它"));
        break;
    }
}




/****************************Slot_ShowWin函数*********************************
Function    :设置对话框为模态窗口
Output      :
*********************************************************************/
void MotorControll::Slot_ShowWin()
{
    this->setWindowModality(Qt::ApplicationModal);
}


/****************************InitMonitor函数*********************************
Function    :初始化监视窗口的函数
Output      :
*********************************************************************/
void MotorControll::InitMonitor()
{
    //添加表头
    QStringList TableHeadTitle;
    int TableHeadTitleLength;
    TableHeadTitle.push_back(QStringLiteral("寄存器"));
    TableHeadTitle.push_back(QStringLiteral("监控值"));
    TableHeadTitle.push_back(QStringLiteral("备注"));
    TableHeadTitleLength=TableHeadTitle.length();
    ui->DataMonitorTableWidget->setColumnCount(TableHeadTitleLength);
    ui->DataMonitorTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    for(int i=0;i<TableHeadTitleLength;i++)
    {
       TableHeadItem.push_back(new QTableWidgetItem(TableHeadTitle[i]));
       ui->DataMonitorTableWidget->setHorizontalHeaderItem(i,TableHeadItem[i]);
    }
    //添加监控值初始数据
    AddMonitorVal(&MonitorSM2001,"false","SM2001","轴运动标识");
    AddMonitorVal(&MonitorSM2010,"false","SM2010","使能标识");
    AddMonitorVal(&MonitorSM2011,"false","SM2011","正向点动标识");
    AddMonitorVal(&MonitorSM2012,"false","SM2012","反向点动标识");

    AddMonitorVal(&MonitorSD2042,"0","SD2042","点动速度");
    AddMonitorVal(&MonitorSD2040,"0","SD2040","点动步长");
    AddMonitorVal(&MonitorSD2001,"0","SD2001","运行模式");
    AddMonitorVal(&MonitorSD2010,"0","SD2010","当前运行速度");
    AddMonitorVal(&MonitorSD2008,"0","SD2008","当前位置");
    AddMonitorVal(&MonitorSD2030,"0","SD2030","设定位置");
    AddMonitorVal(&MonitorSD2032,"0","SD2032","设定速度");
    AddMonitorVal(&MonitorSD2034,"0","SD2034","设定加速时间");
    AddMonitorVal(&MonitorSD2036,"0","SD2036","设定减速时间");
}




/****************************AddMonitorVal函数*********************************
Function    :添加监视栏数据
Output      :
*********************************************************************/
 void MotorControll::AddMonitorVal(QTableWidgetItem **Item,QString Value,QString QStrName,QString QStrVal)
 {
       int Row=ui->DataMonitorTableWidget->rowCount();
       ui->DataMonitorTableWidget->insertRow(Row);
       MonitorLogs.push_back(new QTableWidgetItem(QStrName));
       MonitorLogs.at(MonitorLogs.length()-1)->setTextAlignment(Qt::AlignCenter);
       ui->DataMonitorTableWidget->setItem(Row,0,MonitorLogs.at(MonitorLogs.length()-1));
       (*Item)=new QTableWidgetItem(Value);
       (*Item)->setTextAlignment(Qt::AlignCenter);
       ui->DataMonitorTableWidget->setItem(Row,1,*Item);
       MonitorLogs.push_back(new QTableWidgetItem(QStrVal));
       MonitorLogs.at(MonitorLogs.length()-1)->setTextAlignment(Qt::AlignCenter);
       ui->DataMonitorTableWidget->setItem(Row,2,MonitorLogs.at(MonitorLogs.length()-1));
 }




/****************************SetMonitorVal函数*********************************
Function    :将需要监控的对象加入到监视表中
Output      :
*********************************************************************/
void MotorControll::SetMonitorVal(QTableWidgetItem *Item,bool Type,int addr)
{
     if(Type)
     {
        Item->setText(QString::number(ReadSDShort(addr)));
     }else
     {
         if(ReadSMBool(addr))
         {
              Item->setText("true");
         }else
         {
              Item->setText("false");
         }
     }
 }




/****************************Slot_Monitor函数*********************************
Function    :信号，当触发该信号时，将需要监视的对象设置到监视表中
Output      :
*********************************************************************/
void MotorControll::Slot_Monitor()
{
    SetMonitorVal(MonitorSM2001,false,2001);
    SetMonitorVal(MonitorSM2010,false,2010);
    SetMonitorVal(MonitorSM2011,false,2011);
    SetMonitorVal(MonitorSM2012,false,2012);

    SetMonitorVal(MonitorSD2042,true,2042);
    SetMonitorVal(MonitorSD2040,true,2040);
    SetMonitorVal(MonitorSD2001,true,2001);
    SetMonitorVal(MonitorSD2010,true,2010);
    SetMonitorVal(MonitorSD2008,true,2008);
    SetMonitorVal(MonitorSD2030,true,2030);
    SetMonitorVal(MonitorSD2032,true,2032);
    SetMonitorVal(MonitorSD2034,true,2034);
    SetMonitorVal(MonitorSD2036,true,2036);
}





/****************************通信连接按钮的槽函数函数*********************************
Function    :点击通信连接按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_pushButton_clicked()
{
    Xcon.setWindowFlags(Qt::Dialog|Qt::WindowCloseButtonHint);
    Xcon.setWindowModality(Qt::ApplicationModal);
    Xcon.show();
}




/****************************C运动相关参数配置的槽函数*********************************
Function    :点击C运动参数配置按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_pushButton_2_clicked()
{
    Apar.setWindowFlags(Qt::Dialog|Qt::WindowCloseButtonHint|Qt::WindowMaximizeButtonHint);
    Apar.setWindowModality(Qt::ApplicationModal);
    Apar.show();
}





/****************************************************点动模块*****************************************************/
/****************************开启电机的槽函数*********************************
Function    :点击开启电机按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_pushButton_3_clicked()
{
    //关闭
     WriteMBool(5,false);
     WriteMBool(10,false);
     WriteMBool(15,false);
     WriteMBool(20,false);
     WriteMBool(25,false);
     WriteMBool(30,false);
     WriteMBool(35,false);
     //使能
     WriteMBool(0,true);
}



/****************************关闭电机的槽函数*********************************
Function    :点击关闭电机按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_pushButton_4_clicked()
{
    //关闭
     WriteMBool(5,false);
     WriteMBool(10,false);
     WriteMBool(15,false);
     WriteMBool(20,false);
     WriteMBool(25,false);
     WriteMBool(30,false);
     WriteMBool(35,false);
     WriteMBool(0,false);
}



/****************************更新步长的槽函数*********************************
Function    :点击更新步长按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_DotStepUpdataBtn_clicked()
{
    short value=ui->DotStepLedit->text().toShort();
    WriteDShort(0,value);
}



/****************************更新点动速度的槽函数*********************************
Function    :点击更新点动速度按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_DotSpeedUpdataBtn_clicked()
{
    short value=ui->DotSpeedLedit->text().toShort();
    WriteDShort(50,value);
}



/****************************正向点动的槽函数*********************************
Function    :点击正向点动按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_DotPositiveBtn_clicked()
{
    WriteMBool(10,false);
    WriteMBool(5,true);
}



/****************************反向点动的槽函数*********************************
Function    :点击反向点动按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_DotReverseBtn_clicked()
{
    WriteMBool(5,false);
    WriteMBool(10,true);
}



/****************************停止运动的槽函数*********************************
Function    :点击停止运动按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_DotStopRunBtn_clicked()
{
    WriteMBool(15,true);
}



/****************************继续运动的槽函数*********************************
Function    :点击继续运动按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_DotKeepRunBtn_clicked()
{
    WriteMBool(15,false);
}





/****************************************************基础运动模块*****************************************************/
/****************************更新位置的槽函数*********************************
Function    :点击更新位置按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_RunPlaceUpdataBtn_clicked()
{
    int value=ui->RunPlaceLedit->text().toInt();
    WriteDInt(100,value);
}



/****************************更新速度的槽函数*********************************
Function    :点击更新速度按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_RunSpeedUpdataBtn_clicked()
{
    int value=ui->RunSpeedLedit->text().toInt();
    WriteDInt(150,value);
}





/****************************更新时间的槽函数*********************************
Function    :点击更新时间按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_RunTimeUpdataBtn_clicked()
{
    int value=ui->RunTimeLedit->text().toInt();
    WriteDInt(200,value);
}




/****************************修改位置的槽函数*********************************
Function    :点击修改位置按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_RunStartPlaceModifyBtn_clicked()
{
    int value=ui->RunStartPlaceLedit->text().toInt();
     WriteDInt(450,value);
     WriteMBool(40,true);
     WriteMBool(40,false);
}




/****************************绝对运动的槽函数*********************************
Function    :点击绝对运动按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_RunStartAbsolutBtn_clicked()
{
    WriteMBool(30,true);
    WriteMBool(30,false);
}



/****************************相对运动的槽函数*********************************
Function    :点击相对运动按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_RunStartRelativeBtn_clicked()
{
    WriteMBool(25,true);
    WriteMBool(25,false);
}



/****************************停止运动的槽函数*********************************
Function    :点击停止运动按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_RunStopBtn_clicked()
{
    WriteMBool(20,false);
    WriteMBool(15,true);
}


/****************************继续运动的槽函数*********************************
Function    :点击继续运动按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_RunKeepBtn_clicked()
{
    WriteMBool(15,false);
    WriteMBool(20,true);
}




/****************************************************多段运动模块*****************************************************/
/****************************添加运动的槽函数*********************************
Function    :点击添加运动按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_RunMoreAddRunBtn_clicked()
{
    Movement.setWindowFlags(Qt::Dialog|Qt::WindowCloseButtonHint|Qt::WindowMaximizeButtonHint);
    Movement.setWindowModality(Qt::ApplicationModal);
    Movement.show();
}


/****************************更新数据的槽函数*********************************
Function    :点击更新数据按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_RunMoreDataUpdataBtn_clicked()
{
    int AddValue=ui->RunMoreAddSpeedTimeLedit->text().toInt();
    int SubValue=ui->RunMoreSubSpeedTimeLedit->text().toInt();
    int RunModel=ui->RunMoreModelBox->currentIndex();

    WriteDInt(400,RunModel);
    WriteDInt(404,AddValue);
    WriteDInt(406,SubValue);
}


/****************************启动运动的槽函数*********************************
Function    :点击启动运动按钮，会触发该槽函数
Output      :
*********************************************************************/
void MotorControll::on_RunMoreStartBtn_clicked()
{
    WriteMBool(35,true);
    WriteMBool(35,false);
}



/****************************closeEvent函数*********************************
Function    :窗口关闭事件函数
Output      :
*********************************************************************/
void MotorControll::closeEvent(QCloseEvent *event)
{
    QMessageBox::StandardButton Value=QMessageBox::question(this,QStringLiteral("退出提示"),QStringLiteral("确认退出程序?"));
      if(Value==QMessageBox::Yes)
      {
          emit CloseWin();
          event->accept();
      }else
      {
          event->ignore();
      }
}
