
var SelectAllCheckBoxEx = 
{
	// enum
	ItemsTypeCheckBoxes: 0,
	ItemsTypeListOptions: 1,
	
	// container
	container: new Object(),

	// functions
	Register: function(itemsType, containerId, selectorId)
	{
		var container = document.getElementById(containerId);
		var containerKey = selectorId;
		var selector = document.getElementById(selectorId);
		var items = new Array();
		
		if(container == null || this.container[containerKey] != null)
		{
			return;
		}
		
		switch(itemsType)
		{
			case this.ItemsTypeCheckBoxes:
				this.RegisterForCheckBoxesItems(container, containerKey, selector, items);
				break;
				
			case this.ItemsTypeListOptions:
				this.RegisterForListOptionsItems(container, containerKey, selector, items);
				break;
			
			default:
				alert("SelectAllCheckBoxEx.Register: items type not supported");
		}

		this.container[containerKey] = {};
		this.container[containerKey].selector = selector;
		this.container[containerKey].itemsType = itemsType;
		this.container[containerKey].items = items;
		
		// update selector state
		switch(itemsType)
		{
			case this.ItemsTypeCheckBoxes:
				this.UpdateStateForCheckBoxesItems(containerKey);
				break;
				
			case this.ItemsTypeListOptions:
				this.UpdateStateForListOptionsItems(containerKey);
				break;
		}
	},
	
	RegisterForCheckBoxesItems: function(container, containerKey, selector, items)
	{
		var inputs = container.getElementsByTagName('INPUT');
			
		// get items
		for(var i = 0; i < inputs.length; i++)
		{
			if (inputs[i].type.toUpperCase() == 'CHECKBOX')
			{
				// add event
				inputs[i].onclick = function() { SelectAllCheckBoxEx.UpdateStateForCheckBoxesItems(containerKey); }

				// add to items
				items.push(inputs[i]);
			}
		}
		
		// set selector event
		selector.onclick = function() { SelectAllCheckBoxEx.SelectCheckBoxes(containerKey); }
	},
	
	RegisterForListOptionsItems: function(container, containerKey, selector, items)
	{
		var i;
		
		// get items
		var selects = container.getElementsByTagName('SELECT');
		for(i = 0; i < selects.length; i++)
		{
			items.push(selects[i]);
		}
	
		// container might be a select control itself
		if(container.tagName == 'SELECT')
		{
			items.push(container);
		}

		// set events to items
		for(i = 0; i < items.length; i++)
		{
			// add event
			items[i].onchange = function() { SelectAllCheckBoxEx.UpdateStateForListOptionsItems(containerKey); }
		}
		
		// set selector event
		selector.onclick = function() { SelectAllCheckBoxEx.SelectListOptions(containerKey); }
	},
	
	UpdateStateForCheckBoxesItems: function(containerKey)
	{
		var items = this.container[containerKey].items;
		this.container[containerKey].selector.checked = this.AreAllCheckBoxesSelected(items);
	},
	
	UpdateStateForListOptionsItems: function(containerKey)
	{
		var items = this.container[containerKey].items;
		this.container[containerKey].selector.checked = this.AreAllListOptionsSelected(items);
	},

	SelectCheckBoxes: function(containerKey)
	{
		var items = this.container[containerKey].items;
		var select = this.container[containerKey].selector.checked;

		for(var i = 0; i < items.length; i++)
		{
			items[i].checked = select;
		}
	},
	
	SelectListOptions: function(containerKey)
	{
		var items = this.container[containerKey].items;
		var select = this.container[containerKey].selector.checked;
		var options, i, o;

		for(i = 0; i < items.length; i++)
		{
			options = items[i].options;

			for(o = 0; o < options.length; o++)
			{
				options[o].selected = select;
			}
		}
	},
	
	AreAllCheckBoxesSelected: function(items)
	{
		for(var i = 0; i < items.length; i++)
		{
			if(!items[i].checked)
			{
				return false;
			}
		}

		return true;
	},
	
	AreAllListOptionsSelected: function(items)
	{
		for(i = 0; i < items.length; i++)
		{
			options = items[i].options;

			for(o = 0; o < options.length; o++)
			{
				if(!options[o].selected)
				{
					return false;
				}
			}
		}

		return true;
	}
};
