/*
 *
 * Copyright (c) 2006 Sam Collett (http://www.texotela.co.uk)
 * Licensed under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 * 
 *  5 December 2006
 *   Select option(s) by value with 'selectOptions'
 *   Based on code by Mathias Bank (http://www.mathias-bank.de)
 */
 
/*
 * Adds (single/multiple) options to a select box (or series of select boxes)
 *
 * @name     addOption
 * @author   Sam Collett (http://www.texotela.co.uk)
 * @example  $("#myselect").addOption("Value", "Text"); // add single value (will be selected)
 *           $("#myselect").addOption("Value 2", "Text 2", false); // add single value (won't be selected)
 *           $("#myselect").addOption({"foo":"bar","bar":"baz"}, false); // add multiple values, but don't select
 *
 */
jQuery.fn.addOption = function()
{
	if(arguments.length == 0) return this;
	// select option when added? default is true
	var selectOption = true;
	// multiple items
	var multiple = false;
	if(typeof arguments[0] == "object")
	{
		multiple = true;
		var items = arguments[0];
	}
	if(arguments.length >= 2)
	{
		if(typeof arguments[1] == "boolean") selectOption = arguments[1];
		else if(typeof arguments[2] == "boolean") selectOption = arguments[2];
		if(!multiple)
		{
			var value = arguments[0];
			var text = arguments[1];
		}
	}
	this.each(
		function()
		{
			if(this.nodeName.toLowerCase() != "select") return;
			if(multiple)
			{
				for(var v in items)
				{
					jQuery(this).addOption(v, items[v], selectOption);
				}
			}
			else
			{
				var option = document.createElement("option");
				option.value = value;
				option.text = text;
				this.options.add(option);
			}
			if(selectOption)
			{
				this.options[this.options.length-1].selected = true;
			}
		}
	)
	return this;
}

/*
 * Removes an option (by value or index) from a select box (or series of select boxes)
 *
 * @name     removeOption
 * @author   Sam Collett (http://www.texotela.co.uk)
 * @example  jQuery("#myselect").removeOption("Value"); // remove by value
 *           jQuery("#myselect").removeOption(0); // remove by index
 *
 */
jQuery.fn.removeOption = function()
{
	if(arguments.length == 0) return this;
	if(typeof arguments[0] == "string") var value = arguments[0];
	else if(typeof arguments[0] == "number") var index = arguments[0];
	else return this;
	this.each(
		function()
		{
			if(this.nodeName.toLowerCase() != "select") return;
			if(value)
			{
				var optionsLength = this.options.length;
				for(var i=optionsLength-1; i>=0; i--)
				{
					if(this.options[i].value == value)
					{
						this.options[i] = null;
					}
				}
			}
			else
			{
				this.remove(index);
			}
		}
	)
	return this;
}

/*
 * Sort options (ascending or descending) in a select box (or series of select boxes)
 *
 * @name     sortOptions
 * @author   Sam Collett (http://www.texotela.co.uk)
 * @param    ascending   Sort ascending (true/undefined), or descending (false)
 * @example  // ascending
 *           jQuery("#myselect").sortOptions(); // or jQuery("#myselect").sortOptions(true);
 *           // descending
 *           jQuery("#myselect").sortOptions(false);
 *
 */
jQuery.fn.sortOptions = function(ascending)
{
	this.each(
		function()
		{
			if(this.nodeName.toLowerCase() != "select") return;
			// default sort is ascending if parameter is undefined
			ascending = typeof ascending == "undefined" ? true : ascending;
			// get number of options
			var optionsLength = this.options.length;
			// create an array for sorting
			var sortArray = [];
			// loop through options, adding to sort array
			for(var i = 0; i<optionsLength; i++)
			{
				sortArray[i] =
				{
					value: this.options[i].value,
					text: this.options[i].text
				};
			}
			// sort items in array
			sortArray.sort(
				function(option1, option2)
				{
					// option text is made lowercase for case insensitive sorting
					option1text = option1.text.toLowerCase();
					option2text = option2.text.toLowerCase();
					// if options are the same, no sorting is needed
					if(option1text == option2text) return 0;
					if(ascending)
					{
						return option1text < option2text ? -1 : 1;
					}
					else
					{
						return option1text > option2text ? -1 : 1;
					}
				}
			);
			// change the options to match the sort array
			for(var i = 0; i<optionsLength; i++)
			{
				this.options[i].text = sortArray[i].text;
				this.options[i].value = sortArray[i].value;
			}
		}
	)
	return this;
}
/*
 * Selects an option by value
 *
 * @name     selectOptions
 * @author   Mathias Bank (http://www.mathias-bank.de), original function
 * @author   Sam Collett (http://www.texotela.co.uk), addition of regular expression matching
 * @param    value specifies, which options should be selected
 *           can be a string or regular expression
 * @example  jQuery("#myselect").selectOptions("val1"); // with the value 'val1'
 * @example  jQuery("#myselect").selectOptions(/^val/i); // with the value starting with 'val', case insensitive
 *
 */
