#include "plcsetup.hpp"
#include "common.h"
#include <iostream>
#include <fstream>
#include <thread>
#include <qdebug.h>
#include <qlineedit.h>
#include <qmessagebox.h>
#include <QIntValidator>
#include "PLCDevice.h"
#define PLC_ITEM_FILE    "D:/conf/plc.txt"

extern PLCDevice * m_PLCDevice;

extern bool g_plc_dialog_open;	//是否打开plc配置对话框

void task_osk_()
{
	system("start /b C:\\Windows\\system32\\osk.exe");
}

PlcSetup::PlcSetup(QWidget * parent) : QDialog(parent) {
	ui.setupUi(this);
	this->setWindowFlags(Qt::FramelessWindowHint);
	read_plc_items();
	ui.tableWidget->setColumnCount(7);
	ui.tableWidget->setRowCount(m_plc_items.size());
	QStringList header_list;
	header_list << QStringLiteral("功能描述") << QStringLiteral("读数值")
		<< QStringLiteral("读操作") << QStringLiteral("写数值") << QStringLiteral("写操作") << QStringLiteral("保存") << QStringLiteral("备注") ;
	ui.tableWidget->setHorizontalHeaderLabels(header_list);
	ui.tableWidget->setColumnWidth(0, 200);
	ui.tableWidget->setColumnWidth(1, 100);
	ui.tableWidget->setColumnWidth(2, 50);
	ui.tableWidget->setColumnWidth(3, 100);
	ui.tableWidget->setColumnWidth(4, 50);
	ui.tableWidget->setColumnWidth(5, 50);
	ui.tableWidget->setColumnWidth(6, 390);
	ui.tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);   //禁止编辑
	for (int i = 0; i < m_plc_items.size(); i++)
	{
		ui.tableWidget->setItem(i, 0, new QTableWidgetItem(QString::fromLocal8Bit(m_plc_items[i].func_desc.c_str())));
		//ui.tableWidget->setItem(i, 1, new QTableWidgetItem(QString::number(m_plc_items[i].address)));
		QPushButton * pBtnR = new QPushButton();
		pBtnR->setText(QStringLiteral("读"));
		connect(pBtnR, SIGNAL(clicked(bool)), this, SLOT(click_read()));
		ui.tableWidget->setCellWidget(i, 2, pBtnR);

		QLineEdit *edit = new QLineEdit();
		edit->setValidator(new QIntValidator(0, 100000, this));
		ui.tableWidget->setCellWidget(i, 3, edit);

		QPushButton * pBtnW = new QPushButton();
		pBtnW->setText(QStringLiteral("写"));
		connect(pBtnW, SIGNAL(clicked(bool)), this, SLOT(click_write()));
		ui.tableWidget->setCellWidget(i, 4, pBtnW);

		QPushButton * pBtnS = new QPushButton();
		pBtnS->setText(QStringLiteral("保存"));
		connect(pBtnS, SIGNAL(clicked(bool)), this, SLOT(click_save()));
		ui.tableWidget->setCellWidget(i, 5, pBtnS);

		ui.tableWidget->setItem(i, 6, new QTableWidgetItem(QString::fromLocal8Bit(m_plc_items[i].memo.c_str())));
	}
	m_pTimer = new QTimer(this);
	connect(m_pTimer, SIGNAL(timeout()), this, SLOT(handleTimeout()));
	m_pTimer->setSingleShot(true);
	m_pTimer->start(1000);
}

PlcSetup::~PlcSetup() {
	
}

void PlcSetup::click_read()
{
	QPushButton *pushButton_ = dynamic_cast<QPushButton*>(this->sender());
	if (NULL == pushButton_)
	{
		return;
	}
	int x = pushButton_->frameGeometry().x();
	int y = pushButton_->frameGeometry().y();
	QModelIndex index = ui.tableWidget->indexAt(QPoint(x, y));
	int row = index.row();
	int column = index.column();

	int addr = m_plc_items[row].address;

	uint8_t dest[4];
	uint16_t * dest16 = (uint16_t *)dest;
	memset(dest, 0, 4);
	if (addr > 0)
	{
		if (addr < 40000)	//读取线圈值 bit
		{
			int ret = m_PLCDevice->read_bits_from_plc(addr, 1, dest);
			ui.tableWidget->setItem(row, 1, new QTableWidgetItem(QString::number(dest[0])));
		}
		else {				//读取DWORD值，4字节
			int ret = m_PLCDevice->read_short_from_plc( addr, 2, dest16);
			//printf("%x ", dest16[0]);
			//printf("%x \n", dest16[1]);
			//printf("%d \n", dest16[0] + (dest16[1] << 16));
			ui.tableWidget->setItem(row, 1, new QTableWidgetItem(QString::number(dest16[0] + (dest16[1] << 16))));
		}
	}
}

void PlcSetup::click_write()
{
	QPushButton *pushButton_ = dynamic_cast<QPushButton*>(this->sender());
	if (NULL == pushButton_)
	{
		return;
	}
	int x = pushButton_->frameGeometry().x();
	int y = pushButton_->frameGeometry().y();
	QModelIndex index = ui.tableWidget->indexAt(QPoint(x, y));
	int row = index.row();
	int column = index.column();
	//std::cout << "row:" << row << "\tcol:" << column << std::endl;
	
	int addr = m_plc_items[row].address;
	QWidget *widget=ui.tableWidget->cellWidget(row,3);
	QLineEdit *edit=(QLineEdit*)widget;
	QString d = edit->text();
	uint8_t dest[4];
	uint16_t * dest16 = (uint16_t *)dest;
	memset(dest, 0, 4);
	if (d.length() > 0)
	{
		int data = d.toInt();
		if (addr > 0)
		{
			if (addr < 40000)	//写入线圈值 bit
			{
				if (data != 0)	data = 1;
				int ret = m_PLCDevice->write_bit_2_plc( addr, data);
			}
			else {				//写入DWORD值，4字节
				dest16[0] = (data & 0xffff);
				dest16[1] = (data>>16);
				int ret = m_PLCDevice->write_short_2_plc(addr, 2, dest16);
			}
		}
		QMessageBox::information(NULL, QStringLiteral("提示"), QStringLiteral("写入成功"), QMessageBox::Ok);
	}
}

