/*
=====================================================
Common Routines
=====================================================
*/

reqList = new Array();

function getFieldValue(_form, _fieldname) {
	var value;
	if (_form && _form.elements && _fieldname) {
		for (var i = 0; i < _form.elements.length; i++) {
			if (_form.elements[i]) {
				if (_form.elements[i].name == _fieldname) {
					if ((_form.elements[i].type == 'radio') || (_form.elements[i].type == 'checkbox')) {
						if (_form.elements[i].checked) { value = _form.elements[i].value; }
					} else {
						value = _form.elements[i].value;
					}
				}
			}
		}
	}
	return value;
}

function setFieldValue(_form, _fieldname, _value) {
	var success = false;
	if (_form && _form.elements && _fieldname) {
		for (var i = 0; i < _form.elements.length; i++) {
			if (_form.elements[i]) {
				if (_form.elements[i].name == _fieldname) {
					if ((_form.elements[i].type == 'radio') || (_form.elements[i].type == 'checkbox')) {
						if (_form.elements[i].value == _value) { _form.elements[i].checked = true; success = true; }
						else { _form.elements[i].checked = false; }
					} else {
						_form.elements[i].value = _value;
						success = true;
					}
				}
			}
		}
	}
	return success;
}

function readForm(_form, _data) {
	var args = new Object();
	for (var field = 0; field < _form.elements.length; field++) {
		var name = _form.elements[field].name;
		if (_form.elements[field].isEditor) {
			var editor = FCKeditorAPI.GetInstance(_form.elements[field].editorName);
			_form.elements[field].value = editor.GetXHTML();
			_form.elements[_form.elements[field].editorName].noSend = true;
// 			_form.elements[field].value = _form.elements[field].CKeditor.getData();
		}
		if (_form.elements[field].name) {
			if ((_form.elements[field].type == 'radio') || (_form.elements[field].type == 'checkbox')) {
				if (_form.elements[field].checked) {
					if (args[name]) {
						args[name].values.push(_form.elements[field].value);
					} else {
						args[name] = {
							value:	_form.elements[field].value,
							values:	[_form.elements[field].value]
						};
					}
				}
			} else {
				if (args[name]) {
					args[name].values.push(_form.elements[field].value);
				} else {
					args[name] = {
						value:	_form.elements[field].value,
						values:	[_form.elements[field].value]
					};
				}
			}
		}
	}
	return args;
}


function fillForm(_data, _form) {
//	debugObject(_data, 0);
	var editorTotal = 0;
	for (var i = 0; i < _form.elements.length; i++) {
		var field = _form.elements[i];
		var data = _data;
		if (_data.length) {
			data = _data[0];
		}
		
		if (field.className == 'editor') { editorTotal++; }
		
		var name = field.name;
		var datePart = '';
		var dateField = field.name.match('^(.+?)\.(date|time|meridian|merbutton|tz|field|menu)$');
		if (dateField && dateField[2]) {
			name = dateField[1];
			datePart = dateField[2];
		}
		var nameArray = name.split('\.');
		var value = '';
		if (nameArray[0] && ((nameArray[0] == 'file') || (nameArray[0] == 'media')) && nameArray[1] && data['item'] && data['item'][nameArray[0]]) {
			value = data['item'][nameArray[0]][nameArray[1]];
//			log.add(field.name + ': item, ' + nameArray[0] + ', ' + nameArray[1] + ' = ' + value);
		} else if (nameArray[0] && ((nameArray[0] == 'file') || (nameArray[0] == 'media')) && nameArray[1] && data['setting'] && data['setting'][nameArray[0]]) {
			value = data['setting'][nameArray[0]][nameArray[1]];
//			log.add(field.name + ': item, ' + nameArray[0] + ', ' + nameArray[1] + ' = ' + value);
		} else if (nameArray[0] && nameArray[1] && nameArray[2] && data[nameArray[0]] && data[nameArray[0]][nameArray[1]]) {
			value = data[nameArray[0]][nameArray[1]][nameArray[2]];
//			log.add(field.name + ': ' + nameArray[0] + ', ' + nameArray[1] + ', ' + nameArray[2] + ' = ' + value);
		} else if (nameArray[0] && nameArray[1] && data[nameArray[0]]) {
			value = data[nameArray[0]][nameArray[1]];
//			log.add(field.name + ': ' + nameArray[0] + ', ' + nameArray[1] + ' = ' + value);
		} else if (nameArray[0]) {
			value = data[nameArray[0]];
//			log.add(field.name + ': ' + nameArray[0] + ' = ' + value);
		}
//		debug('field ' + name + ' = ' + value);
		
		if (value) {
			if (datePart == 'date') {
				var dateArray = value.match('^([0-9]+)\-([0-9]+)\-([0-9]+)');
				if (dateArray[3]) {
					var month = Number(dateArray[2]);
					var day = Number(dateArray[3]);
					field.value = month + '/' + day + '/' + dateArray[1];
				}
			} else if (datePart == 'time') {
				var timeArray = value.match(' ([0-9]+)(:[0-9]+)');
				if (timeArray && timeArray[1] && timeArray[2]) {
					var hour = Number(timeArray[1]);
					if (hour < 1) { hour += 12; }
					else if (hour > 12) { hour -= 12; }
					else { hour = Number(hour); }
					field.value = hour + timeArray[2];
				}
				debug('time ' + field.name + ' = ' + field.value);
			} else if (datePart == 'meridian') {
				var timeArray = value.match(' ([0-9]+)(:[0-9]+(?::[0-9]+)?)');
				if (timeArray && timeArray[1] && timeArray[2]) {
					var hour = timeArray[1];
					var meridian = 'am';
					if (hour > 11) { meridian = 'pm'; }
					field.value = meridian;
				}
			} else if (datePart == 'merbutton') {
				var timeArray = value.match(' ([0-9]+)(:[0-9]+(?::[0-9]+)?)');
				if (timeArray && timeArray[1] && timeArray[2]) {
					var hour = timeArray[1];
					var meridian = 'am';
					if (hour > 11) { meridian = 'pm'; }
					field.value = meridian;
				}
			} else if (datePart == 'tz') {
				field.value = '-6';
			} else if (datePart == 'field') {
				var valueArray = value.match('^([a-zA-Z0-9_]+)');
				if (valueArray && valueArray[1]) { field.value = valueArray[1]; }
			} else if (datePart == 'menu') {
				var valueArray = value.match('^[a-zA-Z0-9_]+ +(.+)');
				if (valueArray && valueArray[1]) { field.value = valueArray[1]; }
			} else if (field.type == 'checkbox') {
				if (typeof value == 'object') {
					field.checked = false;
					for (var j = 0; j < value.length; j++) {
						if (value[j] == field.value) { field.checked = true; }
					}
				}
				else if (value == field.value) { field.checked = true; }
				else { field.checked = false; }
			} else if (field.type == 'radio') {
				if (value == field.value) { field.checked = true; }
				else { field.checked = false; }
			} else {
				field.value = value;
				if (field.isEditor) {
					if (field.CKeditor.setData) { field.CKeditor.setData(value); }
					else { CKEDITOR.on('loaded', function() { field.CKeditor.setData(value); }); }
				}
			}
		} else {
			if (field.type == 'select-one') {
				var done = false;
				for (var j = 0; j < field.options.length; j++) {
					if (!done && (field.options[j].value == 0)) {
						field.selectedIndex = j;
						done = true;
					}
				}
			} else if (field.type == 'radio') {
				if (field.value == 0) { field.checked = true; }
			}
		}
		if (field.afterLoad) { field.afterLoad(); }
	}
//	for (var i = 0; i < _form.elements.length; i++) {
//		var field = _form.elements[i];
//		if (field.onchange) { debug('onchange ' + field.name); field.onchange(); }
//	}
	
	if (_form.pauseKey && !editorTotal) {
//		debug('unpausing after fillForm');
		unpauseScreen(_form.pauseKey);
	}
// 	if (editorTotal) {
// 		_form.editorTotal = editorTotal;
// 		finishFill(_form);
// 	}
	if (_form.afterFillForm) {
		_form.afterFillForm(_data);
	}
	unpauseScreen(_form.pauseKey);
}

