//function to get an element by its id - easier to type for w3, cross browser compatible
function getEl(id)
{
	var el;

	if (document.getElementById) {
		//first clause is for w3c specifications
		el = document.getElementById(id);
	} else if (document.all) {
		//this clause is for early version MSIE browsers
		el = document.all[id];
	} else if (document.layers) {
		//this clause is for early netscape browsers
		el = document.layers[id];
	}
	
	//return the correct DOM form of the object
	return el;
}

//-------------------------------------------get position functions---------------------------------------------//

//the following four functions were modified from source code from www.aspandjavascript.co.uk
//returns the current value in px for left, top, height, width, bottom and right of an element with id 'elem' or can be passed an object

function getElementLeft(elem)
{
	if (elem.nodeType != 1) {
		elem = getEl(elem);
	}
	
	var xPos = elem.offsetLeft;
	var tempEl = elem.offsetParent;
	 
	while (tempEl != null) {
		xPos += tempEl.offsetLeft;
		tempEl = tempEl.offsetParent;
	}
	
	return xPos;
}

function getElementTop(elem)
{
	if (elem.nodeType != 1) {
		elem = getEl(elem);
	}
	
	var yPos = elem.offsetTop;
	var tempEl = elem.offsetParent;
	
	while (tempEl != null) {
		yPos += tempEl.offsetTop;
		tempEl = tempEl.offsetParent;
	}
	
	return yPos;
}

function getElementHeight(elem)
{
	if (elem.nodeType != 1) {
		elem = getEl(elem);
	}
	
	return elem.offsetHeight;
}

function getElementWidth(elem)
{
	if (elem.nodeType != 1) {
		elem = getEl(elem);
	}
	
	return elem.offsetWidth;
}

function getElementBottom(elem)
{
	return getElementTop(elem) + getElementHeight(elem);
}

function getElementRight(elem)
{
	return getElementLeft(elem) + getElementWidth(elem);
}

//-----------------------------------xml handling functions------------------------------//

//function that takes a well formed xml text string and returns it as an xml dom object
//the string has to exist as a javascript var
function getXML(xml_str) 
{
	var xmldoc;
	if (window.ActiveXObject) {
		// code for IE
		xmldoc = new ActiveXObject("Microsoft.XMLDOM");
		xmldoc.async = "false";
		xmldoc.loadXML(xml_str);
	} else {
		//code for Mozilla, Firefox, Opera, etc.
		var parser = new DOMParser();
		xmldoc = parser.parseFromString(xml_str,"text/xml");
	}
	
	// documentElement always represents the root node
	return xmldoc.documentElement;
}

//parent function of the recursive function that puts some xml into an associative array
function xmlToArray(xmlObj)
{
	var array = new Array();
	
	//pass to recursive function
	xtaRecursive(xmlObj,array);
	
	//return the array
	return array;
}

//recursive function that takes a segment from the xml dom and loads it into an associative array
function xtaRecursive(xmlObj,array)
{
	//loop through each of the child nodes
	for (var i = 0; i < xmlObj.childNodes.length; i++) {
		//put into an associative array of tag names - if element has children, then call function recursively
		//this does not deal with tags with attributes
		var current = xmlObj.childNodes[i];
		
		if (current.childNodes.length == 1) {
			//if there is only one child, could be text or could be an element
			if (current.childNodes[0].nodeType == 3) {
				//if the type is text, put it in the array
				array[current.nodeName] = current.childNodes[0].nodeValue;
			} else if (current.childNodes[0].nodeType == 1) {
				//otherwise, if it is an element, call function recursively
				//this will put any text nodes as an element in the array, rather than just the value, but this shouldn't happen with my structure
				array[current.nodeName] = new Array();
				xtaRecursive(current,array[current.nodeName]);
			}
		} else if (current.childNodes.length > 1) {
			//if there is more than one child, then call function recursively
			array[current.nodeName] = new Array();
			xtaRecursive(current,array[current.nodeName]);
		} else {
			//if there is nothing in tag, save it as an empty string
			array[current.nodeName] = '';
		}
	}
	
	//return the array
	return array;
}

//-----------------------------------homepage specific functions------------------------------//

