
/* 
 * Standard MCG Library for Web Projects
 * by Merrill Consulting Group, LLC (MCG)
 * http://www.merrillconsultinggroup.us
 *
 * @package    CORE LIBRARY
 * @subpackage javascript for DOM operations
 * @author     Merrill Consulting Group, LLC
 * @license    see License Agreement
 * @copyright  (C) 2009 Merrill Consulting Group, LLC
 *
 * THIS FILE IS SOURCE CODE AND YOU ARE NOT ALLOWED TO ALTER OR COPY it except as authorized within the License Agreement.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY OF ANY KIND; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the License Agreement for more details.
 *
 */


mcgCore.dom = new function(){
	this.init = true;
}

mcgCore.dom.findElementsBy = function(){
	// this function is an AND search ... the response will contain the array of all DOM elements that match ALL of the input arguments
	
	// [0] = starting element (default is "document")
	// [1] = tag name
	// [2] = id
	// then pairs of attributes:
	// [N] = attribute name, [N+1] = attribute value
	// example:  mcgCore.dom.findElementsBy(null,'div',null,'mcgCore_personId','123','mcgCore_isPersonRow','1');
	// example:  mcgCore.dom.findElementsBy(null,null,'OrderDisplay');
	// example:  mcgCore.dom.findElementsBy(document,'div',null,'mcgCore_personId','123','mcgCore_isPersonRow','1');
	// example:  mcgCore.dom.findElementsBy(document.getElementById('OrderPad'),'div',null,'mcgCore_personId','123','mcgCore_isPersonRow','1');
	
	// use a NULL attributeValue to return all elements with the attributeName, regardless of value
	
	// returns array of elements matching ALL arguments
	
	if (arguments.length < 3) {
		alert("ERROR:  mcgCore.dom.findElementsBy called with insufficient arguments");
		return false;
	}
	if ((arguments[1] == null) && (arguments[2] == null)) {
		alert("ERROR:  mcgCore.dom.findElementsBy called with both ID and TAG null");
		return false;
	}
	
	var startNode = arguments[0];
	if (startNode == null) {startNode = document;}
	
	var nodeTagName = arguments[1];
	var nodeId = arguments[2];
	
	// first get results based on TagName and Id
	if (nodeTagName == null) {
		// ok, after much testing and frustration, it appears that the getElementById function never returns an array matching answers
		// apparently javascript assumes that id is always 100% unique (which is how it should be) ... but that is true only if the person
		// writing the HTML did not duplicate the id
		
		// so, since mcgCore.dom.findElementsBy is always supposed to be an array of matching elements, this function has been rewritten to do so
		// even if starting from the getElementById function
		
		if (startNode.getElementById(nodeId)) {
			var searchCollection = new Array();
			searchCollection[0] = startNode.getElementById(nodeId);
		} else {
			var searchCollection = false;	
		}
		
	} else {
		var searchCollection = startNode.getElementsByTagName(nodeTagName);
		if ((nodeId != null) && (searchCollection)) {
			// this is modified due to the singular response function of getElementById, also getElementById will apparently only operate on document (not a collection of HTML object)
			// searchCollection = searchCollection.getElementById(nodeId);
			
			// SO, we must manually search the collection for id tags that match (ugh)
			var responseCollection = new Array();
			var responseCounter = 0;
			for (var j=0; j < searchCollection.length; j++) {
				if (searchCollection[j].getAttribute('id')) {
					if (searchCollection[j].getAttribute('id') == nodeId) {
						responseCollection[responseCounter] = searchCollection[j];
						responseCounter++;
					}
				}
			}
			// if the response collection is empty, then none of the contents of the searchCollection matched the attribute and attribute value
			if (responseCollection.length < 1) {
				//mcgCore.debug.showDialog('mcgCore.dom.findElementsBy is about to return FALSE','global');
				return false;
			} else {
				// now exclude the elements that didn't match, then set up to search for the next attribute
				searchCollection = responseCollection;
			}
		}
	}
	
	// now narrow the results, successively, by each of the attributes fed as arguments
	if ((arguments.length < 3) || (!searchCollection)) {
		if ((searchCollection) && (searchCollection.length < 1)) {
			return false;
		} else {
			return searchCollection;
		}
	} else {
		for (var i=3; i < (arguments.length); i=i+2) {
			//mcgCore.debug.showDialog('mcgCore.dom.findElementsBy:  about to reduce the result set by attribute - the search collection starts with ' + searchCollection.length,'global');
			var responseCollection = new Array();
			var responseCounter = 0;
			var attributeName = arguments[i];
			var attributeValue = arguments[i+1];
			if (attributeName == null) {
				alert("ERROR:  mcgCore.dom.findElementsBy called with attribute name set to null - argument[" + (i+2) + "]");
				return false;
			}
			for (var j=0; j < searchCollection.length; j++) {
				if (searchCollection[j].getAttribute(attributeName)) {
					if (attributeValue == null) {
						responseCollection[responseCounter] = searchCollection[j];
						responseCounter++;
					} else {
						if (searchCollection[j].getAttribute(attributeName) == attributeValue) {
							responseCollection[responseCounter] = searchCollection[j];
							responseCounter++;
						}
					}
				}
			}
			// if the response collection is empty, then none of the contents of the searchCollection matched the attribute and attribute value
			if (responseCollection.length < 1) {
				//mcgCore.debug.showDialog('mcgCore.dom.findElementsBy is about to return FALSE','global');
				return false;
			} else {
				// now exclude the elements that didn't match, then set up to search for the next attribute
				searchCollection = responseCollection;
			}
		}
		// we've searched the collection for all the attributes, whatever is left in the last response collection is our answer
		return responseCollection;
	}
}