/*
function finishFill(_form) {
	_form.filled = true;
//	debug('ffill: finished filling form');
	if (_form.editorList) {
//		debug('ffill: found a list');
		for (var i = 0; i < _form.editorList.length; i++) {
			var editorInstance = _form.editorList[i];
//			debug('ffill: going to fill ' + editorInstance);
			fillFCKeditor(editorInstance);
		}
	}
	if (_form.filled && (_form.editorTotal <= _form.editorCnt)) {
//		debug('ffill: all good');
		unpauseScreen(_form.pauseKey);
	}
}

function fillFCKeditor(editorInstance) {
	var editorField = editorInstance.Name.match('^(.+?)-([a-z0-9]+)$');
	if (editorField && editorField[1] && editorField[2] && editorInstance) {
		var form = document.getElementById('form_' + editorField[2]);
		if (form[editorField[1]].value) {
			// Safari doesn't do the insert the first time,
			//   so first I do a bogus insert for Safari before the real one
			if (RegExp(" AppleWebKit/").test(navigator.userAgent)) {
				editorInstance.InsertHtml('');
			}
			// Real insert
			editorInstance.InsertHtml(form[editorField[1]].value);
			
// 			var oCKeditor = CKEDITOR.appendTo('ckeditor_' + form[editorField[1]].name);
// 			if (oCKeditor.setData) { oCKeditor.setData(form[editorField[1]].value); }
// 			else { CKEDITOR.on('loaded', function() { oCKeditor.setData(form[editorField[1]].value); }); }
			
		}
	}
}


function FCKeditor_OnComplete(editorInstance) {
//	debug('onComplete ' + editorInstance);
	finishFCKeditor(editorInstance);
}

function finishFCKeditor(editorInstance) {
	var editorField = editorInstance.Name.match('^(.+?)-([a-z0-9]+)$');
	if (editorField && editorField[1] && editorField[2] && editorInstance) {
		var _form = document.getElementById('form_' + editorField[2]);
		debug('looking for field ' + editorField[1]);
		_form[editorField[1]].editorName = editorInstance.Name;
		_form[editorField[1]].isEditor = true;
		_form[editorField[1]].isEditorComplete = true;
		if (_form.editorCnt) { _form.editorCnt++; }
		else { _form.editorCnt = 1; }
//		debug('ffck: count ' + _form.editorCnt);
		if (_form.filled) {
//			debug('ffck: fill is finished');
			fillFCKeditor(editorInstance);
		} else if (_form.editorList) {
//			debug('ffck: fill not finished, adding to list');
			_form.editorList.push(editorInstance);
		} else {
//			debug('ffck: fill not finished, starting list');
			_form.editorList = new Array();
			_form.editorList.push(editorInstance);
		}
		if (_form.filled && (_form.editorTotal <= _form.editorCnt)) {
//			debug('ffck: all good');
			unpauseScreen(_form.pauseKey);
		}
		// I think this was for the editor in Page and is no longer needed
		if (_form[editorField[1]].shouldResize) {
			_form[editorField[1]].shouldResize = false;
			_form.parentEditor.resizeY();
		}
	}
}
*/