jQuery.fn.selectOptions = function(value)
{
	var valueType = typeof value;
	// has to be a string or regular expression (object in IE, function in Firefox)
	if(valueType != "string" && valueType != "function" && valueType != "object") return this;
	this.each(
		function()
		{
			if(this.nodeName.toLowerCase() != "select") return this;
			
			// get number of options
			var optionsLength = this.options.length;
			
			for(var i = 0; i<optionsLength; i++)
			{
				if(value.constructor == RegExp)
				{
					if (this.options[i].value.match(value))
					{
						this.options[i].selected = true;
					}
				}
				else
				{
					if (this.options[i].value == value)
					{
						this.options[i].selected = true;
					}
				}
			}
		}
	)
	return this;
}

/*
 *
 * Copyright (c) 2006 Sam Collett (http://www.texotela.co.uk)
 * Licensed under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 * 
 */

 
/*
 * Toggle all checkboxes contained within a form
 *
 * @name     toggleCheckboxes
 * @param    filter   only toggle checkboxes matching this expression
 * @param    returnChecked   return checkboxes as jQuery object, default false
 * @author   Sam Collett (http://www.texotela.co.uk)
 * @example  $("#myform").toggleCheckboxes();
 * @example  $("#myform").toggleCheckboxes(".onlyme");
 * @example  $("#myform").toggleCheckboxes(":not(.notme)");
 * @example  $("#myform").toggleCheckboxes("*", true);
 *
 */
jQuery.fn.toggleCheckboxes = function(filter, returnChecked)
{
	filter = filter || "*";
	returnChecked = returnChecked || false;
	var returnWhat = jQuery([]);
	this.each(
		function()
		{
			var checked = jQuery("input[@type=checkbox]", this).filter(filter).each(
				function()
				{
					this.checked = !this.checked;
				}
			).filter(":checked");
			returnWhat = checked;
		}
	)
	if(!returnChecked)
	{
		returnWhat = this;
	}
	return returnWhat;
}

/*
 * Check all checkboxes contained within a form
 *
 * @name     checkCheckboxes
 * @param    filter   only check checkboxes matching this expression
 * @param    returnChecked   return checkboxes as jQuery object, default false
 * @author   Sam Collett (http://www.texotela.co.uk)
 * @example  $("#myform").checkCheckboxes();
 * @example  $("#myform").checkCheckboxes(".onlyme");
 * @example  $("#myform").checkCheckboxes(":not(.notme)");
 * @example  $("#myform").checkCheckboxes("*", true);
 *
 */
jQuery.fn.checkCheckboxes = function(filter, returnChecked)
{
	filter = filter || "*";
	returnChecked = returnChecked || false;
	var returnWhat = jQuery([]);
	this.each(
		function()
		{
			var checked = jQuery("input[@type=checkbox]", this).filter(filter).each(
				function()
				{
					this.checked = true;
				}
			).filter(":checked");
			returnWhat = checked;
		}
	)
	if(!returnChecked)
	{
		returnWhat = this;
	}
	return returnWhat;
}

/*
 * UnCheck all checkboxes contained within a form
 *
 * @name     unCheckCheckboxes
 * @param    filter   only check checkboxes matching this expression
 * @param    returnUnChecked   return unchecked checkboxes as jQuery object, default false
 * @author   Sam Collett (http://www.texotela.co.uk)
 * @example  $("#myform").unCheckCheckboxes();
 * @example  $("#myform").unCheckCheckboxes(".onlyme");
 * @example  $("#myform").unCheckCheckboxes(":not(.notme)");
 * @example  $("#myform").unCheckCheckboxes("*", true);
 *
 */
jQuery.fn.unCheckCheckboxes = function(filter, returnUnChecked)
{
	filter = filter || "*";
	returnUnChecked = returnUnChecked || false;
	var returnWhat = jQuery([]);
	this.each(
		function()
		{
			var unChecked = jQuery("input[@type=checkbox]", this).filter(filter).each(
				function()
				{
					this.checked = false;
				}
			).filter(":not(:checked)");
			returnWhat = unChecked;
		}
	)
	if(!returnUnChecked)
	{
		returnWhat = this;
	}
	return returnWhat;
}

/*
 * Makes checkboxes behave like a radio button group
 *   i.e. only one can be selected at a time
 *
 * @name     radioCheckboxGroup
 * @param    name  field name (leave blank to apply to all check boxes)
 * @param    filter  apply to checkboxes matching this expression
 * @author   Sam Collett (http://www.texotela.co.uk)
 * @example  $.radioCheckboxGroup("fieldname");
 * @example  $.radioCheckboxGroup("fieldname", ".myclass");
 * @example  $.radioCheckboxGroup("", ".myclass");
 *
 */
jQuery.radioCheckboxGroup = function(name, filter)
{
	filter = filter || "*";
	var expression = "input[@type=checkbox]";
	if(name)
	{
		expression += "[@name=" + name + "]"
	}
	var x = jQuery(expression).filter(filter);
	x.click(
		function()
		{
			// uncheck every other box with the same name
			x.not(this).each(
				function()
				{
					this.checked = false;
				}
			).end();
		}
	);
}

/*
 * radio check by ethan
 *
 */
jQuery.fn.Check = function(value, filter)
{
	filter = filter || "*";
	this.each(
		function()
		{
			if (this.value == value)
			{
				this.checked = true;
			}
		}
	)
}