void PlcSetup::click_save()
{
	QPushButton *pushButton_ = dynamic_cast<QPushButton*>(this->sender());
	if (NULL == pushButton_)
	{
		return;
	}
	int x = pushButton_->frameGeometry().x();
	int y = pushButton_->frameGeometry().y();
	QModelIndex index = ui.tableWidget->indexAt(QPoint(x, y));
	int row = index.row();
	int column = index.column();
	//std::cout << "row:" << row << "\tcol:" << column << std::endl;

	int addr = m_plc_items[row].address;
	QWidget *widget = ui.tableWidget->cellWidget(row, 3);
	QLineEdit *edit = (QLineEdit*)widget;
	QString d = edit->text();
	uint8_t dest[4];
	uint16_t * dest16 = (uint16_t *)dest;
	memset(dest, 0, 4);
	if (d.length() > 0)
	{
		int data = d.toInt();
		if (addr > 0)
		{
			if (addr < 40000)	//写入线圈值 bit
			{
				if (data != 0)	data = 1;
				int ret = m_PLCDevice->write_bit_2_plc( addr, data);
			}
			else {				//写入DWORD值，4字节
				dest16[0] = (data & 0xffff);
				dest16[1] = (data >> 16);
				int ret = m_PLCDevice->write_short_2_plc(addr, 2, dest16);
			}
		}
		//int data = d.toInt();
		for (int i = 0; i < m_plc_items.size(); i++)
		{
			//std::cout << m_plc_items[i].address << std::endl;
			if (m_plc_items[i].address == addr)
			{
				//std::cout << "Hit" << addr << std::endl;
				m_plc_items[i].value = data;
				//std::cout << "SAVE start" << std::endl;
				save_plc_items();
				//std::cout << "SAVE END" << std::endl;
				QMessageBox::information(NULL, QStringLiteral("提示"), QStringLiteral("写入并且保存成功"), QMessageBox::Ok);
				break;
			}
		}
	}
}

void PlcSetup::on_toolButton_batch_read_released()
{
	for (int i = 0; i < m_plc_items.size(); i++)
	{
		int addr = m_plc_items[i].address;
		uint8_t dest[4];
		uint16_t * dest16 = (uint16_t *)dest;
		memset(dest, 0, 4);
		if (addr > 0)
		{
			if (addr < 40000)	//读取线圈值 bit
			{
				int ret = m_PLCDevice->read_bits_from_plc(addr, 1, dest);
				ui.tableWidget->setItem(i, 1, new QTableWidgetItem(QString::number(dest[0])));
			}
			else {				//读取DWORD值，4字节
				int ret = m_PLCDevice->read_short_from_plc( addr, 2, dest16);
				ui.tableWidget->setItem(i, 1, new QTableWidgetItem(QString::number(dest16[0] + (dest16[1] << 16))));
			}
		}
	}
}
void PlcSetup::on_toolButton_keyboard_released()
{
	std::thread osk_thread = std::thread(task_osk_);
	osk_thread.detach();
}
void PlcSetup::on_toolButton_close_released()
{
	g_plc_dialog_open = false;
	this->close();
}

void PlcSetup::handleTimeout()
{
	on_toolButton_batch_read_released();
}

void PlcSetup::read_plc_items()
{
	std::fstream cfg_file;
	cfg_file.open(PLC_ITEM_FILE);
	if (!cfg_file.is_open())
	{
		std::cout << "Error: Open production file " << PLC_ITEM_FILE << std::endl;
		return;
	}
	while (!cfg_file.eof())
	{
		char tmp[1024] = "";
		cfg_file.getline(tmp, 1024);
		std::string line(tmp);
		std::cout << line << std::endl;
		if (line.length() > 0)
		{
			std::vector<std::string> vec_info;
			string_split(line, "|", vec_info);
			if (vec_info.size() == 4)
			{
				PlcItem plc_item;
				plc_item.func_desc = vec_info[0];
				plc_item.address = atoi(vec_info[1].c_str());
				plc_item.value = atoi(vec_info[2].c_str());
				plc_item.memo = vec_info[3];
				m_plc_items.push_back(plc_item);
			}
		}
	}
	cfg_file.close();
}

void PlcSetup::save_plc_items()
{
	std::fstream cfg_file;
	cfg_file.open(PLC_ITEM_FILE, std::ios::out | std::ios::trunc);
	if (cfg_file.good())
	{
		for (int i = 0; i < m_plc_items.size(); i++)
		{
			char buf[512];
			memset(buf, 0, 512);
			sprintf(buf, "%s|%d|%d|%s\n", m_plc_items[i].func_desc.c_str(),
				m_plc_items[i].address, m_plc_items[i].value, m_plc_items[i].memo.c_str());
			cfg_file.write(buf, strlen(buf));
		}
		cfg_file.close();
	}
}