function sendForm(_url, _function, _form, _data, _functionFail) {
	var args = new Array();
	var exist = new Object();
	var blank = new Object();
	for (var field = 0; field < _form.elements.length; field++) {
		if (_form.elements[field].noSend) {
		} else {
			if (_form.elements[field].isEditor) {
// 				var editor = FCKeditorAPI.GetInstance(_form.elements[field].editorName);
// 				_form.elements[field].value = editor.GetXHTML();
// 				_form.elements[_form.elements[field].editorName].noSend = true;
				_form.elements[field].value = _form.elements[field].CKeditor.getData();
			}
			if (_form.elements[field].name) {
				if ((_form.elements[field].type == 'radio') || (_form.elements[field].type == 'checkbox')) {
					if (_form.elements[field].checked) {
						args.push(encodeURIComponent(_form.elements[field].name) + '=' + encodeURIComponent(_form.elements[field].value));
						exist[_form.elements[field].name] = 1;
					} else {
						blank[_form.elements[field].name] = 1;
					}
				} else if (_form.elements[field].type == 'file') {
					var matchArray = _form.elements[field].name.match(/^(\w+)/);
					if (matchArray && matchArray[1]) {
						key = uniqueKey();
						if (_form.elements[field].value) {
							args.push(encodeURIComponent(matchArray[1] + '.key') + '=' + encodeURIComponent(key));
							submitToiFrame(_form, '/members/upload?prefix=' + matchArray[1] + '&key=' + key, key);
						} else if (_form.elements[matchArray[1] + '.id'] && _form.elements[matchArray[1] + '.id'].value) {
							submitToiFrame(_form, '/members/upload?prefix=' + matchArray[1] + '&id=' + _form.elements[matchArray[1] + '.id'].value, key);
						}
					}
				} else {
					args.push(encodeURIComponent(_form.elements[field].name) + '=' + encodeURIComponent(_form.elements[field].value));
				}
			}
		}
	}
	
	for (var fieldname in blank) {
		if (!exist[fieldname]) {
			args.push(encodeURIComponent(fieldname) + '=');
		}
	}
	if (_data) {
		for (var fieldname in _data) {
			args.push(encodeURIComponent(fieldname) + '=' + encodeURIComponent(_data[fieldname]));
		}
	}
	var query_string = args.join('&');
	sendRequest(_url, _function, _form, query_string, _functionFail);
}

function submitToiFrame(_form, _url, _id) {
	debug('Sending to iframe ' + _id + ' to ' + _url);
	var iframe = document.createElement('iframe')
	iframe.setAttribute('id', 'upload_' + _id);
	iframe.setAttribute('name', 'upload_' + _id);
	iframe.setAttribute('class', 'upload_frame');
	iframe.style.display = 'none';
	document.body.appendChild(iframe);
	_form.action = _url
	_form.target = 'upload_' + _id;
	_form.submit();
}

function uniqueKey() {
	var d = new Date();
	var key = d.getTime().toString() + Math.round(10000*Math.random()).toString();
	return key.substring(5);
}


function sendObject(_url, _function, _object, _data) {
	if (_data) {
		var args = new Array();
		for (var key in _data) {
			args.push(encodeURIComponent(key) + '=' + encodeURIComponent(_data[key]));
		}
		var query_string = args.join('&');
		sendRequest(_url, _function, _object, query_string);
	}
}


function sendArray(_url, _function, _object, _name, _data) {
	if (_name && _data) {
		var args = new Array();
		for (var i = 0; i < _data.length; i++) {
			args.push(encodeURIComponent(_name) + '=' + encodeURIComponent(_data[i]));
		}
		var query_string = args.join('&');
		sendRequest(_url, _function, _object, query_string);
	}
}


function sendRequest(_url, _function, _object, _data, _functionFail) {
	// branch for native XMLHttpRequest object
	if (_object.pauseElement) {
		_object.pauseKey = uniqueKey();
		pauseScreen(_object.pauseKey, _object.pauseElement, _object.pauseMessage);
	}
	var cacheKey = uniqueKey();
	if (window.XMLHttpRequest) {
		var req = new XMLHttpRequest();
		req.processFunction = _function;
		req.processFunctionFail = _functionFail;
		req.callingObject = _object;
		req.url = _url;
		req.onreadystatechange = processRequest;
		if (_data) {
			debug('POST ' + _url);
			req.open("POST", _url, true);
			req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
			req.send(_data);
		} else {
			if (_url.match(/\?/)) { _url = _url + '&' + cacheKey; }
			else { _url = _url + '?' + cacheKey; }
			debug('GET ' + _url);
			req.open("GET", _url, true);
			req.send(null);
		}
		reqList.push(req);
	// branch for IE/Windows ActiveX version
	} else if (window.ActiveXObject) {
		var req = new ActiveXObject("Microsoft.XMLHTTP");
		if (req) {
			req.onreadystatechange = processRequest;
			if (_data) {
				req.open("POST", _url, true);
				req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
				req.send(_data);
			} else {
				if (_url.match(/\?/)) { _url = _url + '&' + cacheKey; }
				else { _url = _url + '?' + cacheKey; }
				req.open("GET", _url, true);
				req.send(null);
			}
			req.processFunction = _function;
			req.processFunctionFail = _functionFail;
			req.callingObject = _object;
			reqList.push(req);
		}
	}
}