//function that takes an xml object and prints out the desired html for the calendar section on the homepage
function printHomeCal(xml_obj)
{
	//this assumes xml is in chronological order
	
	//takes an xmlhttp object as an argument and returns the root node then selects only the nodes of interest
	var xml = getResponse(xml_obj);
	xml = getChildrenByTagName(getResponse(xml_obj),'event');
	//stores the max no of events to display
	var maxno = 3;
	//stores the number of events that occured in the past
	var past = 0;
	//stores two dates, current and the event date
	var cur_date = new Date(), event_date = new Date();
	//store the current event in an array
	var event;
	//holds the html text string to be published
	var str = '';
	//builds each entry as it is processed
	var str_build;
	
	//get the starting and ending positions of the homecal based on how many events have occured in the past
	for (var i = 0; i < xml.length; i++)
	{
		//put current event into an xmlExtract object
		event = new xmlExtract(xml[i]);
		//set the event_date object
		var temp = event.get('date');
		event_date.setFullYear(temp.get('year').text,temp.get('month').text-1,temp.get('day').text);
		//set the end date to also compare
		var event_date_end = null;
		if (event.get('enddate').text != undefined) {
			var temp = event.get('enddate');
			event_date_end = new Date();
			event_date_end.setFullYear(temp.get('year').text,temp.get('month').text-1,temp.get('day').text);
		}
		//if multi day, use different condition
		if (event_date_end == undefined) {
			if (event_date < cur_date) past++;
		} else {
			if (event_date_end < cur_date) past++;
		}
		
	}
	
	//if file has less than max entries + past, then reset maxno
	if (maxno + past > xml.length) {
		maxno = xml.length - past;
	}
	
	//loop through necessary number of events, starting from the end
	for (var i = maxno + past - 1; i >= past; i--) {
		
		//put current event into an xmlExtract object
		event = new xmlExtract(xml[i]);
		
		//set the event_date object
		var temp = event.get('date');
		event_date.setFullYear(temp.get('year').text,temp.get('month').text-1,temp.get('day').text);
		str_build = '';
		
		//write string to publish event on homepage
		str_build = '<table class="homecal"><tr><th colspan="2" class="homecal homecalheading">';
		
		//if there is a link, add anchor around the title
		if (event.get('link')) {
			if (event.get('link').text) str_build +='<a href="' + event.get('link').text + '">' + event.get('title').text + '</a>';
			else str_build += event.get('title').text;
		} else {
			str_build += event.get('title').text;
		}
		str_build += '</th></tr><tr><th class="homecal">Date:</th><td class="homecal">' + day(event_date.getDay(),true) + ', ' + event_date.getDate() + ' ' +
		month(event_date.getMonth(),true) + '</td></tr><th class="homecal">';
		
		if (event.get('enddate')) {
			temp = event.get('enddate');
			event_date.setFullYear(temp.get('year').text,temp.get('month').text-1,temp.get('day').text);
			str_build += 'Until:</th><td class="homecal">' + day(event_date.getDay(),true) + ', ' + event_date.getDate() + ' ' + month(event_date.getMonth(),true);	
		} else {
			str_build += 'Time:</th><td class="homecal">' + event.get('time').get('start').text + ' - ' + 
			event.get('time').get('finish').text;
		}
		
		str_build += '</td></tr><tr><th class="homecal">Venue:</th><td class="homecal">' + event.get('venue').text + '</td></tr></table>';
		
		str = str_build + str;
	}
	
	//write the string to the document
	getEl('homecal').innerHTML = str;
}

//-----------------------------------date functions------------------------------//

//function to convert day number to actual day
function day(day_no,short_flag)
{
	var days_long = new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
	var days_short = new Array('Sun','Mon','Tues','Wed','Thu','Fri','Sat');
	
	if (short_flag == true) {
		return days_short[day_no];
	} else {
		return days_long[day_no];
	}
}

//function to convert month no to label
function month(month_no,short_flag)
{
	var months_long = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
	var months_short = new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
	
	if (short_flag == true) {
		return months_short[month_no];
	} else {
		return months_long[month_no];
	}
}

//function to produce an ordinal number suffix
function ordNoSuffix(number) 
{
	var suffix;
	
	switch (number)
	{
	case 1:
		suffix = 'st'; break;
	case 2:
		suffix = 'nd'; break;
	case 3:
		suffix = 'rd'; break;
	default:
		suffix = 'th';
	}
	
	return suffix;
}

//-----------------------------------all page functions and compatibility fixes------------------------------//

//-----------------------------------specific page functions------------------------------//

