/**
 * ActiveSite4 Common Form Methods
 * Requires use of the Protype framework
 *
 * @author Chris Blunt
 */
var AS4FormMethods = {
	/**
	 * Toggles a group of checkboxes between select all/none. The selection will match the toggled
	 * status of the sender.
	 *
	 * @param {Element} sender The Element that triggered the event
	 * @param {Element} form Prototype-extended Form
	 * @param {String} [className] The class of checkbox inputs that will be toggled. Default is 'include_in_select_all'
	 * @param {Boolean} [newState] If set, this new state will be used rather than a toggle.
	 */
	toggleCheckboxes: function(sender, form, className, newState)
	{
		if(!form)
			return;
			
		var className = (className == null ? 'include_in_select_all' : className);
		
		var elements = $(form).select('input.' + className);
		elements.each(function(item)
		{
			if(typeof(newState) != 'undefined')
				item.checked = newState;
			else
				item.checked = $(sender).checked;
		});
	},
	
	/**
	 * Takes all the input and text area elements of a form and returns them as JSON
	 * 
	 * @param {Element} formId Form element to serialise 
	 * @return {string}
	 */
	serializeJSON: function(formId)
	{
		formId = $(formId);
		
		var formElements = $A();
		var idArray = $A();
		var valueArray = $A();
						
		$(formId).select('input').each(function(formInputElements) 
		{
			
			switch(formInputElements.type)
			{
				case "radio":
					if(formInputElements.checked)
					{
						var id = formInputElements.id;
						var value = formInputElements.value;	
						idArray.push(id);
						valueArray.push(value);
					}
					break;
				
				case "checkbox":
					var id = formInputElements.id;
					var value = formInputElements.value;	
					var className = formInputElements.className;
					if(!className)
					{
					
						idArray.push(id);
						valueArray.push(formInputElements.checked ? 'true' : 'false');
					}
					break;
					
				default:						
					var id = formInputElements.id;
					var value = formInputElements.value;	
					idArray.push(id);
					valueArray.push(value);						
			}
		});
		
		$(formId).select('select').each(function(formInputElements) 
		{
			var id = formInputElements.id;
			var value = formInputElements.value;	
			idArray.push(id);
			valueArray.push(value);
		});
		
		// Serialise any textareas in the form
		$(formId).select('textarea').each(function(formTextElements){
			var id = formTextElements.id;
			var value = formTextElements.value;
			idArray.push(id);
			valueArray.push(value);
		});
		
	
		
		
		
		formElements.push(idArray);
		formElements.push(valueArray);
		return formElements.toJSON();
	},	
	
	/**
	 * Takes all the input and text area elements of a form and returns them as JSON
	 * 
	 * @param {Element} formId Form element to serialise 
	 * @return {string}
	 */
	serializeJSONwithSelect: function(formId)
	{
		formId = $(formId);
		
		var formElements = $A();
		var idArray = $A();
		var valueArray = $A();
						
		$(formId).select('input').each(function(formInputElements) {
			
			switch(formInputElements.type)
			{
				case "radio":
					if(formInputElements.checked)
					{
						var id = formInputElements.id;
						var value = formInputElements.value;	
						idArray.push(id);
						valueArray.push(value);
					}
					break;
				
				case "checkbox":
					var id = formInputElements.id;
					var value = formInputElements.value;	
					idArray.push(id);
					valueArray.push(formInputElements.checked ? 'true' : 'false');
					break;
					
				default:						
					var id = formInputElements.id;
					var value = formInputElements.value;	
					idArray.push(id);
					valueArray.push(value);						
			}
		});
		
		// Serialise any textareas in the form
		$(formId).select('textarea').each(function(formTextElements){
			
			var id = formTextElements.id;
			var value = formTextElements.value;
			idArray.push(id);
			valueArray.push(value);
		});
		
		// Serialise any select boxes in the form
		$(formId).select('select').each(function(formSelectElements){
			var id = formSelectElements.id;
			var value = formSelectElements.value;
			idArray.push(id);
			valueArray.push(value);
		});
		
		
		
		formElements.push(idArray);
		formElements.push(valueArray);
		return formElements.toJSON();
	},	
	
	/**
	 * Pops up a confirm requester with the given message and returns the result 
	 * 
	 * @param {string} message The message to display
	 * @param {string} url The url to forward to if the user confirms the action
	 */
	confirmLink: function(message, url)
	{
		if(!confirm(message))
			return;

		AS4Shell.getInstance().redirect(url);
	},
	
	// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
	
	/**
	 * Submits the given form
	 *
	 * @param {Element} sender The element that triggered the event
	 * @param {Element} form Prototype-extended form to submit
	 */
	submitForm: function(sender, form)
	{
		return $(form).submit();
	},

	//  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
	
	/**
	 * Confirm that a form should be submitted before submitting it
	 *
	 * @param {Element} sender The element that triggered the event
	 * @param {Element} form Prototype-extended form to submit
	 * @param {String} [message] Optional message to display to the user. Defaults to 'Are you sure you want to continue?'
	 */
	confirmSubmitForm: function(sender, form, message)
	{
		var message = (message ? message : 'Are you sure you want to continue?')

		if(!confirm(message))
			return;

		AS4FormMethods.submitForm(sender, form);
	},

	//  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

	/**
	 * Updates an array of elements with placeholder values if they are text inputs. The placeholder
	 * is read from a 'placeholder' attribute
	 * 
	 * @param Object sender The caller
	 * @param Array elements Array of elements to which placeholders will be applied  
	 */
	applyPlaceholders: function(sender, elements)
	{
		elements.each(function(element){
			element = $(element);
			if(!element.readAttribute('type') == 'text' || !element.readAttribute('placeholder'))
				return;
			
			element.value = element.readAttribute('placeholder');
			element.addClassName('placeholder');
			
			element.observe('blur', function() {
				if(this.value.length < 1)
				{
					this.value = this.readAttribute('placeholder');
					element.addClassName('placeholder');
				}
				else
					element.removeClassName('placeholder');
			}.bind(element));
						
			element.observe('focus', function() {
				if(this.value == this.readAttribute('placeholder'))
				{
					this.value = '';
					element.removeClassName('placeholder');
				}
			}.bind(element));
		});
	}
	
};

// # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
// Prototype Extension Methods

/**
 * Returns the value of the selected radio button in the radio group, null if
 * none are selected, and false if the button group doesn't exist
 *
 * @param {radio Object} or {radio id} el
 * OR
 * @param {form Object} or {form id} el
 * @param {radio group name} radioGroup
 */
function $RF(el, radioGroup) 
{
		if(!$(el))
			return null;

    if($(el).type && $(el).type.toLowerCase() == 'radio') {
        var radioGroup = $(el).name;
        var el = $(el).form;
    } else if ($(el).tagName.toLowerCase() != 'form') {
        return false;
    }
 
    var checked = $(el).getInputs('radio', radioGroup).find(
        function(re) {return re.checked;}
    );
    return (checked) ? $F(checked) : null;
}

Element.addMethods({
	
	/**
	 * Binds the property of a given object to the given form element
	 * 
	 * @param {Object} object the object to bind to
	 * @param {String} property The property of object to bind
	 */
	 bindTo: function(element, object, property)
	 {
	 	element.binding = {
	 		object: object,
	 		property: property
	 	};
	 	
	 	element.observe('change', function() {
	 		window.eval(this.binding.object + '.' + this.binding.property + ' = ' + this.value);
	 	},null);
	 },
	 
	/**
	 * Sets the given element's selected option if the element is a radio group.
	 * 
	 * @param Element element
	 * @param string value The value to match 
	 */
	setChecked: function(element, value)
	{
		$$('#' + element.id).each(function(element) {
			if($(element).value == value)
				$(element).checked = true;
			else
				$(element).checked = false;
		});
	}
});


/**
 * Pads a string with the given character to match the given
 * length
 * 
 * @param {String} l Desired string length
 * @param {integer} s String to pad
 * @param {string} [t] Optional type of padding. 0 = Left, 1 = Right, 2 = Centre. Default is 0 
 */
String.prototype.pad = function(l, s, t) 
{
    return s || (s = " "), (l -= this.length) > 0 ? (s = new Array(Math.ceil(l / s.length)
        + 1).join(s)).substr(0, t = !t ? l : t == 1 ? 0 : Math.ceil(l / 2))
        + this + s.substr(0, l - t) : this;
};