mcgCore.dom.deleteElements = function() {
	if (arguments.length < 1) {
		alert("ERROR:  mcgCore.dom.deleteElements called with insufficient arguments");
		return false;
	}
	if (arguments[0] == null) {
	    return true;
	}
	if (typeof(arguments[0]) == 'string') {
	    var elementToDelete = document.getElementById(arguments[0]);
	} else {
	    var elementToDelete = arguments[0];
	}
	
	if (elementToDelete.length) {
		var parentElement = null;
		for (var i=0; i < elementToDelete.length; i++) {
			// the element may already have been deleted from a prior deletion (parent/child)
			if (elementToDelete[i]) {
				parentElement = elementToDelete[i].parentNode;
				parentElement.removeChild(elementToDelete[i]);
			}
		}
	} else {
		var parentElement = null;
		if (elementToDelete) {
			parentElement = elementToDelete.parentNode;
			parentElement.removeChild(elementToDelete);
		}
	}
	return true;
}

mcgCore.dom.createElement = function() {
	// this function creates an element using a single element or a collection of elements passed as the attachment point - [0] is used if a collection
	
	// [0] = DOM element to append new element to
	// [1] = tag name
	// [2] = content to include within the created element
	// then pairs of attributes:
	// [N] = attribute name, [N+1] = attribute value
	// example:  mcgCore.dom.createElement(elementToAppendTo,'div',htmlSnippet,'id','MyUniqueDomId','mcgCore_PersonId','1235','mcgCore_ProductId','1234.564 Juno');
	
	// returns the element that it created
	
	if (arguments.length < 3) {
		alert("ERROR:  mcgCore.dom.createElement called with insufficient arguments");
		return false;
	}
	if (arguments[0] == null) {
		alert("ERROR:  mcgCore.dom.createElement called without argument specifying which element to append it to");
		return false;
	}
	if (arguments[1] == null) {
		alert("ERROR:  mcgCore.dom.createElement called with NULL XHTML tag name (e.g., div, td, span, script).");
		return false;
	}
	if (!arguments[1]) {
		alert("ERROR:  mcgCore.dom.createElement called without valid element to append it to - the argument passed refers to an element that does not exist in the DOM");
		return false;
	}
	
	if (arguments[0]) {
		// create the element and attach the contents
		var elementToAppend = document.createElement(arguments[1]);
		elementToAppend.innerHTML = arguments[2];
		
		// now cycle through the attributes passed, attaching them to the DOM element we've created
		for (var i=3; i < (arguments.length); i=i+2) {
			elementToAppend.setAttribute(arguments[i],arguments[i+1]);
		}
		
		// now append the element we created to the element that was passed, if the element passed was a collection, we attach it to the first occurence [0]
		if (arguments[0].length) {
			var elementToAppendTo = arguments[0];
			elementToAppendTo[0].appendChild(elementToAppend);
			return elementToAppendTo[0];
		} else {
			var elementToAppendTo = arguments[0];
			elementToAppendTo.appendChild(elementToAppend);
			return elementToAppendTo;
		}
	} else {
		alert("ERROR:  mcgCore.dom.createElement called with reference to append to an element that does not exist");
		return false;
	}
}

mcgCore.dom.moveElements = function() {
	if (arguments.length < 2) {
		alert("ERROR:  mcgCore.dom.moveElements called with insufficient arguments");
		return false;
	}
	if (arguments[0] == null) {
		alert("ERROR:  mcgCore.dom.moveElements called without argument specifying which element to move to");
		return false;
	}
	if (!arguments[0]) {
		alert("ERROR:  mcgCore.dom.moveElements called without valid element to move it to - the argument passed refers to an element that does not exist in the DOM");
		return false;
	}
	if (arguments[0].length) {
		var tempElement = arguments[0];
		var elementToMoveTo = tempElement[0];
	} else {
		var elementToMoveTo = arguments[0];
	}
		
	if (arguments[1]) {
		if (arguments[1].length) {
			var elementCollectionToMove = arguments[1];
			for (var i=0; i < elementCollectionToMove.length; i++) {
				elementToMoveTo.appendChild(elementCollectionToMove[i]);
			}
			return elementCollectionToMove;
		} else {
			elementToMoveTo.appendChild(arguments[1]);
			return arguments[1];
		}
	} else {
		alert("ERROR:  no elements to move using mcgCore.dom.moveElements - the argument passed refers to element(s) that do not exist in the DOM");
		return false;
	}
}


