#include "tcl_var.h"

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

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

char* TclVar::catchVar(ClientData clientData, Tcl_Interp* tcl,CONST84 char* name1, CONST84 char* name2, int flags)
{
	((TclVar*)clientData)->catchWrite(name1,name2);
	return 0;
}

void TclVar::catchWrite(const char* name1,const char* name2)
{
	if (!eventsEnabled) return;
	for(t_listeners::iterator it=listeners.begin();it!=listeners.end();it++)
	{
		(*it)->valueUpdated(this);
	}
}

TclVar::TclVar(Ptr<TclInterp>& interp)
{
	this->interp=interp;
	eventsEnabled=true;
	objName=Tcl_NewStringObj(guid.getId().c_str(),(int)guid.getId().length());
	Tcl_IncrRefCount(objName);
}

TclVar::~TclVar()
{
	if (listeners.size()!=0)
	{
		Tcl_UntraceVar(
			interp->getInterp(),
			guid.getId().c_str(),
			TCL_GLOBAL_ONLY|TCL_TRACE_WRITES,
			catchVar,
			(ClientData)this
		);
	}
	Tcl_DecrRefCount(objName);
}

const string& TclVar::toString() const
{
	return guid.getId();
}

void TclVar::addListener(TclVarListener* listener)
{
	if (listeners.size()==0)
	{
		Tcl_TraceVar(
			interp->getInterp(),
			guid.getId().c_str(),
			TCL_GLOBAL_ONLY|TCL_TRACE_WRITES,
			catchVar,
			(ClientData)this
		);
	}
	listeners.push_back(listener);
}

void TclVar::setEventsEnabled(bool value)
{
	eventsEnabled=value;
}

bool TclVar::isEventsEnabled() const
{
	return eventsEnabled;
}	