function processRequest() {
//	only if req shows "loaded"
	var complete = false;
	for (var i = 0; i < reqList.length; i++) {
		var req = reqList[i];
//		debug('--> check ' + req.url);
		if (req.complete) {
			complete = true;
		} else if (req.readyState == 4) {
//			debug('----> ready 4 ' + req.url + ', status=' + req.status);
			// only if "OK"
			if (req.status == 200) {
				req.complete = true;
				complete = true;
				var results = req.responseText;
//				debug('------> 200: processRequest(' + req.url + ')');
				var response = convertXMLtoObj(req.responseXML, 0);
//				debug(printObject(response, 0));
				if (req.processFunction) {
					req.processFunction(response.sitemasonAPI, req.callingObject);
				} else if (req.callingObject && req.callingObject.pauseKey) {
					unpauseScreen(req.callingObject.pauseKey);
				}
			} else {
				req.complete = true;
				complete = true;
				if (req.processFunctionFail) {
					req.processFunctionFail(req.callingObject);
				} else {
					alert("There was a problem connecting to the server:\n" + req.statusText);
				}
			}
		}
	}
	if (complete) {
		var tmpArray = new Array();
		for (var j = 0; j < reqList.length; j++) {
			if (!reqList[j].complete) {
				debug('--> keeping ' + reqList[j].url);
				tmpArray.push(reqList[j]);
			}
		}
		reqList = tmpArray;
	}
}


var pauseScreenList = new Object();

function pauseScreen(_name, _pauseObject, _pauseMessage) {
	if (_name && !pauseScreenList[_name] && _pauseObject) {
		var _parent = _pauseObject.parentNode;
		pauseScreenList[_name] = createDiv({ className: 'pause_screen' });
		pauseScreenList[_name].style.top = _pauseObject.style.top;
		pauseScreenList[_name].style.left = _pauseObject.style.left;
		pauseScreenList[_name].style.width = _pauseObject.style.width;
		pauseScreenList[_name].style.height = _pauseObject.style.height;
		_parent.appendChild( pauseScreenList[_name] );
		if (!_pauseMessage) { _pauseMessage = 'Loading...'; }
		_pauseMessage += '<br /><img src="/members/resources/interface/images/indicators/activity_blue_bar.gif" width="220" height="19" alt="" />';
		var pauseMessage = createDiv({ className: 'message', html: _pauseMessage });
		var matchArray = pauseScreenList[_name].style.height.match(/(\d+)/);
		if (matchArray && matchArray[1]) {
			pauseMessage.style.marginTop = Math.floor((matchArray[1]/2) - 30) + 'px';
		}
		pauseScreenList[_name].appendChild( pauseMessage );
	}
}


function unpauseScreen(_name) {
	if (_name) {
		if (pauseScreenList[_name]) {
			if (pauseScreenList[_name]) {
				pauseScreenList[_name].parentNode.removeChild(pauseScreenList[_name]);
			}
			delete pauseScreenList[_name];
		}
	}
}


function convertXMLtoObj(_xml, _depth) {
	var xml = _xml;
	var hash = new Object();
	var tabs = '';
	for (var tab = 0; tab < _depth; tab++) { tabs += '- '; }
	if (xml && xml.childNodes && (typeof xml == 'object')) {
		var cnt = 0;
		for (var a = 0; a < xml.childNodes.length; a++) {
			var name = xml.childNodes[a]['nodeName'];
			if (xml.childNodes[a]['nodeName'] == '#text') {
			} else if (typeof xml.childNodes[a] == 'object') {
				var type = getAttr(xml.childNodes[a], 'type');
				if (type == 'array') {
					if (!hash[name]) {
//						debug(tabs + name);
						if ((typeof xml.childNodes[a] == 'object') && (xml.childNodes[a].childNodes.length > 1)) {
							var value = xml.childNodes[a].firstChild.data;
//							debug(tabs + '- |' + cnt + '| ' + value + ' (' + typeof xml.childNodes[a] + ', ' + xml.childNodes[a].childNodes.length + ')');
							hash[name] = [convertXMLtoObj(xml.childNodes[a], Number(_depth) + 2)];
						} else if (xml.childNodes[a].childNodes.length == 0) {
							hash[name] = [''];
						} else if (xml.childNodes[a].firstChild) {
							var value = xml.childNodes[a].firstChild.data;
//							debug(tabs + '- |' + cnt + '| ' + value);
							hash[name] = [value];
						}
					} else {
						if ((typeof xml.childNodes[a] == 'object') && (xml.childNodes[a].childNodes.length > 1)) {
							var value = xml.childNodes[a].firstChild.data;
//							debug(tabs + '- [' + cnt + '] ' + value + ' (' + typeof xml.childNodes[a] + ', ' + xml.childNodes[a].childNodes.length + ')');
							hash[name].push(convertXMLtoObj(xml.childNodes[a], Number(_depth) + 2));
						} else if (xml.childNodes[a].childNodes.length == 0) {
							hash[name] = [''];
						} else if (xml.childNodes[a].firstChild) {
							var value = xml.childNodes[a].firstChild.data;
//							debug(tabs + '- [' + cnt + '] ' + value);
							hash[name].push(value);
						}
					}
					cnt++;
				} else if ((typeof xml.childNodes[a] == 'object') && (xml.childNodes[a].childNodes.length > 1)) {
					var value = '';
					var isString = true;
					for (var i = 0; i < xml.childNodes[a].childNodes.length; i++) {
						if (typeof xml.childNodes[a].childNodes[i].data != 'string') { isString = false; }
					}
					if (isString) {
						for (var i = 0; i < xml.childNodes[a].childNodes.length; i++) {
							value = value + xml.childNodes[a].childNodes[i].data;
						}
//						debug(tabs + name + ': ' + value);
						hash[name] = value;
						cnt++;
					} else {
//						debug(tabs + name + ':: ' + value + ' (' + typeof xml.childNodes[a] + ', ' + xml.childNodes[a].childNodes.length + ')');
						hash[name] = convertXMLtoObj(xml.childNodes[a], Number(_depth) + 1);
						cnt++;
					}
				} else if (xml.childNodes[a].firstChild) {
					var value = xml.childNodes[a].firstChild.data;
//					debug(tabs + name + ': ' + value);
					hash[name] = value;
					cnt++;
				} else {
					debug('convertXMLtoObj: Found a blank XML element - ' + name);
				}
			}
		}
	}
	return hash;
}


