#include <algorithm>
#include "imodule.h"
#include "moduletype.h"
#include "modulemanager.h"
#include "../exceptions/exceptions.h"

Ptr<ModuleType> ModuleType::nullRef;

const char* ModuleType::type="ModuleType";

const char* ModuleType::getType() const
{
	return type;
}

void ModuleType::registerModule(IModule* module,const string& instanceName)
{
	if (!manager->getModule(instanceName).isNull()) throw new Exception(type,"Module instance with name '%s' already exists !",instanceName.c_str());
	module->registerModule(this,instanceName);
	this->instances.push_back(module);
}

VarDef* ModuleType::getVariable(const string& name)
{
	Ptr<VarDef>* vars=getVariables();
	int i=0;
	while(!vars[i].isNull())
	{
		if (name==vars[i]->getName()) return (VarDef*)vars[i];
		i++;
	}

	return 0;
}

Command* ModuleType::getCommand(const string& cmdName)
{
	Ptr<Command>* cmds=getCommands();
	int i=0;
	while(!cmds[i].isNull())
	{
		if (cmdName==cmds[i]->getName()) return (Command*)cmds[i];
		i++;
	}

	return 0;
}

Ptr<IModule>& ModuleType::getModule(const string& instanceName)
{	
	for(t_instances::iterator it=instances.begin();it!=instances.end();it++)
	{
		if ((*it)->getName()==instanceName) return *it;
	}
	return *(new Ptr<IModule>());
}

Ptr<IModule>& ModuleType::operator[](const string& instanceName)
{
	return getModule(instanceName);
}

void ModuleType::sendToAll(TObject* mesg)
{
	for(t_instances::iterator it=instances.begin();it!=instances.end();it++)
	{
		(*it)->receiveMessage(mesg);
	}
}
