/**
@Name: sb.forms
@Description: Methods for Dealing with forms and input data
*/
sb.forms = {
	
	/**
	@Name: sb.forms.getInputsByName
	@Description: Returns all inputs by name
	@Param: String name The name of the input to find
	@Param: String form This optional argument is the ID e.g. #myForm of the form to search within
	@Return: Array An iterable array of 
	@Example:
	//returns a reference to all inputs named deleteMe
	myNodes  = sc.forms.getInputsByName('deleteMe');
	*/
	getInputsByName : function(name, form){
		var parent  = form || 'body';
		return $(parent, 'input').filter(function(v){return v.name==name;});
	},

	/**
	@Name: sb.forms.getRadioValue
	@Description: Returns the set value of a radio button collection, if nothing is found it returns ''
	@Param: String name The name of the radio button
	@Param: String form This optional argument is the ID e.g. #myForm of the form to search within
	@Return: String The value of the selected radio button with the name specified in the name argument
	@Example:
	//returns a reference to all inputs named deleteMe
	myNodes  = sb.forms.getInputsByName('deleteMe');
	*/
	getRadioValue : function(name, form){
		var val = '',inputs = sb.forms.getInputsByName(name, form);
		inputs.forEach(function(v,k,a){
			if(v.checked ===true){
				val = v.value;
			}
		});
		return val;
	},

	/**
	@Name: sb.forms.toggleChecked
	@Description: Checks every value with a particular name, great for select/deselect all checkboxes feature.  If the seconds parameter is set it sets the specified input to that state e.g. true or false, 1 or 0
	@Param: String name The name of the radio button
	@Param: Boolean checkedState  The optional paramter allows you to specify the state of the checkbox.
	@Return: String The value of the selected radio button with the name specified in the name argument
	@Example:
	//This would toggle the checked status of all inputs with the name email[]
	sb.forms.toggleChecked('email[]');
	
	//This would set the checked status of all inputs with the name email[] to checked, regarless of their previous state
	sb.forms.toggleChecked('email[]', 1);
	*/
	toggleChecked : function(name, checkedState){
	
		sb.forms.getInputsByName(name).forEach(function(v){
			if(typeof checkedState != 'undefined'){
				v.checked=checkedState;
			} else if(v.checked==1){
				v.checked=0;
			} else {
				v.checked=1;
			}
		});
	},
	
	/**
	@Name: sb.forms.serialize
	@Description: Returns all key values forms that are filled out in a form as a string of key value pairs e.g. first_name=paul&day=monday.  It  can handle all form input types including text, select, select-multiple, radio, checkbox
	@Param: String form The name of the form to serialize
	
	@Return: String The serialized form dat e.g.first_name=paul&day=monday
	@Example:
	<form method="post" action="index.php">
	<input type="text" name="first_name" value="paul" />
	<input type="text" name="last_name" value="visco" />
	</form>
	
	var data = sb.forms.serialize("#myForm");
	//data = first_name=paul&last_name=visco
	*/
	serialize : function(form) { 
		var dat=[],s,e=sb.toArray(sb.$(form).elements);
		e.forEach(function(v){
			var n=v.name,t=v.type;
			if(n && v.value){
				if(t=='select-one'){
					dat.push(n + "=" + encodeURIComponent(v.options[v.selectedIndex].value));
				} else if(t =="select-multiple"){
					for(s=0;s<v.options.length;s++){
						if(v.options[s].selected===true){
							dat.push(n + "=" + encodeURIComponent(v.options[s].value));	
						}
					}
				} else if(t == "checkbox" || t=="radio"){
					if(v.checked==1){dat.push(n + "=" + escape(v.value));}
				} else {
					dat.push(n + "=" + escape(v.value));
				}
			}
		});
		
		return dat.join('&');
	},
	
	/**
	@Name: sb.forms.getSelection
	@Description: Returns the text selection in a textarea or text input
	@Param: String field The id or a reference to the textarea or text input.  Can be an obj reference or a string such as '#myField'.
	
	@Return: Object An object with selection data properties as follows
	begin - the character position of the beginning of the selection
	end - the character position of the end of the selection
	caret - the character position of the caret
	before - a string representing all text before the selection
	selected - a string representing all text in the selection
	after - a string represenitng all text after the selection
	
	@Example:
	<textarea id="myTextArea">surebert toolkit rocks</textarea>
	
	s$('#myTextArea').event('mouseup', function(e){
		var sel = sb.forms.getSelection(this);
	});

	//if the string toolkit was selected by the user with the mouse and then they let go of the mouse button sel would be defined as this in the event handler above
	
	sel = {
		begin : 9,
		end : 16,
		caret : 9,
		before : 'surebert ',
		selected : 'toolkit',
		after : ' rocks'
	}
	*/
	getSelection : function(field){
		field = sb.$(field);
		var range,sel={},selectionEnd,selectionStart,stored_range;
		field.focus(); 
		
		if (document.selection) {
			range = document.selection.createRange();
			stored_range = range.duplicate();
			stored_range.moveToElementText( field );
			stored_range.setEndPoint( 'EndToEnd', range );
			selectionStart = stored_range.text.length - range.text.length;
			
			selectionEnd = selectionStart + range.text.length;
			sel.begin = selectionStart;
			sel.end = selectionEnd;
	
		} else if(typeof field.selectionStart !='undefined'){
	
			sel.begin = field.selectionStart;
			sel.end = field.selectionEnd;
		} 
	
		sel.caret = sel.begin;
		sel.before = field.value.substr(0, sel.begin);
		sel.selected = field.value.substr(sel.begin, (sel.end - sel.begin));
		sel.after = field.value.substr(sel.end, (field.value.length - sel.end));
		return sel;
	},
	
	/**
	@Name: sb.forms.addTags
	@Description: Add tags before and after the selection in a text area
	@Param: String field The id or a reference to the textarea or text input.  Can be an obj reference or a string such as '#myField'.
	@Param: String beginTag The tag to be added to the beginning of the user text selection
	@Param: String endtag The tag to be added to the end of the user text selection
	@Example:
		sb.forms.addTags('#myField', '[b]', '[/b]');
		//would change the text field by putting the begin and end tags around wha the user selected e.g. surebert toolkit rocks.  If toolkit was selected and this method was run, it would turn into surebert [b]toolkit[/b] rocks.
	*/
	addTags : function(field, beginTag, endTag){
		field = sb.$(field);
		var sel = sb.forms.getSelection(field); 
		var tagLength = beginTag.length +endTag.length;
		field.value = sel.before + beginTag + sel.selected + endTag + sel.after;
		window.setTimeout(function(){
			field.focus();
			sb.forms.moveCaret(field, sel.caret);
		}, 0);
	},
	
	/**
	@Name: sb.forms.setSelection
	@Description: Forces a selection of a certain substring in a text area
	@Param: String field The id or a reference to the textarea or text input.  Can be an obj reference or a string such as '#myField'.
	@Param: String start The start character position of the selection, character position starts at 0.
	@Param: String end The end position of the selection.
	@Example:
		sb.forms.setSelection('#myTextArea', 0, 5);
		//forces characters 0-5 to be selected in the form field specified
	*/
	setSelection : function(field, start, end) {
		var range;
		field = sb.$(field);
		if (field.setSelectionRange) {
			field.setSelectionRange(start, end);
		} else {
			range = field.createTextRange();
			range.collapse(true);
			range.moveStart("character", start);
			range.moveEnd("character", end - start);
			range.select();
		}
	},
	
	/**
	@Name: sb.forms.replaceSelection
	@Description: replaces a selection with another text string
	@Param: String field The id or a reference to the textarea or text input.  Can be an obj reference or a string such as '#myField'.
	@Param: String txt The new string which will replace the current selection

	@Example:
		sb.forms.replaceSelection('#myTextArea', 'newString');
		//replaces the current selection with the string 'newString' and moves the caret to the end of the newString string
	*/
	replaceSelection : function(field, txt){
		field = sb.$(field);
		var sel = sb.forms.getSelection(field);
		
		field.value = sel.before + txt + sel.after;	
		sb.forms.moveCaret(field, sel.end);
		field.focus();
	},
	
	/**
	@Name: sb.forms.insertAtCaret
	@Description: inserts a string into a textarea at the caret location
	@Param: String field The id or a reference to the textarea or text input.  Can be an obj reference or a string such as '#myField'.
	@Param: String txt The new string to insert

	@Example:
		sb.forms.insertAtCaret('#myTextArea', 'newString');
		//inserts the text in the textarea at the caret
	*/
	insertAtCaret : function(field, txt){
		field = sb.$(field);
		sb.forms.replaceSelection(field, txt);
	},
	
	/**
	@Name: sb.forms.moveCaret
	@Description: moves the caret (cursor location) within a textarea
	@Param: String field The id or a reference to the textarea or text input.  Can be an obj reference or a string such as '#myField'.
	@Param: Number pos The character position to move the mouse to, rememeber it starts at 0.

	@Example:
		sb.forms.moveCaret('#myTextArea', 6);
		//moves the caret to character position 6
	*/
	moveCaret : function(field, pos){
		var range;
		field = sb.$(field);
		if (field.setSelectionRange) {
			field.setSelectionRange(pos, pos);
		} else {
			range = field.createTextRange();
			range.collapse(true);
			range.moveStart("character", pos);
			range.moveEnd("character", pos - pos);
			range.select();
		}
		field.focus();
	},

	/**
	@Name: sb.forms.allowTabs
	@Description: Allows the user to use tabs in a textarea
	@Param: String textarea The id or a reference to the textarea which you want to allow tabs on.

	@Example:
		s$(''#myTextArea').event('keydown', sb.forms.allowTabs);
	*/
	allowTabs : function(e){
		var sel = sb.forms.getSelection(this), textarea = this, scrollTo;
	
		if(e.keyCode == 9){
		
				scrollTo = this.scrollTop;
				setTimeout(function(){
					textarea.value = sel.before + unescape('%09') + sel.after;	
					sb.forms.moveCaret(textarea, sel.end+1);
					textarea.focus();
				}, 0);
				setTimeout(function(){
					textarea.scrollTop =  scrollTo;
				}, 10);
		
			return false;
		}
	},
	
	extend : sb.objects.extend
};