/*
=====================================================
Load HTML from a URL
=====================================================
*/

// Sets '.html' in the given object to the contents of the given URL.
//   loadHTML(this, '/members/resources/interface/html/tag_entry.html');
function loadHTML(_object, _url) {
	sendHTMLrequest(_url, _common_setHTML, _object);
}

function _common_setHTML(_html, _object) {
	_object.html = _html;
}

// Calls the given function and passes the text contents of the given URL as the first argument. An optional object may be given that will be passed through to the called function as the second argument.
//   sendHTMLrequest('/members/resources/interface/html/tag_entry.html', setContents, this);
function sendHTMLrequest(_url, _function, _object) {
	// branch for native XMLHttpRequest object
	if (window.XMLHttpRequest) {
		var htmlReq = new XMLHttpRequest();
		htmlReq = new XMLHttpRequest();
		htmlReq.processFunction = _function;
		htmlReq.callingObject = _object;
		htmlReq.onreadystatechange = _common_processHTMLrequest;
		htmlReq.open("GET", _url, true);
		htmlReq.send(null);
		reqList.push(htmlReq);
	// branch for IE/Windows ActiveX version
	} else if (window.ActiveXObject) {
		var htmlReq = new ActiveXObject("Microsoft.XMLHTTP");
		if (htmlReq) {
			htmlReq.processFunction = _function;
			htmlReq.callingObject = _object;
			htmlReq.onreadystatechange = _common_processHTMLrequest;
			htmlReq.open("GET", _url, true);
			htmlReq.send();
			reqList.push(htmlReq);
		}
	}
}

function _common_processHTMLrequest() {
//	only if req shows "loaded"
	var complete = false;
	for (var i = 0; i < reqList.length; i++) {
		var htmlReq = reqList[i];
//		debug('--> check ' + htmlReq.url);
		if (htmlReq.complete) {
			complete = true;
		} else if (htmlReq.readyState == 4) {
//			debug('----> ready 4 ' + htmlReq.url);
			// only if "OK"
			if (htmlReq.status == 200) {
				htmlReq.complete = true;
				complete = true;
				var results = htmlReq.responseText;
				var parts = results.match(/^(.*?)(?:\n|\r)/m);
				var body = results.replace(/^(.*?)(?:\n|\r)/m, '');
				if (htmlReq.processFunction) {
					htmlReq.processFunction(results, htmlReq.callingObject);
				}
			} else {
				alert("There was a problem retrieving the HTML:\n" + htmlReq.statusText);
			}
		}
	}
	if (complete) {
		var tmpArray = new Array();
		for (var j = 0; j < reqList.length; j++) {
			if (!reqList[j].complete) {
//				debug('--> keeping ' + reqList[j].url);
				tmpArray.push(reqList[j]);
			}
		}
		reqList = tmpArray;
	}
}


/*
=====================================================
HTML and DOM functions
=====================================================
*/

// Returns the number of pixels from the left side of the window for the given element.
function findPosX(obj, _stop) {
	var curleft = 0;
	var cnt = 0;
	var stop = 'stop traversing';
	if (_stop) { stop = _stop; }
	if (obj.offsetParent) {
		while (obj.offsetParent && (obj.id != stop)) {
//			cnt += 1;
//			log.add(cnt + ': ' + curleft + ' (left) +=' + obj.offsetLeft + ' - ' + obj.id);
			curleft += obj.offsetLeft
			obj = obj.offsetParent;
		}
	}
	else if (obj.x) { curleft += obj.x; }
	return curleft;
}

// Returns the number of pixels from the top of the window for the given element.
function findPosY(obj, _stop) {
	var curtop = 0;
	var cnt = 0;
	var stop = 'stop traversing';
	if (_stop) { stop = _stop; }
	if (obj.offsetParent) {
		while (obj.offsetParent && (obj.id != stop)) {
//			cnt += 1;
//			log.add(cnt + ': ' + curtop + ' (top) +=' + obj.offsetTop + ' - ' + obj.id);
			curtop += obj.offsetTop
			obj = obj.offsetParent;
		}
	}
	else if (obj.y) { curtop += obj.y; }
	return curtop;
}

// Returns a div with the given attributes.
function createDiv(_param) {
	var newDiv = document.createElement('div');
	if (_param) {
		if (_param.id) { newDiv.setAttribute('id', _param.id); }
		if (_param.name) { newDiv.setAttribute('name', _param.name); }
		if (_param.className) { newDiv.setAttribute('class', _param.className); }
		if (_param.html) { newDiv.innerHTML = _param.html; }
		if (_param.style) {
			for (var name in _param.style) {
				var value = _param.style[name];
				newDiv.style[name] = value;
			}
		}
		if (_param.onmousemove) { newDiv.onmousemove = _param.onmousemove; }
		if (_param.onmousedown) { newDiv.onmousedown = _param.onmousedown; }
		if (_param.onmouseup) { newDiv.onmouseup = _param.onmouseup; }
	}
	return newDiv;
}

