
/* 
 * Standard MCG Library for Web Projects
 * by Merrill Consulting Group, LLC (MCG)
 * http://www.merrillconsultinggroup.us
 *
 * @package    CORE LIBRARY
 * @subpackage javascript common to all web pages
 * @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.
 *
 */


var mcgCore = new function() {
	this.moduleId = "mcgCore";
	this.version = "1.0.0";
	this.versionDate = "23 May 2009";
	this.codeStatus = "stable";
	this.lastAuthor = "Ray Merrill";
	this.copyright = "Copyright 2009, Merrill Consulting Group, LLC";
	this.license = "Proprietary copyrights.  See your license agreement.";
}

mcgCore.doNothing = function() {
	// place holder only
	return true;
}

mcgCore.explicitTypeOf = function(testvar) {
  if (typeof(testvar) == "object") {
    if (testvar === null) return "null";
    if (testvar.constructor == (new Array).constructor) return "array";
    if (testvar.constructor == (new Date).constructor) return "date";
    if (testvar.constructor == (new RegExp).constructor) return "regular_expression";
    return "object";
  }
  return typeof(testvar);
}

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.fireEvent = function() {
	var docElement = arguments[0];
	if (typeof(docElement) != 'object') {
		if (typeof(docElement) == 'string') {
			if (!document.getElementById(docElement)) {
				alert("ERROR in [mcgCore.fireEvent]:  the document element id (string value passed ='" + docElement + "') cannot be located in the DOM.");
				return false;
			} else {
				// reassign docElement to be a reference to the element
				docElement = document.getElementById(docElement);
			}
		} else {
			alert("ERROR in [mcgCore.fireEvent]:  the document element id is not of type string or object.  You must pass either the reference to the element, or the element id as string.");
			return false;
		}
	}
	if (!docElement) {
		alert("ERROR in [mcgCore.fireEvent]:  the document element (reference to DOM object passed) does not appear to exist.");
		return false;
	}
	switch (arguments[1].toLowerCase()) {
		case 'onchange':
			//on IE
			if (docElement.fireEvent) {
				docElement.fireEvent('onchange');
			}
			//on Gecko based browsers
			if (document.createEvent) {
				var evt = document.createEvent('HTMLEvents');
				if (evt.initEvent) {
					evt.initEvent('change', true, true);
				}
				if (docElement.dispatchEvent) {
					docElement.dispatchEvent(evt);
				}
			}
			break;
		case 'onclick':
			//on IE
			if (docElement.fireEvent) {
				docElement.fireEvent('onclick');
			}
			//on Gecko based browsers
			if (document.createEvent) {
				var evt = document.createEvent('HTMLEvents');
				if (evt.initEvent) {
					evt.initEvent('click', true, true);
				}
				if (docElement.dispatchEvent) {
					docElement.dispatchEvent(evt);
				}
			}
			break;
		default:
			alert("ERROR in [mcgCore.fireEvent]:  event '"+arguments[1]+"' is not enabled for programmatic fire via javascript.");
			return false;
	}
	
	return true;
}


