function addTextSection(sectionID) {
	addSection(SECT_TEXT, sectionID);
}

function addLinkSection(sectionID) {
	addSection(SECT_LINK, sectionID);
}

function addBulletedSection(sectionID) {
	addSection(SECT_BULLET, sectionID);
}

function addNumberedSection(sectionID) {
	addSection(SECT_NUMBER, sectionID);
}

function addImageSection(sectionID) {
	addSection(SECT_IMAGE, sectionID);
}

function addNumberedEditItem(sectionID) {
	addSection(SECT_LIST_EDIT_NUMBER, sectionID);
}

function addBulletedEditItem(sectionID) {
	addSection(SECT_LIST_EDIT_BULLET, sectionID);
}

function addSection(sectionTemplate, sectionID) {
	// Replace the sequence number and field repeat values with dummy values because
	// they will be updated in the resequencing functions   
	var newSection = sectionTemplate.format( "000", "000" );
	//alert( newSection ); 
	//alert( "Section ID: " + sectionID );
	var parentID;
	if ( sectionID.startsWith(ID_SECTION_BUTTONS) || sectionID.startsWith(ID_BTNS_INS)) {
		parentID = getParentFieldSetID(sectionID);
	} else {
		parentID = getParentListID(sectionID);
	}
	var elem = document.getElementById(parentID);
	/*
	if (elem == null) {
		alert( "Element from Section ID returned null");
	} else {
		alert( "Element from Section ID: " + elem.id );
	}
	*/
	var newElem = buildElement(newSection);
	if (elem.nextSibling == null) {
		elem.parentNode.appendChild( newElem );
	} else {
		elem.parentNode.insertBefore( newElem, elem.nextSibling );
	}
	resequenceSections();
}

function deleteSection(sectionID) {
	if ( getSectionCount() <= 1 ) {
		alert("Unable to delete this section, add other sections before trying to delete this one.");
	} else {
		if ( confirm( "Are you sure you want to delete this section?") ) {
			var parentID;
			if ( sectionID.startsWith(ID_SECTION_BUTTONS) || sectionID.startsWith(ID_BTNS_DEL)) {
				parentID = getParentFieldSetID(sectionID);
			} else {
				parentID = getParentListID(sectionID);
			}
			//alert ("Section ID: " + sectionID + ", Parent ID: " + parentID);
			var elem = document.getElementById(parentID);
			elem.parentNode.removeChild(elem);
			resequenceSections();
		}
	}
}

function getSectionCount() {
	var elem = document.getElementById(SECTION_EDIT_PARENT);
	// Return the number of child elements -1 because of the Title Section
	return elem.childNodes.length - 1;
}

function moveSectionUp(sectionID) {
	//alert ("moving section Up");
	var parentID;
	if ( sectionID.startsWith(ID_SECTION_BUTTONS) || sectionID.startsWith(ID_BTNS_UP)) {
		parentID = getParentFieldSetID(sectionID);
	} else {
		parentID = getParentListID(sectionID);
	}
		
	//alert( "Parent ID: " + parentID); 
	var elem = document.getElementById(parentID);
	//alert ("Element: " + elem.id + ", elem.previousSibling.id: " + elem.previousSibling.id + ", FORM_LIST_PREFIX: " + FORM_LIST_PREFIX + ", Starts With: " + elem.previousSibling.id.startsWith(FORM_LIST_PREFIX)); 
	if (elem.previousSibling.id.startsWith(FORM_FLDSET_PREFIX) || elem.previousSibling.id.startsWith(FORM_LIST_PREFIX)) {
		elem.parentNode.insertBefore(elem, elem.previousSibling);
		resequenceSections();
	} else {
		alert("Unable to move this section up.");
	}
}

function moveSectionDown(sectionID) {
	//alert ("moving section Down");
	var parentID;
	if ( sectionID.startsWith(ID_SECTION_BUTTONS) || sectionID.startsWith(ID_BTNS_DWN)) {
		parentID = getParentFieldSetID(sectionID);
	} else {
		parentID = getParentListID(sectionID);
	}
	var elem = document.getElementById(parentID);
	if (null == elem.nextSibling || (!elem.nextSibling.id.startsWith(FORM_LIST_PREFIX) && !elem.nextSibling.id.startsWith(FORM_FLDSET_PREFIX))) {
		alert("Unable to move this section down.");
	} else {
		elem.parentNode.insertBefore(elem, elem.nextSibling.nextSibling);
		resequenceSections();
	}
}