// Returns an array of the option values for the given select element.
function selectToArray(_select) {
	var newArray = new Array();
	if (_select && _select.options) {
		for (var i = 0; i < _select.options.length; i++) {
			if (_select.options[i] && _select.options[i].value) {
				newArray.push(_select.options[i].value);
			}
		}
	}
	return uniqueArray(newArray);
}

function selectToArrayObject(_select) {
	var newArray = new Array();
	if (_select && _select.options) {
		for (var i = 0; i < _select.options.length; i++) {
			if (_select.options[i] && _select.options[i].text) {
				newArray.push( { label: _select.options[i].text, value: _select.options[i].value, selected: _select.options[i].selected } );
			}
		}
	}
	return uniqueArray(newArray);
}

function selectedOptionsToArray(_select) {
	var newArray = new Array();
	if (_select && _select.options) {
		for (var i = 0; i < _select.options.length; i++) {
			if (_select.options[i] && _select.options[i].selected && _select.options[i].value) {
				newArray.push(_select.options[i].value);
			}
		}
	}
	return uniqueArray(newArray);
}

// Replaces options in a select with the given array.
function arrayToSelect(_array, _select) {
	if (_array && _select && _select.options) {
		var newArray = uniqueArray(_array);
		_select.options.length = 0;
		for (var i = 0; i < newArray.length; i++) {
			if ((typeof newArray[i] == 'object') && newArray[i].label) {
				var is_selected = false;
				if (newArray[i].selected) { is_selected = true; }
				_select.appendChild(new Option(newArray[i].label, newArray[i].value, is_selected, is_selected));
			} else if (newArray[i]) {
				_select.appendChild(new Option(newArray[i], newArray[i], false, false));
			}
		}
		return true;
	}
	return false;
}

// Adds options in a select with the given array.
function addOptionsToSelect(_array, _select) {
	if (_array && _select) {
		var selectOptions = selectToArrayObject(_select);
		combineArrays(selectOptions, _array);
		arrayToSelect(selectOptions, _select);
		return true;
	}
	return false;
}

function removeOptionsFromSelect(_select, _array) {
	if (_array && _select) {
		var newArray = Array();
		var selectOptions = selectToArrayObject(_select);
		for (var i = 0; i < selectOptions.length; i++) {
			if (selectOptions[i] && (typeof selectOptions[i] == 'object')) {
				if (!arrayContains(_array, selectOptions[i].value)) {
					newArray.push( { label: selectOptions[i].label, value: selectOptions[i].value, selected: selectOptions[i].selected } );
				}
			} else if (selectOptions[i]) {
				if (!arrayContains(_array, selectOptions[i])) {
					newArray.push(selectOptions[i]);
				}
			}
		}
		arrayToSelect(newArray, _select);
		return true;
	}
	return false;
}


/*
=====================================================
Array Functions
=====================================================
*/

function addToArray(_array, _item) {
	_array.push(_item);
	var newArray = uniqueArray(_array);
	return newArray;
}

function removeFromArray(_array, _item) {
	var newArray = new Array();
	for (var i = 0; i < _array.length; i++) {
		if (_array[i] != _item) { newArray.push(_array[i]); }
	}
	return newArray;
}

function arrayToList(_array) {
	var newArray = uniqueArray(_array);
	var list = newArray.join(', ');
	return list;
}

function listToArray(_list) {
	var newArray = new Array();
	if (_list) {
		var _array = _list.split(/\s*,\s*/);
		if (_array) {
			newArray = uniqueArray(_array);
		}
	}
	return newArray;
}

function arrayToCR(_array) {
	var newArray = uniqueArray(_array);
	var list = newArray.join("\n");
	return list;
}

function CRToArray(_list) {
	var newArray = new Array();
	if (_list) {
		var _array = _list.split(/\s*\n\s*/);
		if (_array) {
			newArray = uniqueArray(_array);
		}
	}
	return newArray;
}

function uniqueArray(_array) {
	var newArray = new Array();
	if (_array) {
		for (var i = 0; i < _array.length; i++) {
			if (_array[i] && !arrayContains(newArray, _array[i])) { newArray.push(_array[i]); }
		}
	}
	var sortedArray = newArray.sort(sortAlpha);
	return sortedArray;
}

function arrayContains(_array, _string) {
	if (_array && _string) {
		for (var i = 0; i < _array.length; i++) {
			if ((typeof _array[i] == 'object') && (_array[i].value == _string)) { return true; }
			else if (_array[i] == _string) { return true; }
		}
	}
	return false;
}

function combineArrays(_array1, _array2) {
	if (_array1 && _array2) {
		for (var i = 0; i < _array2.length; i++) {
			_array1.push(_array2[i]);
		}
	}
}

function sortAlpha(a, b) {
	var al;
	var bl;
	if ((typeof a == 'object') && a.label) { al = a.label.toLowerCase(); }
	else { al = a.toLowerCase(); }
	if ((typeof b == 'object') && b.label) { bl = b.label.toLowerCase(); }
	else { bl = b.toLowerCase(); }
	if (al < bl) { return -1; }
	else if (al > bl) { return 1; }
	else { return 0; }
}

