/********************************/
//	Dynamic Dependant Project
//	Forms Stuff
//	Requires the foundation code
/********************************/


var ddp;
if(!ddp) ddp = {};
ddp.forms = {};

/********************************/
//	DDP -> Forms
/********************************/
(function() {


/***************************************************************/
//getRadioValue
//gets the value of a radio group by it's name
//arguments:
//strNameOrRef  - string or element reference   - the name of a radio group or one of the elements in the group
//elContainer   - element reference *optional*  - an element to confine the search to
//returns the value of the selected radio button or null if there are none selected
function getRadioValue(strNameOrRef, elContainer){
  //if a container was specified, only look within it, otherwise look at the whole document
  if(!elContainer)
    elContainer = document;
  //if the arg was an element, use it's "name" property, otherwise just use the arg value
  var strRadioName = (!ddp.f.isString(strNameOrRef) && typeof strNameOrRef == 'object') ? strNameOrRef.name : strNameOrRef;
  //get the elements with the supplied name within the container (or the whole document if the element doesn't support the getElementsByName method)
	var objInputs = (elContainer.getElementsByName) ? elContainer.getElementsByName(strRadioName) : document.getElementsByName(strRadioName);
  //step through the elements and pick the first one that's checked
	for(var i=0, l=objInputs.length; i<l; i++)
    //if one of the elements is checked and it's within the container
    if(objInputs[i].checked && (elContainer == document || ddp.f.isChild(objInputs[i], elContainer)))
      //return it's value
      return objInputs[i].value;
  
  //if none were selected, return null
  return null;
}


function clearRadioGroup(strNameOrRef, elContainer){
  //if a container was specified, only look within it, otherwise look at the whole document
  if(!elContainer)
    elContainer = document;
  //if the arg was an element, use it's "name" property, otherwise just use the arg value
  var strRadioName = (!ddp.f.isString(strNameOrRef) && typeof strNameOrRef == 'object') ? strNameOrRef.name : strNameOrRef;
  //get the elements with the supplied name within the container (or the whole document if the element doesn't support the getElementsByName method)
	var objInputs = (elContainer.getElementsByName) ? elContainer.getElementsByName(strRadioName) : document.getElementsByName(strRadioName);
  //step through the elements and pick the first one that's checked
	for(var i=0, l=objInputs.length; i<l; i++)
    //if one of the elements is checked and it's within the container
    if(objInputs[i].checked != false)
      //clear the checked box
      objInputs[i].checked = false;
  
  //if none were selected, return null
  return;
}


/***************************************************************/

function generateFormString(formid)
{
	var t="";
	var theform = document.getElementById(formid);
	var AND = "";
	for(i=0;i<theform.elements.length;i++)
	{
		t += AND + theform.elements[i].name + "=" + theform.elements[i].value;
		AND="&";
	}
	return t;
}


/***************************************************************/
//accepts a form element and iterates through it's child elements looking for elements with a name and value property
//returns a string of name value pairs eg. "varname=varvalue&vartwo=vartwovalue" 
function parseForm(elForm, blnSkipBlankFields, blnReturnAnObject){

  //make sure we're dealing with an HTML element (probably a form but doesn't have to be)
  if(!elForm || !elForm.getElementsByTagName)
    throw new Error('ddp.forms.parseForm - Error: elForm is not an element.')
  
  //create an object to hold our properties
  var objReturn = {};
  //get all child elements of the form
  var arElements = elForm.getElementsByTagName('*');
  //iterate throught the elements
  for(var i=0, l=arElements.length; i<l; i++){
    //if the element has a name property which isn't blank and a value property AND we don't already have a return property by that name
    if(typeof arElements[i].name != 'undefined' && arElements[i].name != '' && typeof arElements[i].value != 'undefined'){
      
      //default to the element's value
      var elementValue = arElements[i].value;
      
      //if it's an <input> element and it has a "type" property
      if(arElements[i].tagName.toLowerCase() == 'input' && typeof arElements[i].type != 'undefined'){
        //if it's a radio element
        if(arElements[i].type.toLowerCase() == 'radio'){
          //get the radio group's return value (only radio's with the specified name that are within "elForm")
          elementValue = getRadioValue(arElements[i].name, elForm);
          if(elementValue === null) //if the function returned null
            elementValue = ''; //then set the value for the serialization to blank
        }
        else if(arElements[i].type.toLowerCase() == 'checkbox'){
          if(!arElements[i].checked)
            elementValue = '';
        }
        //if it's a file input,
        else if(arElements[i].type.toLowerCase() == 'file'){
          //then tell them not to do it this way...
          elementValue = '"' + arElements[i].name + '" - File inputs can\'t be serialized with ddp.forms.serializeObject. (try ddp.ajax.submitToForm)';
          try{ console.log(elementValue); }catch(e){}
        }
      }
      //if it's a multiple selection <select> input
      else if(arElements[i].tagName.toLowerCase() == 'select' && arElements[i].multiple){
        //get the <select>'s <option>s
        var arOptions = arElements[i].getElementsByTagName('option');
        //make the a new array for return values
        var arSelectedOptions = [];
        //go through the option elements
        for(var j=0, jl=arOptions.length; j<jl; j++){
          if(arOptions[j].selected) //and if they are selected
            arSelectedOptions.push(arOptions[j].value); //add them to the array
        }
            
        if(arSelectedOptions.length == 0) //if there were none selected
          elementValue = ''; //set the value to blank (so it can be not-included)
        else if(arSelectedOptions.length == 1) //if there was only one selected
          elementValue = arSelectedOptions[0]; //uncomplicate things and just make it a single string
        else //otherwise
          elementValue = arSelectedOptions; //just return the new array of values
      }
      
      //if we aren't skipping blank fields,
      if(!(blnSkipBlankFields == true && elementValue == '')){
        //if the property doesn't exist
        if(typeof objReturn[arElements[i].name] == 'undefined')
          //add this property to the object we're building
          objReturn[arElements[i].name] = elementValue;
        else if(ddp.f.isArray(objReturn[arElements[i].name])) //if the property is already an array
          //add this property to the object we're building
          objReturn[arElements[i].name].push(elementValue);
        else //the property exists already but it's not an array
          //make it an array, assign it's first element to be the old property value, and add the new value
          objReturn[arElements[i].name] = [objReturn[arElements[i].name], elementValue];
      }
    }
  }

  //serialize the object into a URI encoded string (only "hasOwnProperty" properties will be included)
  return (blnReturnAnObject == true) ? objReturn : ddp.a.serializeObject(objReturn, true);
}
      

/**************************************************/
//Export the public functions to a public namespace
/**************************************************/

//Exports go here
var ddpns = ddp.forms;
ddpns.getRadioValue = getRadioValue;
ddpns.clearRadioGroup = clearRadioGroup;
ddpns.generateFormString = generateFormString;
ddpns.parseForm = parseForm;
})();