//function to print the events calendar
function printCal(xml_obj)
{
	//implement appropriate sort function by date.
	
	//takes an xmlhttp object as an argument and returns the root node then selects only the nodes of interest
	var xml = getResponse(xml_obj);
	xml = getChildrenByTagName(getResponse(xml_obj),'event');
	//store the current event in an array
	var event;
	//holds the html text string to be published
	var str = '';
	//holds a date object for the event
	var event_date = new Date();

	//for now, loop through all events - this may change to only those within a specifc date range. May also add a sorting mechanism
	//maybe also separate out into semesters
	for (var i = 0; i < xml.length; i++) {
	
		//put current event into an xmlExtract object
		event = new xmlExtract(xml[i]);
		
		//set the event_date object
		var temp = event.get('date');
		event_date.setFullYear(temp.get('year').text,temp.get('month').text-1,temp.get('day').text);
		
		//build section to present individual event in its own table
		str += '<table class="cal"><tr><td colspan="3" class="caltitle">';
		//if there is a link, then attach anchor to title
		
		if (event.get('link').text == undefined || event.get('link').text == '') {
			str += event.get('title').text; 
		} else {
			str +='<a href="' + event.get('link').text + '">' + event.get('title').text + '</a>';
		}
		str += '</td></tr>' +
			'<tr><td class="calhead">Date:</td>' + 
			'<td class="calprop">Week ' + temp.get('week').text + '<br />' + day(event_date.getDay(),false) + ', ' + event_date.getDate() + '<span class="super">' + ordNoSuffix(event_date.getDate()) + '</span> ' + month(event_date.getMonth(),false) + '</td>' +
			'<td rowspan="4" class="caldesc">';
		//if there is an entry in the speakers section, insert above description 
		if (event.get('speakers')) {
			str += 'Speaker: ' + event.get('speakers').text + '<br />';
		}
		str += event.get('description').text;
		//if there is a link, also put a read more link
		if (event.get('link')) {
			if (event.get('link').text) str += '<br /><a href="' + event.get('link').text + '">...read more</a>';
		}
		
		str += '</td></tr><tr><td class="calhead">';
		
		//multi-day events have a legal time stamp, but will not print out, because enddate will print instead
		if (event.get('enddate')) {
			temp = event.get('enddate');
		event_date.setFullYear(temp.get('year').text,temp.get('month').text-1,temp.get('day').text);
			str += 'Until:</td><td class="calprop">' + day(event_date.getDay(),false) + ', ' + event_date.getDate() + '<span class="super">' + ordNoSuffix(event_date.getDate()) + '</span> ' + month(event_date.getMonth(),false);
		} else {
			temp = event.get('time');
			str += 'Time:</td><td class="calprop">' + temp.get('start').text + ' - ' + temp.get('finish').text;
		}
		
		str += '</td></tr><tr><td class="calhead">Venue:</td>' +
			'<td class="calprop">' + event.get('venue').text + '</td></tr>' +
			'<tr><td class="calhead">Cost:</td>' +
			'<td class="calprop">' + event.get('cost').text + '</td></tr></table>';
	}
	
	//write the string to the document
	getEl('caldiv').innerHTML = str;
}