function toArray(_object, _key) {
	var newArray = new Array();
	if (typeof _object == 'object') {
		for (var i = 0; i < _object.length; i++) {
			if (_key && (typeof _object[i] == 'object') && _object[i][_key]) {
				newArray.push(_object[i][_key]);
			} else if (typeof _object[i] == 'string') {
				newArray.push(_object[i]);
			}
		}
	} else if (typeof _object == 'string') {
		newArray.push(_object);
	}
	return uniqueArray(newArray);
}


/*
=====================================================
Debugging

Uses Firebug's console API when available.
  http://getfirebug.com/console.html
=====================================================
*/

log = new Log('debug');
function Log(_id) {
	this.element = document.getElementById(_id);
	if (this.element) {
		this.element.style.display = 'none';
	}
	this.active = false;
	this.show = _logShow;
	this.hide = _logHide;
	this.scrollOff = _logScrollOff;
	this.scrollOn = _logScrollOn;
	this.clear = _logClear;
	this.add = _logAdd;
	this.replace = _logReplace;
	this.height = 150;
	this.odd = true;
}

function _logShow() {
	this.active = true;
	if (this.element) {
		this.element.style.height = Number(log.height - 2) + 'px';
		this.element.style.display = '';
	}
}

function _logHide() {
	this.active = false;
	if (this.element) {
		this.element.style.display = 'none';
	}
}

function _logScrollOff() {
	if (this.element) {
		this.element.style.overflow = 'hidden';
	}
}

function _logScrollOn() {
	if (this.element) {
		this.element.style.overflow = 'scroll';
	}
}

function _logClear() {
	if (this.active) {
		this.odd = true;
		if (this.element) {
			this.element.innerHTML = '';
		}
	}
}

function _logAdd(_text) {
	if (this.active) {
		this.show();
		if (!_text) {
			_text = '&nbsp;';
		}
		if (this.element) {
			if (this.odd) {
				this.element.appendChild( createDiv( { className: 'odd', html: _text } ) );
				this.odd = false;
			} else {
				this.element.appendChild( createDiv( { className: 'even', html: _text } ) );
				this.odd = true;
			}
			this.element.scrollTop = this.element.scrollHeight - this.height + 17;
		}
	}
}

function _logReplace(_text) {
	if (this.active) {
		this.clear();
		this.add(_text);
	}
}

function debugInfo(_text) { debug(_text, 'info'); }
function debugWarn(_text) { debug(_text, 'warn'); }
function debugError(_text) { debug(_text, 'error'); }

function debug(_text, _level) {
	if (window.console) {
		if (_level == 'info') { console.info("%s", _text); }
		else if (_level == 'warn') { console.warn("%s", _text); }
		else if (_level == 'error') { console.error("%s", _text); }
		else { console.log("%s", _text); }
	}
	if (log) {
		log.add(_text);
	}
}

function debugObject(_object, _label, _limit) {
	if (window.console) {
		console.info("%s", _label);
		if (console.dir) {
			console.dir(_object);
		} else {
			var output = printObject(_object, _limit, _label);
			console.log(output);
		}
	}
	if (log && log.active) {
		var output = printObject(_object, _limit, _label);
		log.add('<hr />' + output + '<hr />');
	}
}

function debugClear() {
	if (log) {
		log.clear();
	}
}

var printObject_count = 0;
function printObject(_object, _limit, _label, _args) {
	var content = '';
	if (_label) { content = _label + '<br />'; }
	if (!_limit || (_limit == 0)) { _limit = 7; }
	var _loop_limit = 150;
	var _total_limit = 500;
	var _depth = 1;
	if (_args) { _depth = _args.depth; }
	else { printObject_count = 0; }
	if (_object) {
		if (printObject_count < Number(_total_limit)) {
			if (_object && (_depth == 0) && _label) {
				content = 'object ' + _label + '<br />';
				_depth = Number(_depth) + 1;
			}
			var tabs = '';
			for (var tab = 0; tab < _depth; tab++) { tabs += ': . '; }
			if (typeof _object == 'object') {
	//			debug('! ' + typeof _object + ' ' + _object + ' ' + _object.length + ' ' + _depth);
				var length_count = 0;
				var shouldContinue = true;
				var cnt = 0;
				while (shouldContinue) {
					if (_object[cnt]) {
						var i = _object[cnt];
						cnt++;
	// 				for (var i in _object) {
						length_count++;
						if (length_count < Number(_loop_limit)) {
							printObject_count++;
							var lineNumbers;
							if (printObject_count < 10) { lineNumbers = '...' + printObject_count; }
							else if (printObject_count < 100) { lineNumbers = '..' + printObject_count; }
							else if (printObject_count < 1000) { lineNumbers = '.' + printObject_count; }
							lineNumbers += ',';
							if (length_count < 10) { lineNumbers += '..' + length_count; }
							else if (length_count < 100) { lineNumbers += '.' + length_count; }
							var label = i;
							if (_object.length) { label = '[' + i + ']'; }
							if (typeof _object[i] == 'object') {
								if (hasProperties(_object[i])) {
									if (Number(_depth) < Number(_limit)) {
										if ((_depth > 1) && ((i == 'element') || (i == 'subelement') || (i == 'parent') || (i == 'form') || (i == 'parentNode') || (i == 'previousSibling') || (i == 'nextSibling') || (i == 'body'))) {
											content += tabs + label + ' -- LIMITED from element list<br />';
	// 										debug(lineNumbers + ' ' + tabs + label + ' -- LIMITED from element list<br />');
										} else {
											content += tabs + label + ' -- object<br />';
	// 										debug(lineNumbers + ' ' + tabs + label + ' -- object<br />');
											content += printObject(_object[i], _limit, null, {
												depth:	Number(_depth) + 1
											});
										}
									} else {
										content += tabs + label + ' -- LIMITING to depth of ' + _limit + '<br />';
	// 									debug(lineNumbers + ' ' + tabs + label + ' -- LIMITING to depth of ' + _limit + '<br />');
									}
								} else {
									content += tabs + label + ': (null)<br />';
	// 								debug(lineNumbers + ' ' + tabs + label + ': (null)<br />');
								}
							} else if (typeof _object[i] == 'function') {
								content += tabs + 'function ' + label + '();<br />';
	// 							debug(lineNumbers + ' ' + tabs + 'function ' + label + '();<br />');
							} else if (typeof _object[i] == 'string') {
								content += tabs + label + ': ' + _object[i] + '<br />';
	// 							debug(lineNumbers + ' ' + tabs + label + ': ' + _object[i] + '<br />');
							} else {
								content += tabs + label + ': ' + _object[i] + '<br />';
	// 							debug(lineNumbers + ' ' + tabs + label + ': ' + _object[i] + '<br />');
							}
						} else if (length_count == Number(_loop_limit)) {
							content += tabs + 'LIMITING to length of ' + _loop_limit + '<br />';
	// 						debug(tabs + 'LIMITING to length of ' + _loop_limit + '<br />');
						}
					} else { shouldContinue = false;}
				}
			} else {
				content += _object;
			}
		} else if (printObject_count == Number(_total_limit)) {
			content += tabs + 'LIMITING to total length of ' + _total_limit + '<br />';
// 			debug(tabs + 'LIMITING to length of ' + _total_limit + '<br />');
		}
	}
	return content;
}

