#include "SH_runtime.h"


ScriptCache::ScriptCache() {
	root_ = 0;
	cmd_id_ = 0;
	obj_id_ = 0;
}


void ScriptCache::build(SHS::Object & o, const QString & root) {
	QMutableMapIterator<QString, SHS::Object> oit(o.objects);
	while (oit.hasNext()) {
		oit.next();
		oit.value().name = oit.key();
		root_ = &(oit.value());
		QStringList path;
		if (!root.isEmpty()) path << root;
		path << oit.key();
		buildInternal(oit.value(), path);
	}
}


void ScriptCache::clear() {
	command_by_id.clear();
	object_by_id.clear();
	commands_in.clear();
	root_ = 0;
	cmd_id_ = 0;
	obj_id_ = 0;
}


void ScriptCache::buildInternal(SHS::Object & o, QStringList path) {
	o.binded_properties.clear();
	o.id = ++obj_id_;
	object_by_id[o.id] = &o;
	QMutableMapIterator<QString, SHS::Command> it(o.commands);
	while (it.hasNext()) {
		it.next();
		SHS::Command & cmd(it.value());
		cmd.id = ++cmd_id_;
		cmd.name = it.key();
		cmd.object_path = path;
		if (!cmd.binded_property.isEmpty()) {
			if (cmd.user_arguments.size() == 1) {
				o.binded_properties[cmd.binded_property] = &cmd;
			} else {
				piCout << "[ScriptCache] Warning: ignore binded property for command" << Q2PIString(cmd.name);
			}
		}
		command_by_id[cmd.id] = &cmd;
		if (cmd.flags.testFlag(SHS::Input))
			piForeachC (PIString & p, cmd.devices)
				commands_in[PI2QString(p)] << &cmd;
	}
	QMutableMapIterator<QString, SHS::Object> oit(o.objects);
	while (oit.hasNext()) {
		oit.next();
		oit.value().object_path = path;
		oit.value().name = oit.key();
		buildInternal(oit.value(), QStringList(path) << oit.key());
	}
}




SHRuntime::SHRuntime() {
	engine_ = 0;
	shs_engine_ = 0;
}


SHRuntime::~SHRuntime() {

}


SHRuntime * SHRuntime::instance() {
	static SHRuntime ret;
	return &ret;
}


void SHRuntime::setServerData(const SHS::ServerData & d) {
	server_data = d;
	plugins_props_project = d.plugins;
}


void SHRuntime::openFromCmdFile() {
	QPIConfig conf("_ui_config_", QIODevice::ReadOnly);
	//QMessageBox::information(0, "", tr("dat = %1\nvar = %2").arg(conf.getValue("dat").toString(), conf.getValue("var").toString()));
	QString p = conf.getValue("dat").toString();
	if (!p.isEmpty()) setServerData(loadFromFile<SHS::ServerData>(p));
	p = conf.getValue("var").toString();
	if (!p.isEmpty()) variables = loadFromFile<typeof(variables)>(p, SHS::ScriptVariable::Version);
	cache.clear();
	cache.build(server_data.blocks);
}