//function to print the executive details section
function printExec(xml_obj)
{
	//function that takes a well formed xml string and prints out the executive details page
	//implement sorting on this later
	
	//takes an xmlhttp object as an argument and returns the root node then selects only the nodes of interest
	var xml = getResponse(xml_obj);
	xml = getChildrenByTagName(getResponse(xml_obj),'exec');
	//store the current exec member in an array
	var exec;
	//holds the html text string to be published
	var str = '';
	//variable to hold the photo width in px - keep here for ease of change
	var photo_width = 150;
	
	//put the links in for show/hide all
	str += '<div class="allbox">' +
		'<a href="#" id="hide_all"><img src="/img/hide_all.gif" /></a>&nbsp;&nbsp;' +
		'<a href="#" id="show_all"><img src="/img/show_all.gif" /></a>' +
	'</div>';
	
	//loop through all exec members
	for (var i = 0; i < xml.length; i++) {
		
		//put current exec member into array
		exec = xmlToArray(xml[i]);
		
		//considering scraping the javascript xmlToArray and replacing it with a suite of xml dom functions...due to the two issues - text and tags in one element and two of same child
		var paras = xml[i].getElementsByTagName('para');
		
		//set the name to a variable
		var name = exec['name']['firstname'] + ' ' + exec['name']['surname'];
		//build table for exec member
		str += '<table class="exec" id="exec' + i + '"><tr>' +
			'<td colspan="2" class="exectitle"><span class="exectitle">' + name + ' - ' + exec['position'] + '</span>' + 
			'<span class="exectog"><a href="#" class="exectog" id="exectog' + i + '"><img src="/img/hide.gif"/></a></span></td></tr>' +
			'<tr class="hide"><td rowspan="' + (paras.length + 1) + '" class="execpic"><img class="execpic" src="/img/exec/' + exec['photo'] + '" alt="Photo: ' + name + '" width="' + photo_width + 'px" /></td>' +
			'<td class="execinfo">' + exec['course'] + '</td></tr>';
			//loop through each of the paragraphs
			for (var j = 0; j < paras.length; j++) {
				str += '<tr class="hide"><td class="execinfo"><strong>' + paras[j].getElementsByTagName('heading')[0].childNodes[0].nodeValue + 
					'</strong><br />' + paras[j].getElementsByTagName('body')[0].childNodes[0].nodeValue + '</td></tr>';
			}
		
		str += '</table>';
	}
	
	getEl('exectable').innerHTML = str;
	
	for (i = 0; i < xml.length; i++) {
		//toggle visibility function
		getEl('exectog' + i).onclick = function () {
			var par = findParent(this,2,'table','class','exec');
			var tog;
			if (this.innerHTML.indexOf('hide') != -1) {
				tog = 0;
				getChildrenByTagName(this,'img')[0].src = '/img/show.gif';
			} else {
				tog = 1;
				getChildrenByTagName(this,'img')[0].src = '/img/hide.gif';
			}
			toggleVisByTag(tog,'tr',par,0,'class','hide');
			return false;
		}
		
		//toggle image onmousedown function
		getEl('exectog' + i).onmousedown = function () {
			if (this.innerHTML.indexOf('hide') != -1) {
				//switch the image src from standard to pushed image.
				getChildrenByTagName(this,'img')[0].src = '/img/hide_on.gif';
			} else if (this.innerHTML.indexOf('show') != -1) {
				getChildrenByTagName(this,'img')[0].src = '/img/show_on.gif';
			}
		}
		
		//toggle image onmouseout function
		getEl('exectog' + i).onmouseout = function () {
			if (this.innerHTML.indexOf('hide') != -1) {
				//switch the visibility of the standard and the pushed button.
				getChildrenByTagName(this,'img')[0].src = '/img/hide.gif';
			} else if (this.innerHTML.indexOf('show') != -1) {
				getChildrenByTagName(this,'img')[0].src = '/img/show.gif';
			}
		}
	}
	
	//hide all event handlers
	getEl('hide_all').onclick = function () {
		toggleVisByTag(0,'tr','exectable',0,'class','hide');
		var list = getElementsByAtt('a','class','exectog',getEl('exectable'));
		for (var i = 0; i < list.length; i++) {
			list[i].innerHTML = '<img src="/img/show.gif" />';
		}
		return false;
	}
	
	getEl('hide_all').onmousedown = function () {
		getChildrenByTagName(this,'img')[0].src = '/img/hide_all_on.gif';
	}
	
	getEl('hide_all').onmouseout = function () {
		getChildrenByTagName(this,'img')[0].src = '/img/hide_all.gif';
	}
	
	getEl('hide_all').onmouseup = function () {
		getChildrenByTagName(this,'img')[0].src = '/img/hide_all.gif';
	}
	
	//show all event handlers
	getEl('show_all').onclick = function () {
		toggleVisByTag(1,'tr','exectable',0,'class','hide');
		var list = getElementsByAtt('a','class','exectog',getEl('exectable'));
		for (var i = 0; i < list.length; i++) {
			list[i].innerHTML = '<img src="/img/hide.gif" />';
		}
		return false;
	}
	
	getEl('show_all').onmousedown = function () {
		getChildrenByTagName(this,'img')[0].src = '/img/show_all_on.gif';
	}
	
	getEl('show_all').onmouseout = function () {
		getChildrenByTagName(this,'img')[0].src = '/img/show_all.gif';
	}
	
	getEl('show_all').onmouseup = function () {
		getChildrenByTagName(this,'img')[0].src = '/img/show_all.gif';
	}
}