// Workaround to get IE8 to work. It doesn't seem to have getAttribute where others do.
function getAttr(_object, _name) {
	var answer;
	if (_object && (typeof _object == 'object')) {
// 		if (_object.getAttribute) {
// 			answer = _object.getAttribute(_name);
		if (_object.attributes) {
			for (var i = 0; i < _object.attributes.length; i++) {
				if (_object.attributes[i].name == _name) {
					answer = _object.attributes[i].value;
				}
			}
		}
	}
	return answer;
}

function hasProperties(_object) {
	try { for (var k in _object) throw(null); throw('empty') }
    catch(e) { if (e) return false; }
    return true;
}


/*
=====================================================
Stylesheet Functions
=====================================================
*/

function appendCSSRule(stylesheet, _selector, _rule) {
	if (stylesheet.cssRules) {
		return stylesheet.insertRule(_selector + ' { ' + _rule + ' }', stylesheet.cssRules.length);
	} else if (stylesheet.rules) {
		return stylesheet.addRule(_selector, _rule, stylesheet.rules.length);
	}
}

function replaceCSSRule(stylesheet, _selector, _rule) {
	deleteCSSRule(stylesheet, _selector);
	return appendCSSRule(stylesheet, _selector, _rule);
}

function deleteCSSRule(stylesheet, _selector) {
	var cssRuleIndex = findCSSRuleIndex(stylesheet, _selector);
	if (cssRuleIndex) {
		if (stylesheet.deleteRule) {
			stylesheet.deleteRule(cssRuleIndex);
		} else if (stylesheet.removeRule) {
			stylesheet.removeRule(cssRuleIndex);
		}
	}
}

function findCSSRuleIndex(stylesheet, _selector) {
	var cssRuleIndex;
	if (stylesheet.cssRules) {
		for (var c = 0; c < stylesheet.cssRules.length; c++) {
			if (stylesheet.cssRules[c].selectorText == _selector) {
				cssRuleIndex = c;
			}
		}
	} else if (stylesheet.rules) {
		for (var c = 0; c < stylesheet.rules.length; c++) {
			var rule = stylesheet.rules[c];
			if (stylesheet.rules[c].selectorText == _selector) {
				cssRuleIndex = c;
			}
		}
	}
	return cssRuleIndex;
}

function findStyleSheet(_styleSheetName) {
	if (document.styleSheets) {
		var stylesheet;
		for (var s = 0; s < document.styleSheets.length; s++) {
			if (document.styleSheets[s].href) {
				var tmpArray = document.styleSheets[s].href.match(/(\w+.css)$/);
				if (tmpArray && (tmpArray[1] == _styleSheetName)) {
					stylesheet = s;
				}
			}
		}
		return document.styleSheets[stylesheet];
	} else {
		alert('This browser does not support DOM stylesheets.');
	}
}


/*
=====================================================
Field Checking
=====================================================
*/

function checkInt(e, _field, _param) {
	var echar = String.fromCharCode(e.which);
	var value = _field.value.replace(/\D+/g, '');
	value = Number(value);
	var fix = false;
	if (e.keyCode == 38) {
		value = value + 1; fix = true;
	} else if (e.keyCode == 40) {
		value = value - 1; fix = true;
	} else if (e.keyCode == 33) {
		value = value + 10; fix = true;
	} else if (e.keyCode == 34) {
		value = value - 10; fix = true;
	} else if (e.keyCode == 36) {
		value = value + 100; fix = true;
	} else if (e.keyCode == 35) {
		value = value - 100; fix = true;
	}
	if (fix) {
		if (_param) {
			if (_param.min && (value < _param.min)) { value = _param.min; }
			else if (_param.max && (value > _param.max)) { value = _param.max; }
		}
		_field.value = value;
	}
}


/*
=====================================================
Subscription Manager
=====================================================
*/

function testSubscription() {
	alert("got here");
	var source_url = document.window_form.source_url.value;
	alert(source_url);
}
