
var Object = require ('./object');
var Value = require ('./value');

/**
 * A map container for many Sql.Object
 **/
module.exports = new Class
({
	Extends: Object
	,Tag: 'sql-batch'
	,Properties:
	{
		blocked:
		{
			type: Boolean
			,set: function (x)
			{
				this._blocked = x;
			}
			,get: function ()
			{
				return this._blocked;
			}
		}
	}

	,objects: {}
	,_blocked: false

	,loadXml: function (builder, node)
	{
		this.parent (builder, node);

		var childs = node.childNodes;
	
		for (var i = 0; i < childs.length; i++)
		if (childs[i].tagName && childs[i].tagName.toLowerCase () == 'item')
		{
			var object;
			var id = childs[i].getAttribute ('name');

			if (id)
			{
				if (object = builder.getById (childs[i].getAttribute ('param')))
					this.addParam (id, object);
				else if (object = builder.getById (childs[i].getAttribute ('object')))
					this.addObject (id, object);
			}
		}
	}
	
	,get: function (id)
	{
		if (this.objects[id])
			return this.objects[id];
			
		return null;
	}
	
	,add: function (id)
	{
		if (!this.objects[id])
			this.objects[id] = null;
	}
	
	,_addObject: function (id, object)
	{
		this.remove (id);
		this.objects[id] = object;
		object.on ('changed', this.emitChanged, this);
		this.emitChanged ();
	}

	,addObject: function (id, object)
	{
		this._addObject (id, object.ref ());
	}

	,addValue: function (id, value)
	{
		this._addObject (id,
			new Value ({value: value}));
	}
	
	,addValues: function (values)
	{
		for (var id in values)
			this.addValue (id, values[id]);
	}

	,addParam: function (id, param)
	{
		this._addObject (id,
			new Value ({param: param}));
	}
	
	,getValue: function (id)
	{
		var object = this.objects[id];
		
		if (object instanceof Value)
			return object.value;
			
		return null;
	}
	
	,addParams: function (params)
	{
		for (var id in params)
			this.addParam (id, params[id]);
	}
	
	,remove: function (id)
	{
		if (this.objects[id])
		{
			this._unrefObject (this.objects[id]);
			delete this.objects[id];
		}
	}

	,block: function ()
	{
		this._blocked = true;
	}

	,unblock: function ()
	{
		this._blocked = false;
	}
	
	,emitChanged: function ()
	{
		if (!this._blocked)
			this.signalEmit ('changed');
	}

	,changed: function ()
	{
		this.signalEmit ('changed');
	}

	,isReady: function ()
	{
		for (var id in this.objects)
		if (!(this.objects[id] && this.objects[id].isReady ()))
			return false;

		return true;
	}
	
	,_unrefObject: function (object)
	{
		if (object)
		{
			object.disconnect ('changed', this.emitChanged, this);
			object.unref ();
		}
	}
	
	,_destroy: function ()
	{
		for (var id in this.objects)
			this._unrefObject (this.objects[id]);

		this.parent ();
	}
});