//function that shows or hides all child elements  with a given tag name. has optional attribute-value pair for filtering
//input parent can be either an object or an id or empty, in which case assume body element 
//if display is omitted for non att-val only, == '' or == 0 or == 'default', then use default, which is a hardcoded function associating default displays with elements
function toggleVisByTag(show_hide,tag_name,parent,display,att,val)
{
	//var show_hide;		//variable to return the new state of the page
	//if parent_id is not entered, then assume it is body element, otherwise,
	if (!parent) {
		var parent = document.body;
	} else if (typeof parent == 'string') {
		parent = getEl(parent);
	} else if (!parent.nodeType == 1) {
		return false;
	}
	
	var list = parent.getElementsByTagName(tag_name);
	
	//hold variable of the element style to be toggled
	var el;
	for (var i = 0; i < list.length; i++) {
	
		//if att/val pair is specified, filter using attribute
		if (att) {
			var att_flag = false;
			for (var j = 0; j < list[i].attributes.length; j++) {
				if (list[i].attributes[j].nodeName.toLowerCase() == att) { 	//only pick up attributes
					if (val) {
						if (list[i].attributes[j].nodeValue.toLowerCase() == val) {
							att_flag = true;
							break;
						}
					} else {
						att_flag = true;
						break;
					}
				}
			}
			if (att_flag == false) continue;
		}
		
		el = list[i].style;
		if (show_hide == 0) {
			el.display = 'none';
			//show_hide = 0;
		} else {
			if (!display || (display == 'default' || display == 0 || display == '')) el.display = defDisp(list[i]);
			else el.display = display;
			//show_hide = 1;
		}
	}
	return show_hide;
}

//defDis function hardcodes relationship between elements and default display
function defDisp(el)
{
	var disp = 'inline';		//set the default to inline
	
	if (el.nodeType == 1) {
		switch (el.nodeName.toLowerCase()) {
			case 'table': disp = 'table'; break;
			case 'tr': disp = 'table-row'; break;
			case 'td': disp = 'table-cell'; break;
			case 'li': disp = 'list-item'; break;
		}
	}
	
	//freak out - browser detect - cant seem to find away around ie 7 not noticing table-row!!!
	var agt = navigator.userAgent.toLowerCase();
	var is_ie = ((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1));
	if (is_ie) disp = 'inline';
	
	return disp;
}