function resequenceSections() {
	var elem = document.getElementById(SECTION_EDIT_PARENT);
	var idList = "";
	var id = "";
	var sectionID = "";
	var sectionType = "";
	var sequenceNo = "";
	var fldRepeatNo = "";
	var childID = "";
	var newIDSuffix = "";
	
	// alert ("Child Nodes: " + elem.childNodes.length);
	for (i=0; i < elem.childNodes.length; i++) {
		if (elem.childNodes[i].id.startsWith( FORM_FLDSET_PREFIX )) {
			id = elem.childNodes[i].id
			// alert ("Parsing Field: " + id);
			idList += sectionID + "\n";
			sectionType = getSectionType( id, FORM_FLDSET_PREFIX );
			sectionID = getSectionID( id, FORM_FLDSET_PREFIX );
			sequenceNo = i;
			fldRepeatNo = getFieldRepeatNo( id, FORM_FLDSET_PREFIX );
			newIDSuffix = getIdSuffix(i, 0, sectionType, sectionID);
			
			idList += "Type: " + sectionType + ", ID: " + sectionID + ", SequenceNo: " + sequenceNo + ", Field Repeat No: " + fldRepeatNo + ",\n";
			// alert(idList);
			
			// if the node is an element node(1), check for the child edit buttons
			if (elem.childNodes[i].nodeType == 1) {
				var elemButtons = getChildElementByID (elem.childNodes[i], ID_SECTION_BUTTONS);
				// alert( "Buttons is Null: " + (elemButtons == null) );
				updateEditButtons( elemButtons, newIDSuffix );
			}
			
			// Update the ID of the child field ID if it is a Text Field or Text Area,
			// and we call resequenceListItems if it is a list
			if (sectionType == SECTION_TYPE_TEXT || sectionType == SECTION_TYPE_LINK || sectionType == SECTION_TYPE_IMAGE) {
			
				childID = FORM_FLD_PREFIX + id.substring( FORM_FLDSET_PREFIX.length );
				idList += "Child ID: " + childID + "\n";
				
				//alert( "Replacing Element ID: [" + childID + "] with: [" + FORM_FLD_PREFIX + newIDSuffix + "]");
				updateElementIDs(elem.childNodes[i], childID, FORM_FLD_PREFIX + newIDSuffix);

				if (sectionType == SECTION_TYPE_IMAGE) {
					updateElementIDs(elem.childNodes[i], childID, FORM_FLD_PREFIX + newIDSuffix);
					updateElementIDs(elem.childNodes[i], childID, FORM_FLD_PREFIX + newIDSuffix);
					
					//updateElementIDs(elem.childNodes[i], childID, ID_SECTION_IMAGE_DISP + FORM_FLD_PREFIX + newIDSuffix);
					//updateElementIDs(elem.childNodes[i], ID_SECTION_IMAGE + childID, ID_SECTION_IMAGE_ID + FORM_FLD_PREFIX + newIDSuffix);
				}
				//var childElem = getChildElementByID (elem.childNodes[i], childID);
				
				// update the id and name fields of the child text box or text area
				//childElem.attributes["id"].value = FORM_FLD_PREFIX + newIDSuffix;
				//childElem.attributes["name"].value = FORM_FLD_PREFIX + newIDSuffix;
				
			} else if ( sectionType == SECTION_TYPE_BULLETS || sectionType == SECTION_TYPE_NUMBERS ){
			
				idList += "Child is a list or an image\n";
				updateListItems(elem.childNodes[i], sequenceNo, sectionType, sectionID);
				
			} else {
				alert ("Unknown section type: " + sectionType); 
			}
			
			// Update the legend for the fieldset to have the section Title
			
			// finally update the section ID and Section Title
			//alert ( "About to set ID for element[" + i + "]: " + elem.childNodes[i].attributes["id"].value + " to: " + FORM_FLDSET_PREFIX + newIDSuffix ); 
			elem.childNodes[i].attributes["id"].value = FORM_FLDSET_PREFIX + newIDSuffix;
			updateSectionTitle(elem.childNodes[i], sequenceNo, sectionType)
			//alert ( "ID for element set to: " + elem.childNodes[i].attributes["id"].value );
		}
	}
	// alert(idList);
}

function updateElementIDs(elem, existingID, newID) {
	var childElem = getChildElementByID (elem, existingID);
	
	// update the id and name fields of the child text box or text area
	if (childElem != null) {
		childElem.attributes["id"].value = newID;
		childElem.attributes["name"].value = newID;
	}			
				
}

function updateSectionTitle(fieldsetElem, sequenceNo, sectionType) {
	var title = "";
	
	switch (sectionType) {
		case SECTION_TYPE_TEXT:
			title = SECTION_TITLE_PARAGRAPH;
			break;
		case SECTION_TYPE_IMAGE:
			title = SECTION_TITLE_IMAGE;
			break;
		case SECTION_TITLE_LINK:
			title = SECTION_TITLE_LINK;
			break;
		case SECTION_TYPE_BULLETS:
			title = SECTION_TITLE_BULLET;
			break;
		case SECTION_TYPE_NUMBERS:
			title = SECTION_TITLE_NUMBER;
			break;
		
		default:
			title = SECTION_TITLE_PARAGRAPH;
	}
	
	title = title.format( pad(sequenceNo, 3) );
	if ( fieldsetElem.firstChild.tagName.toLowerCase() == "legend" ) {
		var msg = "Found Legend: [" + fieldsetElem.firstChild.innerText; 
		fieldsetElem.firstChild.innerText = title;
		msg += "], Set value to: [" + title + "], Actual value is: [" + fieldsetElem.firstChild.innerText + "]";
		//alert( msg );
	}
}

