#include "cdutils_interface.h"
#include "cdutils_core.h"
#include "piconfig.h"
#include "pifile.h"

using namespace CDUtils;


Interface::Interface(CDType::cdT type_) {
	core = CDCore::instance();
	s = core->root(type_);
	type = type_;
	//piCoutObj << (void*)this << core;
	file_ = core->typeLetter(type_) + PIStringAscii(".dat");
	file_size = 0;
	switch (type) {
	case CDType::cdK:
		CONNECTU(core, K_Sended, this, sended);
		CONNECTU(core, K_SendFail, this, sendFailed);
		CONNECTU(core, K_Received, this, received);
		CONNECTU(core, K_ReceiveFail, this, receiveFailed);
		CONNECTU(core, K_ChangedGlobal, this, changedGlobal);
		break;
	case CDType::cdX:
		CONNECTU(core, X_Sended, this, sended);
		CONNECTU(core, X_SendFail, this, sendFailed);
		CONNECTU(core, X_Received, this, received);
		CONNECTU(core, X_ReceiveFail, this, receiveFailed);
		CONNECTU(core, X_ChangedGlobal, this, changedGlobal);
		break;
	case CDType::cdC:
		CONNECTU(core, C_Sended, this, sended);
		CONNECTU(core, C_SendFail, this, sendFailed);
		CONNECTU(core, C_Received, this, received);
		CONNECTU(core, C_ReceiveFail, this, receiveFailed);
		CONNECTU(core, C_ChangedGlobal, this, changedGlobal);
		break;
	case CDType::cdM:
		CONNECTU(core, M_Sended, this, sended);
		CONNECTU(core, M_SendFail, this, sendFailed);
		CONNECTU(core, M_Received, this, received);
		CONNECTU(core, M_ReceiveFail, this, receiveFailed);
		CONNECTU(core, M_ChangedGlobal, this, changedGlobal);
		break;
	default: break;
	}
}


bool Interface::test(int v) {
	return s->test(v);
}


CDType & Interface::operator [](const PIString & name_) {
	return (*s)[name_];
}


const CDType Interface::operator [](const PIString & name_) const {
	return (*s)[name_];
}


CDType & Interface::operator [](const PIDeque<int> & path_) {
	return (*s)[path_];
}


const CDType Interface::operator [](const PIDeque<int> & path_) const {
	return (*s)[path_];
}


CDType & Interface::operator [](int v) {
	//piCout << (void*)this << "[]" << core;
	return (*s)[v];
}


const CDType Interface::operator [](int v) const {
	//piCout << (void*)this << "[]" << core;
	return (*s)[v];
}


CDSection & Interface::section(int v) {
//	CDSection & ret = s->section(v);
//	piCout << "[get section]" << v << ret.name;
	return s->section(v);
}


const CDSection Interface::section(int v) const {
	return s->section(v);
}


CDSection & Interface::section(const PIDeque<int> &path) {
	PIDeque<int> spath = path;
	CDSection * rs = s;
	while (!spath.isEmpty()) {
		rs = &(rs->section(spath.take_front()));
	}
	return *rs;
}


CDSection & Interface::root() {
	return *s;
}


const CDSection & Interface::root() const {
	return *s;
}


int Interface::count(bool recursive) const {
	return s->count(recursive);
}


bool Interface::exists(PIDeque<int> path) const {
	return s->exists(path);
}


void Interface::setFileName(const PIString & _file) {
	file_ = _file;
}


bool Interface::configure(const PIString & config) {
	PIConfig conf(config, PIIODevice::ReadOnly);
	PIConfig::Entry & e(conf.getValue(core->typeLetter(s->cd_type_)));
	bool ret = false;
	setFileName(e.getValue("file", file(), &ret));
	return ret;
}


void Interface::reinitConnection(const PIString & configuration) {
	core->init(configuration);
}


void Interface::releaseConnection() {
	core->release();
}


void Interface::write(PIIODevice * d) {
	core->cd_write(s, d);
}


void Interface::read(PIIODevice * d) {
	core->cd_read(s, d);
}


void Interface::parse(PIIODevice * d) {
	core->cd_parse(s, d);
}


void Interface::update(PIIODevice * d, UpdateModeFlags mode) {
	core->cd_update(s, d, mode);
}


void Interface::calculate() {
	core->cd_calculate(s);
}


PIString Interface::appConfig() {
	return core->appConfig();
}


PIString Interface::pultConfig() {
	return core->pultConfig();
}


void Interface::readFile() {
	if (file_.isEmpty()) return;
	PIFile f(file_, PIIODevice::ReadOnly);
	read(&f);
	file_size = f.size();
}


void Interface::writeFile() {
	if (file_.isEmpty()) return;
	PIFile f(file_, PIIODevice::ReadWrite);
	f.clear();
	write(&f);
	file_size = f.size();
}


bool Interface::inProgress() {
	return core->inProgress();
}


void Interface::send() {
	core->send(type);
}


void Interface::request() {
	core->request(type);
}