//printPos function - function that prints the executive positions section to the page
function printPos(xml_obj)
{
	//takes an xmlhttp object as an argument and returns the root node then selects only the nodes of interest
	var xml = getResponse(xml_obj);
	xml = getChildrenByTagName(getResponse(xml_obj),'position');
	//holds the number of positions
	var length = xml.length;
	//holds the string to print
	var str = '';
	//hld the current position
	var pos;
	//holds the hide icon string
	var hide_str = '<img src="/img/hide.gif" />';
	//holds the shopw icon string
	var show_str = '<img src="/img/show.gif" />';
	
	//put the links in for show/hide all
	str += '<div class="allbox">' +
		'<a href="#" id="hide_all"><img alt="hide all" src="/img/hide_all.gif" /></a>&nbsp;&nbsp;' +
		'<a href="#" id="show_all"><img alt="show all" src="/img/show_all.gif" /></a>' +
	'</div>';
	
	for (var i = 0; i < xml.length; i++) {
		//put the current position into an xmlExtract object
		pos = new xmlExtract(xml[i]);
		//write html string for table
		str += '<table class="pos" id="pos' + i + '"><tr>';
		str += '<td colspan="2" class="postitle"><span class="postitle">' + pos.get('title').text + '</span>';
		str += '<span class="postog"><a href="#" class="postog" id="postog' + i + '">' + hide_str + '</a></span></td></tr>';
		str += '<tr class="hide"><td class="poshead">Role:</td><td class="posdesc">' + pos.get('description').text + '</td></tr>';
		str += '<tr class="hide"><td class="poshead">Qualities:</td><td class="posdesc">'+ pos.get('qualities').text +'</td></tr>';
		str += '</tr></table>';
	}
	
	getEl('postable').innerHTML = str;
	
	for (i = 0; i < xml.length; i++) {
		//toggle visibility function
		getEl('postog' + i).onclick = function () {
			var par = findParent(this,2,'table','class','pos');
			var tog;
			if (this.innerHTML.indexOf('hide') != -1) {
				tog = 0;
				getChildrenByTagName(this,'img')[0].src = '/img/show.gif';
			} else {
				tog = 1;
				getChildrenByTagName(this,'img')[0].src = '/img/hide.gif';
			}
			toggleVisByTag(tog,'tr',par,0,'class','hide');
			return false;
		}
		
		//toggle image onmousedown function
		getEl('postog' + i).onmousedown = function () {
			if (this.innerHTML.indexOf('hide') != -1) {
				//switch the image src from standard to pushed image.
				getChildrenByTagName(this,'img')[0].src = '/img/hide_on.gif';
			} else if (this.innerHTML.indexOf('show') != -1) {
				getChildrenByTagName(this,'img')[0].src = '/img/show_on.gif';
			}
		}
		
		//toggle image onmouseout function
		getEl('postog' + i).onmouseout = function () {
			if (this.innerHTML.indexOf('hide') != -1) {
				//switch the visibility of the standard and the pushed button.
				getChildrenByTagName(this,'img')[0].src = '/img/hide.gif';
			} else if (this.innerHTML.indexOf('show') != -1) {
				getChildrenByTagName(this,'img')[0].src = '/img/show.gif';
			}
		}
	}
	
	//hide all event handlers
	getEl('hide_all').onclick = function () {
		toggleVisByTag(0,'tr','postable',0,'class','hide');
		var list = getElementsByAtt('a','class','postog',getEl('postable'));
		for (var i = 0; i < list.length; i++) {
			getChildrenByTagName(list[i],'img')[0].src = '/img/show.gif';
		}
		return false;
	}
	
	getEl('hide_all').onmousedown = function () {
		getChildrenByTagName(this,'img')[0].src = '/img/hide_all_on.gif';
	}
	
	getEl('hide_all').onmouseout = function () {
		getChildrenByTagName(this,'img')[0].src = '/img/hide_all.gif';
	}
	
	getEl('hide_all').onmouseup = function () {
		getChildrenByTagName(this,'img')[0].src = '/img/hide_all.gif';
	}
	
	//show all event handlers
	getEl('show_all').onclick = function () {
		toggleVisByTag(1,'tr','postable',0,'class','hide');
		var list = getElementsByAtt('a','class','postog',getEl('postable'));
		for (var i = 0; i < list.length; i++) {
			getChildrenByTagName(list[i],'img')[0].src = '/img/hide.gif';
		}
		return false;
	}
	
	getEl('show_all').onmousedown = function () {
		getChildrenByTagName(this,'img')[0].src = '/img/show_all_on.gif';
	}
	
	getEl('show_all').onmouseout = function () {
		getChildrenByTagName(this,'img')[0].src = '/img/show_all.gif';
	}
	
	getEl('show_all').onmouseup = function () {
		getChildrenByTagName(this,'img')[0].src = '/img/show_all.gif';
	}
}

//findParent function - returns the youngest parent of obj matching criteria
function findParent(obj,type,arg1,arg2,arg3)
{
	//loop through until the top of the document. attributes are needed, so test if they are null too.
	//all html nodes have an attribute list, even if it is 0 length, but #document does not.
	while (obj.parentNode && obj.parentNode.attributes) {
		//go to the next parent
		obj = obj.parentNode;
		//type argument sets which branch to follow
		if (type == 0  && obj.nodeName.toLowerCase() == arg1.toLowerCase()) {
			//type = 0 if only need to find parent with given tag name
			return obj;
		} else if (type == 1 && obj.attributes[arg1]) {
			//type = 1 if only need to find parent with given att/value pair
			if (obj.attributes[arg1].value == arg2) {
				return obj;
			}
		} else if (type == 2 && obj.nodeName.toLowerCase() == arg1.toLowerCase()) {
			//type = 2 need both tag name att/value matching
			if (obj.attributes[arg2]) {
				if (obj.attributes[arg2].value == arg3) {
					return obj;
				}
			}
		}
	}
	//default return if no matches is null
	return null;
}

function getElementsByAtt(tag,att,value,parent)
{
	var list = parent.getElementsByTagName(tag);
	var arr = new Array();
	for (var i = 0; i < list.length; i++) {
		if (list[i].attributes[att]) {
			if (list[i].attributes[att].value == value) {
				arr.push(list[i]);
			}
		}
	}
	return arr;
}