function updateEditButtons(buttonsElement, newIDSuffix) {
	var aElements = buttonsElement.getElementsByTagName("A");
	var newID = "";
    var msg = "";
    
	for (k=0; k < aElements.length; k++) {
		newID = aElements[k].id;
		newID = newID.substring( 0, newID.indexOf("_") + 1 ) + newIDSuffix; 
		msg += "Current ID: " + aElements[k].id + ", New Suffix: " + newIDSuffix + ", New ID: " + newID;
		aElements[k].id = newID;
	}
	//alert(msg);
}

function updateListItems(listElement, sequenceNo, sectionType, sectionID) {
	var newIDSuffix = "";
	var currentID = "";
    var msg = "";
    var textElement;
    var fldID = "";
    
	for (l=0; l < listElement.childNodes.length; l++) {
		msg += "Comparing tagName: " + listElement.childNodes[l].tagName + ", to 'div'\n";
		if (listElement.childNodes[l].tagName.toLowerCase() == "div") {
			currentID = listElement.childNodes[l].id;
			if (currentID.startsWith( FORM_LIST_PREFIX )) {
				newIDSuffix = getIdSuffix(sequenceNo, l, sectionType, sectionID);
				fldID = FORM_FLD_PREFIX + currentID.substring( currentID.indexOf("_") + 1 );
				textElement = getChildElementByID (listElement.childNodes[l], fldID);
				if (textElement == null) {
					msg += "TextBox not found for ID: " + fldID + ".\n";
				} else {
					msg += "TextBox ID: " + textElement.attributes["id"].value + " found, changing id to: " + FORM_FLD_PREFIX + newIDSuffix + ".\n";
					textElement.attributes["id"].value = FORM_FLD_PREFIX + newIDSuffix;
					textElement.attributes["name"].value = FORM_FLD_PREFIX + newIDSuffix;
				}
				
				// Update the edit buttons for each list item
				var elemButtons = getChildElementByID (listElement.childNodes[l], ID_SECTION_MINI_BTNS);
				// alert( "Buttons is Null: " + (elemButtons == null) + " for id: " + ID_SECTION_MINI_BTNS);
				updateEditButtons( elemButtons, newIDSuffix );
				
				// Change the List DIV element ID
				listElement.childNodes[l].attributes["id"].value = FORM_LIST_PREFIX + newIDSuffix;
				
			} else {
				msg += "Current ID: " + listElement.childNodes[l].id + " does not have the list prefix: " + FORM_LIST_PREFIX + ".\n";
			}
		} else {
			msg += "Current ID: " + listElement.childNodes[l].id + " is not a DIV.\n"; 
		}
	}
	//alert(msg);
}

function getSequenceNo(id, prefix) {
	var index = prefix.length;
	return id.substring( index, index + 3);
}

function getFieldRepeatNo(id, prefix) {
	var index = prefix.length + 4;
	return id.substring( index, index + 3);
}

function getSectionType(id, prefix) {
	var index = prefix.length + 8;
	return id.substring(index, index + 1); 
}

function getSectionID(id, prefix) {
	var index = prefix.length + 10;
	return id.substring(index); 
}

function getIdSuffix(sequenceNo, fieldRepeatID, sectionType, sectionID) {
	var result = ID_SUFFIX_TEMPLATE.format(pad(sequenceNo, 3), pad(fieldRepeatID, 3), sectionType, sectionID)
	//alert( ID_SUFFIX_TEMPLATE + " formatted to: " + result);
	return result;
}

function setNewElementID(parentElement, currentID, newID) {
	var elemChild = getChildElementByID (parentElement, currentID);
	elemChild.attributes["id"].value = newID;
}

function getChildElementByID (elem, id, duplicateItemIndex)
  {
  	var itemIndex = 0;
  	
  	if (duplicateItemIndex == undefined) {
  		duplicateItemIndex = 0;
  	}
  	
  	for (j = 0; j < elem.childNodes.length; j++) {
  		if (elem.childNodes[j].id == id) {
  			if (itemIndex == duplicateItemIndex) {
  				return elem.childNodes[j];
  			} else {
  				itemIndex++;
  			}
  		}
  	}
    return null;
  };

function getParentFieldSetID(id) {
	var parentID = FORM_FLDSET_PREFIX + id.substring( id.indexOf("_") + 1 );
	return parentID;
}

function getParentListID(id) {
	var parentID = FORM_LIST_PREFIX + id.substring( id.indexOf("_") + 1 );
	return parentID;
}

String.prototype.format = function(){
    var pattern = /\{\d+\}/g;    
    var args = arguments;    
    return this.replace(pattern, function(capture){ return args[capture.match(/\d+/)];});
};

String.prototype.trim = function(){
	return (this.replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, ""));
};

String.prototype.startsWith = function(str){
	return (this.match("^"+str)==str);
};

String.prototype.endsWith = function(str){
	return (this.match(str+"$")==str);
};

function pad(numNumber, numLength){
	var strString = '' + numNumber;
	while(strString.length<numLength){
		strString = '0' + strString;
	}
	return strString;
}

function buildElement(html) {
	var div = document.createElement("div");
	div.innerHTML = html;
	return div.firstChild; 
}
