#include "brick_interface.h"


bool BrickInterfaceBaseIn::received(void * t, uchar * d, int s) {
	mutex.lock();
	BrickInterfaceBaseIn * i = (BrickInterfaceBaseIn * )t;
	memcpy(i->data.data(), d + i->header_, i->data.size() - i->header_);
	///i->struct_.readData(i->data.data());
	mutex.unlock();
	return true;
}


bool BrickInterfaceBaseIn::tick_body(double time) {
	mutex.lock();
	/**for (uint i = 0; i < struct_.count(); ++i)
		outputs[i + 1] = struct_[i].value();*/
	mutex.unlock();
	return true;
}


bool BrickInterfaceBaseOut::tick_body(double time) {
	mutex.lock();
	/**for (uint i = 0; i < struct_.count(); ++i)
		struct_[i].setValue(inputs[i]);
	struct_.writeData(data.data());*/
	mutex.unlock();
	return true;
}


void BrickInterfaceSerialIn::started() {
	parameterChanged(0);
	///struct_.writeData(data.data());
	header_ = parameters[5].toInt();
	ser.stop(false);
	ser.setDevice(parameters[1].toString());
	PIFlags<PISerial::Parameters> f = 0;
	if (parameters[2].toBool()) f |= PISerial::ParityControl;
	if (parameters[3].toBool()) f |= PISerial::TwoStopBits;
	ser.setParameters(f);
	ser.setSpeed((PISerial::Speed)parameters[4].toInt());
	ser.setThreadedReadSlot(received);
	ser.setThreadedReadData(this);
	//ser.setReadData(data.data(), header_, data.size() - header_);
	//cout << "header " << header_ << " bytes, data " << data.size() - header_ << " bytes" << endl;
	ser.start();
}


bool BrickInterfaceSerialIn::tick_body(double time) {
	outputs[0] = dbool(ser.isOpened());
	return BrickInterfaceBaseIn::tick_body(time);
}


void BrickInterfaceSerialOut::started() {
	parameterChanged(0);
	ser.stop(false);
	ser.setDevice(parameters[1].toString());
	PIFlags<PISerial::Parameters> f = 0;
	if (parameters[2].toBool()) f |= PISerial::ParityControl;
	if (parameters[3].toBool()) f |= PISerial::TwoStopBits;
	ser.setParameters(f);
	ser.setSpeed((PISerial::Speed)parameters[4].toInt());
	ser.initialize();
}


bool BrickInterfaceSerialOut::tick_body(double time) {
	BrickInterfaceBaseOut::tick_body(time);
	ser.send(data.data(), data.size());
	outputs[0] = dbool(ser.isOpened());
	return true;
}


void BrickInterfaceUDPIn::started() {
	parameterChanged(0);
	eth.stop(false);
	eth.setReadAddress(parameters[1].toString(), parameters[2].toInt());
	eth.setThreadedReadSlot(received);
	eth.setThreadedReadData(this);
	eth.start();
}


bool BrickInterfaceUDPIn::tick_body(double time) {
	outputs[0] = dbool(eth.isOpened());
	return BrickInterfaceBaseIn::tick_body(time);
}


bool BrickInterfaceUDPOut::tick_body(double time) {
	BrickInterfaceBaseOut::tick_body(time);
	if (eth.send(parameters[1].toString(), parameters[2].toInt(), data.data(), data.size()))
		outputs[0] = 1.;
	else outputs[0] = 0.;
	return true;
}


void BrickInterfaceBinFileOut::started() {
	if (file.isOpened()) file.close();
	file.open(parameters[1].toString());
	if (!file.isOpened()) file.open(parameters[1].toString(), PIIODevice::ReadWrite);
	if (parameters[3].toBool() > 0) file.clear();
	file.seekToEnd();
	id = parameters[2].toInt();
}


bool BrickInterfaceBinFileOut::tick_body(double time) {
	BrickInterfaceBaseOut::tick_body(time);
	///file.writeToBinLog(id, data.data(), struct_.size());
	if (parameters[4].toBool() > 0) file.flush();
	return true;
}

