window.onload = init;
var template;
var form;

function init() {
	//get the first form in the html document
	form = getForm();
	
	// if there was a form in the document, set up the handlers to deal
	// with it
	if (form) {
		setTemplateHandler();
		addRow();
	}
}

/*********************************************************/
/***********    Template Handler          ****************/
/*********************************************************/
function setTemplateHandler() {
	var addbuttons = getAddbuttons();
	if (addbuttons.length > 0) {
		var templateID = addbuttons[0].getAttribute("template");
		template = document.getElementById(templateID);
	
	
		// For knowing where the repeated rows should be saved,
		// we save the parent's id.
		// ensure that parent has a unique id
	   	if (!template.parentNode.id) {
	   		template.parentNode.id = templateID + "_parent";
		}
	    
		// if trying to insert repeated rows <tr> into a <table>,
		// redirect <tr> to be appended to a <tbody>
		var insertPt = document.getElementById(template.parentNode.id);
		if ( (template.tagName == "TR") && (insertPt.tagName == "TABLE") ) {
			var tbody = document.createElement("tbody");
			tbody.id = templateID + "_tbody";
			insertPt.insertBefore(tbody, template);
			template.setAttribute("insertInto", tbody.id);
		} else {
			template.setAttribute("insertInto", template.parentNode.id);    	
		}
	
		template.parentNode.removeChild(template);
		template.setAttribute("lastSibling", null);

		for (var i=0; i < addbuttons.length; i++) {
			addbuttons[i].onclick = addbuttonHandler;
		}
	} else {
		alert("Missing a button for adding rows");
	}
}

function getAddbuttons() {
    var allButtons = document.getElementsByTagName("input");
    var addbuttons = new Array();

    for (i=0; i<allButtons.length; i++) {
        if(allButtons.item(i).getAttribute("template")) {
            addbuttons[addbuttons.length]=allButtons[i];
			break;
        }
    }
    return addbuttons;
} //end getAddButtons

// returns the number of rows corresponding to this template
function addRow() {
    var copy = template.cloneNode(true);
    var inputs = getInputElements(copy);
    var removebutton = setupRemovebutton(copy.getElementsByTagName("input"));
    var index = template.getAttribute("noOfRows") ? template.getAttribute("noOfRows") : 0;

    copy.id += "_" + index;   
    removebutton.setAttribute("copyID", copy.id) ;
    insertAddbutton(removebutton); //insert an add button beside the remove button
    copy.setAttribute("index", index);
    copy.setAttribute("isClone", "true");
    
    // give each of the inputs an id based on the index
    for (i=0; i < inputs.length; i++) {
        inputs[i].id = inputs[i].name + "_" + template.id + "_" + index;
    }
 
    // insert the row  
    var insertionPt = document.getElementById(copy.getAttribute("insertInto"));
    
    //if last Sibling exists
    if (template.getAttribute("lastSiblingID") != null) {
        var lastSibling = document.getElementById(template.getAttribute("lastSiblingID"));
        //and if there is a none clone element after it
        if (lastSibling && lastSibling.nextSibling) {
            insertionPt.insertBefore(copy, lastSibling.nextSibling);
        } else {
            insertionPt.appendChild(copy);
        }
        //remove last Sibling's add button
		  deleteAddbutton(lastSibling);
    } else {
        insertionPt.appendChild(copy);
    }
    // increment the stored no. of Rows and set lastSiblingID    
    template.setAttribute("noOfRows", index + 1);
    template.setAttribute("lastSiblingID", copy.id);
    return (index + 1); // return no. of rows

} //end function addRow
function addbuttonHandler(evt) {
    if (!evt) var evt = window.event;
    var e;
    if(evt.target) e = evt.target; // W3C DOM/Netscape
	 else if(evt.srcElement) e = evt.srcElement; // IE

    addRow();
    return false;
}

// insert an addbutton next to the removebutton
function insertAddbutton(removebutton) {
	var parent = removebutton.parentNode;
	var addbuttons = getAddbuttons();
	if (addbuttons.length > 0) {
		var addbutton = addbuttons[0].cloneNode(true);
		addbutton.onclick = addbuttonHandler;
		parent.appendChild(addbutton);
	}
}

// assumes that the last input element is the add button
function deleteAddbutton(element) {
	var inputs = element.getElementsByTagName("input");
	if (inputs.length > 0) {
		var addbutton = inputs[inputs.length-1];
		addbutton.parentNode.removeChild(addbutton);
	}
}

function setupRemovebutton(buttonList) {
	var i;
    for (i=0; i < buttonList.length; i++) {
        if (buttonList.item(i).getAttribute("function") == "remove") {
            buttonList.item(i).onclick = removebuttonHandler;
				return buttonList.item(i);
        }
    }
    return null;
}

function removebuttonHandler(evt) {
    if (!evt) var evt = window.event;
    var e;
    if(evt.target) e = evt.target; // W3C DOM/Netscape
	else if(evt.srcElement) e = evt.srcElement; // IE

    // remove gaps in the index numbers when a row in the middle is removed
    var toBeRemoved = document.getElementById(e.getAttribute("copyID"));
    var lastSiblingID = template.getAttribute("lastSiblingID");
    var sibling = toBeRemoved.nextSibling;
    
    if (toBeRemoved.id == lastSiblingID) {
        // trying to remove the last sibling,
    	  if (toBeRemoved.previousSibling && (toBeRemoved.previousSibling.getAttribute("isClone") == "true")) {
    	  	  lastSiblingID = toBeRemoved.previousSibling.id;
    	  	  var rembutton = setupRemovebutton(document.getElementById(lastSiblingID).getElementsByTagName("input"));
        	  insertAddbutton(rembutton); //put addbutton on lastSibling;
        } else {
      	  lastSiblingID = null;
        }
        template.setAttribute("lastSiblingID", lastSiblingID);
        
    } else {
    	//removing someone from in between
        while (sibling && (sibling.getAttribute("isClone"))=="true" ){
            reduceIndexByOne(sibling);
            if (sibling.nextSibling == null || !sibling.nextSibling.getAttribute("isClone")) {
            	template.setAttribute("lastSiblingID", sibling.id);
            }
				sibling = sibling.nextSibling;
        }
    }
    
    toBeRemoved.parentNode.removeChild(toBeRemoved);
    var noOfRows = template.getAttribute("noOfRows");
    template.setAttribute("noOfRows", noOfRows-1);
	 return false;
}

function reduceIndexByOne(row) {
    var inputs = getInputElements(row);
    var removebutton = setupRemovebutton(row.getElementsByTagName("input"));
	 var index = row.getAttribute("index");

    var length = row.id.length;
    var templateID = row.id.slice(0, length-2);
    row.id = row.id.slice(0,length-1) + (index-1);

    removebutton.setAttribute("copyID", row.id);
    for (var i=0; i < inputs.length; i++) {
        length = inputs[i].id.length;
        inputs[i].id = inputs[i].id.slice(0, length-1) + (index-1);
    }
    row.setAttribute("index", index-1);
}

function getForm() {
	return document.forms[0];
}

function getFormValue(element) {
	var value;

	switch(element.type) {
		case 'hidden':
		case 'text':
		case 'textarea':
			value = element.value;
			break;
		case 'select-one':
			value = element.options.length > 0 ? element.options[element.selectedIndex].value : '';
			break;
	}

	return value;
}

function setFormValueByName(name, value) {
	var form = getForm();
	var element = form.elements.namedItem(name);

	return setFormValue(element, value);
}

function setFormValue(element, value) {
	switch(element.type) {
		case 'hidden':
		case 'text':
		case 'textarea':
			element.value = value;
			break;
		case 'select-one':
			for(var i = 0; i < element.options.length; i++) {
				if(element.options.item(i).value == value) {
					element.options.item(i).selected = true;
					if (element.getAttribute('dependant')) {
						var dependant = changeOptions(element);
					}
					break;
				}
			}
			break;
	}
}

function setFormValueById(elementID, value) {
	var form = getForm();
	var element = document.getElementById(elementID);
	if (element) {
		return setFormValue(element, value);
	}
	return null;
}

function isInputElement(element) {
	var rc = false;

	switch(element.type) {
		case 'text':
		case 'textarea':
		case 'hidden':
		case 'select-one':
			rc = true;
	}

	return rc;
}

function getFormInputElements(form) {
	var inputs = new Array();

	for (var i=0; i < form.elements.length; i++) {
		var e = form.elements.item(i);
		if (isInputElement(e)) {
			inputs[inputs.length] = e;
		}
	}
	return inputs;
}


function getInputElements (element) {
	var selects = element.getElementsByTagName("select");
	var inputs = element.getElementsByTagName("input");
	var allInputs = new Array();
	var j=0;
	for (var i=0; i<selects.length; i++) {
		allInputs[i] = selects.item(i);
		j++;
	}
	
	for (var i=0; i<inputs.length; i++) {
		if (isInputElement(inputs.item(i)) ) {
			allInputs[j]=inputs.item(i);
			j++;
		}
	}
	return allInputs;
}


var labels;

function getLabelFor(id) {
	if(!labels)
		getFormLabels();

	

	//alert(id + " -> " + labels[id]);
	return ( (labels[id])? labels[id] : document.getElementById(id).name);
}

function getFormLabels() {
	labels = new Object;

	var ls = document.getElementsByTagName('LABEL');
	for(var i = 0; i < ls.length; i++) {
		var l = ls.item(i);
		if(l.htmlFor) {
			//alert("Label for " + l.htmlFor + ": " + top.getXMLText(l));
			labels[l.htmlFor] = top.getXMLText(l);
		}
	}
}
