//*************
//* common.js *
//*************
//
// Purpose: Contains function to handle several things common
//
// Dependancies:
//		yui/yahoo-dom-event.js
//		yui/animation.js
//		style.css
//
if ( typeof(djo) == 'undefined' ) {
	var djo = {};
}

//**************
// assocMatrix *
//**************
//
// Purpose:
djo.assocMatrix = function(formEle) {
	var inArr = new Array(); //array of incoming record data
	var exArr = new Array(); // array of existing data
	this.fieldMaskArr = []; // array field masks, by recordtypeid
	this.fieldOrderArr = []; // array of field order lists by recordtypeid
	this.loadBoxArr = []; //array of loader objects on the page
	var accessId = -1;
	var accessWhich = {};
	var accessMode = "in";
	var theMatrix = this;
	this.parentRecordId = -1; //record id of the parent, may be needed for access id
	this.formElement = formEle; // set with constructor ... the id of the form element to pass the data
	this.newRecordCounter = 0; // counter used by public when new record added
	this.onArrayUpdate=""; // can be set externally to execute on php_array_build

	this.append_loadbox_array = function(obj) {//adds an object to the loadBox array
		this.loadBoxArr[this.loadBoxArr.length] = obj;
	}

	this.append_record_array = function( recType, recId, datArr, whichAr ) {//adds a record to a record array
		var tmpCounter = 0;
		if ( !whichAr ) whichAr = 'in';
		if ( (recId+'').substring(0,3)=='NEW' ) {
			tmpCounter = (recId+'').substring(3,20)*1;
			this.newRecordCounter = (tmpCounter>this.newRecordCounter?tmpCounter:this.newRecordCounter);//ensure that newRecordCounter is the highest value
		}
		if ( whichAr == 'in' ) {
			if ( !inArr[recType] ) inArr[recType] = [];
			inArr[recType][recId] = datArr;
		} else {
			if ( !exArr[recType] ) exArr[recType] = [];
			exArr[recType][recId] = datArr;
		}
	}

	this.build_php_array = function() { // builds the PHP-ready string for the submit page
		if ( !document.getElementById(this.formElement) ) return; //if form not yet set, nothing to update!
		var outStr = '';//set the out string to blank
		for ( var i in inArr ) {//work throught the inArr
			if(typeof(inArr[i])=='function') continue;//if this is an function, skip it
			if ( !this.fieldOrderArr[i].length ) continue; //if no fieldorderlist, no data move on
			outStr += '$assocArr[\''+i+'\']=Array(';//start the assocArr for this item
			var recCounter = 0;//set the counter to 0
			var recArr = inArr[i];//get the array from the inArr
			for ( var z in recArr ) {//for each of the record array vars
				if(typeof(recArr[z])=='function') continue;//if this is an function, skip it
				outStr += ((recCounter>0)?',':'')+'"'+z+'"=>Array(';//add the array element to the out string
				outStr += '"fieldOrderList"=>"'+this.fieldOrderArr[i]+'"';//add the field order list to the outstring
				for ( var y in recArr[z] ) {//for each of the rec Arr elements
					if(typeof(recArr[z][y])=='function') continue;//if this is an function, skip it
					outStr += ',"'+y+'"=>"'+(recArr[z][y]+'').replace(/"/g,'".chr(34)."')+'"';//add the inner elements to the outstring, replacing quotes
				}
				recCounter++;//iterate the counter
				outStr += ')';//finish the array of elements
			}
			outStr+=');';//finish the array
		}
		document.getElementById(this.formElement).value=outStr;//get the form element value and set it to outStr
		if ( this.onArrayUpdate.length ) eval( this.onArrayUpdate );//if there is length to the onArrayUpdate JS, eval the JS
	}

	function record_type_str_to_id(str) {//get the record type id based on it's string
		if (str == 'company') return 1;
		if (str == 'person') return 2;
		if (str == 'thing') return 3;
		if (str == 'article') return 4;
		if (str == 'prospect') return 5;
		if (str == 'image') return 6;
		if (str == 'statistic') return 8;
		if (str == 'filing') return 9;
	}

	function assoc_name(arr) { // private helper function returns the needed name for the record
		var nam = '????';
		if ( arr['lastname_9999'] || arr['firstname_9999'] ) { // PERSON !!!!
			lnam = arr['lastname_9999']?arr['lastname_9999']:'????';
			fnam = arr['firstname_9999']?arr['firstname_9999']:'????';
			nam = lnam +', '+fnam;
			if ( arr['middlename_9999'] && arr['middlename_9999'].length ) {
				nam += ' '+arr['middlename_9999'];
			}
		} else if ( arr['company_9999'] ) { // COMPANY !!!!
			nam = arr['company_9999'];
		} else if ( arr['prospectlast_9999'] && arr["prospectfirst_9999"] && arr["prospectlast_9999"].length
			&& arr["prospectfirst_9999"].length ) {
			nam = arr["prospectfirst_9999"]+" "+arr["prospectlast_9999"];
		} else if ( arr["prospectemail_9999"] && arr["prospectemail_9999"].length ) {
			nam = arr["prospectemail_9999"];
		} else if ( arr["prospectfax_9999"] && arr["prospectfax_9999"].length ) {
			nam = arr["prospectfax_9999"];
		} else if ( arr["imagename_9999"] && arr["imagename_9999"].length ) {
			nam = arr["imagename_9999"];
		}  else if ( arr["thing_9999"] && arr["thing_9999"].length ) {
			nam = arr["thing_9999"];
		} else {
			nam = '';
			var count = 0;
			for ( var a in arr ) {
				if ( !(arr[a]+'').length || a == 'id' || a == 'image_9999' ) continue;
				if ( count > 3 ) break;
				nam += arr[a] + ';';
				count++;
			}
			if ( !nam.length ) nam = '????';
		}
		return nam;
	}

	this.disable_all = function(which, disable) {//disables all of the fields in an association block
		var recTypeId = record_type_str_to_id(which.recordType);//get the record type id
		var datArr = starter_array(recTypeId, which);//get the starter array
		for ( var x in datArr ) {//for each element in the starter array
			if(typeof(datArr[x])=='function') continue;//if this is an function, skip it
			tgt = document.getElementById(which.el.id +'-'+x);//get the target element
			if ( !tgt ) continue;//if it's not there, skip it
			existTgt = document.getElementById(which.el.id +'-'+x+'~currentValue'); //existing data for sub process

			YAHOO.util.Event.removeListener(tgt,"keyup"); // remove any keyup listeners from the target so the listeners do not get stacked!

			if ( tgt.tagName != 'INPUT' && tgt.tagName != 'TEXTAREA' && tgt.tagName != 'SELECT' ) { // unusual input types ...
				if ( tgt.tagName == 'DIV' ) {//if it's a div
					if ( YAHOO.util.Dom.hasClass(tgt, 'djoBoolean') || YAHOO.util.Dom.hasClass(tgt, 'djoValueList') ) {//if it's a bool or value list
						valueListArr[tgt.id].setDisabled(true);//call the set disabled on the object
					} else if ( YAHOO.util.Dom.hasClass(tgt, 'djoImagePreview') ) {//if this is a djoImagePreview
						tmpULId = tgt.id.replace('image_9999','')+'SubmitImgDiv';
						if(djoUpArr[tmpULId] && djoUpArr[tmpULId].disable){
							djoUpArr[tmpULId].disable();//disable the image upload controls
						}

						tgt.innerHTML = '';//set the inner html to blank
						tgt.style.display = '';//set the display to blank
					}  else if ( YAHOO.util.Dom.hasClass(tgt,'djoDateTime') ) {//if it's a datetime
						djoDtArr[tgt.id].set_disabled(true);//set the object to disabled
					}
				}
			} else {//else it's a normal input
				tgt.value = which.innerSelect?"Click NEW!":"";//set the value to "Click NEW!"
				tgt.disabled = true;//set the input to disabled
			}
		}
		return;//return
	}

	this.select = function(which) {// method used when an association is selected from the association box (including new assoc. creation)
		if ( !which.el.value ) {//if there is no value
			this.disable_all(which, true);//disable all the controls
			return;//return
		}

		var qArr = new Array();//create the qArr
		var tgt;//create the target
		var datArr = [];//create the data array
		var datArr2 = false; // array of existArr data, if applicable
		var recTypeId = record_type_str_to_id(which.recordType);//get the record type id
		if (!inArr[recTypeId]) inArr[recTypeId] = [];//if the record type is not in the inArr, add it, set it to an empty array
		datArr = inArr[recTypeId][which.el.value];//set the dat arr to the inArr, record type id, with the which.el.value
		if ( exArr[recTypeId] ) {//if the record typeid exists in the exArr
			datArr2 = exArr[recTypeId][which.el.value];//add it to the datArr2
		}

		if ( !datArr && which.innerSelect ) { // PUBLIC SIDE add new record
			inArr[recTypeId][which.el.value] = starter_array(recTypeId, which);//get the starter array and set it as the value for the element
			datArr = starter_array(recTypeId, which);//set the starter array as the dat arr
			which.getLi(which.el.value).text = assoc_name(datArr);//set the name of the li to the assoc_name in the datArr
		} else if ( !datArr && this.accessId != which.el.value ) {
			//ajax call on id that has no place in the array

			accessId = which.el.value;//set the access id to the value
			accessWhich = which; // set the active object for the connection
			accessMode = "in";//set the access mode to in
			this.access_id();//call the access id method
		}
		for ( var x in datArr ) {//for each element in the dat array
			if(typeof(datArr[x])=='function') continue;//if this is an function, skip it
			tgt = document.getElementById(which.el.id +'-'+x);//get the target
			existTgt = document.getElementById(which.el.id +'-'+x+'~currentValue'); //existing data for sub process

			if ( tgt ) {//if the target is there
				if ( YAHOO.util.Dom.hasClass(tgt, "retro") ) {//if it's a retro
					var theEle = document.getElementById(which.el.id +'-'+x+'_on');
					if ( datArr[x].length>0 ) {
						YAHOO.util.Dom.addClass(theEle, "checked");
					} else {
						YAHOO.util.Dom.removeClass(theEle, "checked");
					}
					theEle.onclick();
				} else if ( YAHOO.util.Dom.hasClass(tgt, "footnotetext") ) {//if it's a footnote
					var theEle = document.getElementById(which.el.id +'-'+x+'_on');
					if ( datArr[x].length>0 ) {
						YAHOO.util.Dom.addClass(theEle, "checked");
					} else {
						YAHOO.util.Dom.removeClass(theEle, "checked");
					}
					theEle.onclick();
				}

				if ( tgt.tagName != 'INPUT' && tgt.tagName != 'TEXTAREA' ) { // unusual input types ...
					if ( tgt.tagName == 'DIV' ) {//if it's a div
						if ( YAHOO.util.Dom.hasClass(tgt,'djoBoolean') || YAHOO.util.Dom.hasClass(tgt,'djoValueList') ) {//if it's a bool or value list
							var subArr = tgt.getElementsByTagName('input');
							for ( var sa in subArr ) {
								if(typeof(subArr[sa])=='function') continue;//if this is an function, skip it
								YAHOO.util.Event.removeListener(subArr[sa],"change");
								YAHOO.util.Event.addListener(subArr[sa],"change",this.update,subArr[sa].onchange,which,false);
							}
							valueListArr[tgt.id].selectList(datArr[x]);
						} else if ( YAHOO.util.Dom.hasClass(tgt,'djoDateTime') ) {//if it's a date time
							djoDtArr[tgt.id].set_disabled(false);
							djoDtArr[tgt.id].select_value(datArr[x]);
							YAHOO.util.Event.removeListener(djoDtArr[tgt.id].mmEle,"change");// remove all listeners on change -- val is updated through update
							YAHOO.util.Event.removeListener(djoDtArr[tgt.id].ddEle,"change");
							YAHOO.util.Event.removeListener(djoDtArr[tgt.id].yyEle,"change");
							YAHOO.util.Event.addListener(djoDtArr[tgt.id].mmEle,"change",this.update,djoDtArr[tgt.id].mmEle.onchange,which,false);
							YAHOO.util.Event.addListener(djoDtArr[tgt.id].ddEle,"change",this.update,djoDtArr[tgt.id].ddEle.onchange,which,false);
							YAHOO.util.Event.addListener(djoDtArr[tgt.id].yyEle,"change",this.update,djoDtArr[tgt.id].yyEle.onchange,which,false);

						} else if ( YAHOO.util.Dom.hasClass(tgt, 'djoImagePreview') ) {//if it's an image
							if ( top.frames['iManager'] ) {//if there is a frame->iManager, this is viewd in the admin tool
								if(YAHOO.util.Dom.hasClass(which.getLi(which.getSelectedId()),'isNew')){
									top.changeManagerBodyURL('/dj4/mgr_record.php?recordType=6&action=preview&imageId='+which.el.value);//init the transfer
								}
							}else{//public side
								djoUpArr[tgt.id.replace('image_9999','SubmitImgDiv')].upEv.unsubscribe(this.update_image);//unsubscribe to the event
								djoUpArr[tgt.id.replace('image_9999','SubmitImgDiv')].upEv.subscribe(this.update_image,which);//subscribe to the event

								//set upload controls
								djoUpArr[tgt.id.replace('image_9999','SubmitImgDiv')].reset();//reset the image upload controls
								if(which.el.value.toString().search('NEW') != -1){//if this is a new element
									djoUpArr[tgt.id.replace('image_9999','SubmitImgDiv')].enable();//enable the image upload controls
									tgt.innerHTML = "<br><br>&nbsp;&nbsp;No Image Uploaded";
								}else{//this is an existing element
									djoUpArr[tgt.id.replace('image_9999','SubmitImgDiv')].disable();//reset the image upload controls
								}
							}

							//update preview image if available
							if(datArr[x]){//if there is a path value for the image
								imgId = tgt.id.replace('image_9999','imgPrev');
								tgt.innerHTML = '<image src="'+datArr[x]+'" id="'+imgId+'" />';//update the image preview
								//set the delay to fix the image size
								setTimeout('djo.adjust_preview_size("'+imgId+'",70,130)',500);
							}
						}
					} else if ( tgt.tagName == 'SELECT' ) {
						YAHOO.util.Event.removeListener(tgt,"change");
						tgt.selectedIndex = -1;
						for ( var sX=0; sX<tgt.length; sX++ ) {
							if ( tgt.options[sX].value == datArr[x] ) {
								tgt.selectedIndex = sX;
								break;
							}
						}
						tgt.disabled = false;
					}
				} else if ( document.getElementById(tgt.id+'~locked') ) {
					document.getElementById(tgt.id+'~locked').innerHTML = datArr[x]?datArr[x]:"&mdash;";
				} else {
					tgt.disabled = false;
					if ( (datArr[x]+'').indexOf('$~')!=-1 ) {
						datArr[x] = datArr[x].split('$~')[0];
					}
					tgt.value = datArr[x];
				}

				if ( existTgt ) { // existing data for submissions
					if ( datArr2 && x != 'image_9999' ) {
						if ( !datArr2[x] && datArr[x].length ) { //if the incoming has data but no data in exist ...
							datArr2[x] = '<i>No data</i>';
						}
						if ( datArr2[x] && datArr2[x] != datArr[x] ) {
							existTgt.innerHTML = '<b>Currently:</b><br />' + datArr2[x]; // set the exist data, if applicable
							existTgt.style.display='block';
							YAHOO.util.Dom.addClass(tgt, "isAltered");
						} else {
							existTgt.style.display='none';
							YAHOO.util.Dom.removeClass(tgt, "isAltered");
						}
					} else {
						YAHOO.util.Dom.removeClass(tgt, "isAltered");
						existTgt.style.display='none';
					}
				}
				if ( tgt.tagName == 'SELECT' ) { //took out "which.innerSelect || " so public side also blur (safe than change)
					YAHOO.util.Event.removeListener(tgt,'change'); // so the listeners do not get stacked!
					YAHOO.util.Event.addListener(tgt,'change',this.update,tgt.onchange,which,false);
				} else { //changed from keyup to blur, to ensure cut/paste with mouse click captured
					YAHOO.util.Event.removeListener(tgt,'blur'); // so the listeners do not get stacked!
					YAHOO.util.Event.addListener(tgt,'blur',this.update,tgt.onblur,which,false);
				}

			}
		}
	}

	this.access_id = function() {
		var id = accessId;//set the id
		var recTypeId = record_type_str_to_id(accessWhich.recordType);//get the record type id
		//make an ajax call to con_record_detials
		var transaction = YAHOO.util.Connect.asyncRequest('GET', 'con_record_details.php?accessid='+id+'&theId='+this.parentRecordId+'&rectype='+accessWhich.recordType+'&yr=<?= $projYr ?>&mask='+this.fieldMaskArr[recTypeId], this.accessCallback);
	}

	this.accessHandle = function(o){//ajax handler for the access id ajax call
		if( o.status == 200 && o.responseText !== undefined){//if it was successful
			var arr = top.explode_with_key(o.responseText);//explode the response
			var recTypeId = record_type_str_to_id(accessWhich.recordType);//get the record type id
			if ( accessMode == "ex" ) { //if ex mode (process submission)
				if ( !exArr[recTypeId] ) exArr[recTypeId] = []; //ensure record type arr exists
				if ( exArr[recTypeId][arr['id']] ) { //if the ex arr has already been built for this id, just flesh it out
					for ( var r in arr ) {//for each value in the array
						if ( !exArr[recTypeId][arr['id']][r] ) exArr[recTypeId][arr['id']][r] = arr[r];//if it exists in the exArr, set the value to the exArr
					}
				} else { //otherwise make the exArr equal to the ajax retrieved array
					exArr[recTypeId][arr['id']] = arr; // set the comparison data for the existing data array
				}
				if ( arr["image_9999"] ) inArr[recTypeId][arr['id']]["image_9999"] = arr["image_9999"];//if this is an image, set the value to the inArr

			} else {//if this isn't a submission
				if ( arr["image_9999"] && arr["imageSm"] ) {//if this is an image and there is a small image available
					arr["image_9999"] = arr["imageSm"];//set the small image to the image_9999
				}
				inArr[recTypeId][arr['id']] = arr;//set the array to the inArr
			}
			theMatrix.select(accessWhich);//select the item in the matrix
			theMatrix.build_php_array();//build the php array
		}
	}

	this.accessCallback = {
		success: theMatrix.accessHandle,
		failure: theMatrix.accessHandle
	}

	this.update = function(e,a,o) {//update event called on various events such as an input on-keypress
		var e = e || window.event;
		var tgtEle = e.target || e.srcElement;
		var qArr = new Array();
		var newQStr = '';
		//var theVal = '';
		var theVal = tgtEle.value;

		if ( tgtEle.getAttribute("type") == "radio" || tgtEle.getAttribute("type") == "checkbox" ) { // boolean, value list
			var fLoc = tgtEle.id.split("`")[0].split('-')[1];
			theVal = document.getElementById(tgtEle.id.split("`")[0]+'input').value; // this is the hidden element
		} else if ( tgtEle.className == 'djoMM' || tgtEle.className == 'djoDD' || tgtEle.className == 'djoYY' ) { //date/time field
			var fLoc = tgtEle.id.split("~")[0].split('-')[1];
			djoDtArr[tgtEle.id.split("~")[0]].set_value(); // for IE in case the listeners are out of order
			theVal = document.getElementById(tgtEle.id.split("~")[0]+'~value').value;
		} else if (tgtEle.id.indexOf('SubmitFile') != -1) {
			var fLoc = 'imagename_9999';
			theVal = theVal.split('\\');
			theVal = theVal[(theVal.length-1)];
		} else {
			var fLoc = tgtEle.id.split('-')[1]; // field loc to be updated
		}

		var recTypeId = record_type_str_to_id(this.recordType);

		inArr[recTypeId][this.el.value][fLoc]=theVal;

		var theName = assoc_name(inArr[recTypeId][this.el.value]);

		theMatrix.reset_name(this, this.el.value, theName);
		if (tgtEle.id.indexOf('SubmitFile') != -1) { //update the name box ...
			this.select(this.el.value);
		}
		for ( var x=0; x<theMatrix.loadBoxArr.length; x++ ) {
			var tmpObj = theMatrix.loadBoxArr[x];
			if ( tmpObj != this
				&& tmpObj.recordType == this.recordType
				&& tmpObj.getLi(this.el.value) ) {
				// if another association loader is of the same type ...
				theMatrix.reset_name(tmpObj, this.el.value, theName);
				if ( tmpObj.el.value == this.el.value ) {
					theMatrix.select(tmpObj); //if currently is accessing the same record select it to propogate the data
				}
			}
		}
		theMatrix.build_php_array();
	}
	this.update_image = function(e,a,o) {//update event called on various events such as an input on-keypress
		var recTypeId = record_type_str_to_id(this.recordType);//get the record type
		inArr[recTypeId][o.el.value]['image_9999']=a[0].value;//set the image_9999 value to the uploaded image path

		var theName = assoc_name(inArr[recTypeId][o.el.value]);//get theName by calling assoc_name
		if(theName == '????'){//if there is no name assigned
			var imgName = document.getElementById(a[0].djoUpId + '_djoFileName');//get the image upload name element
			if(imgName && imgName.innerHTML.length > 0){//if the element was found and there is length
				theName = imgName.innerHTML.split(' - ')[0].split('.')[0];//extract the base name
				inArr[recTypeId][o.el.value]['imagename_9999']=theName;//set the image_9999 value to the uploaded image path
				if(document.getElementById(a[0].djoUpId.replace('SubmitImgDiv','imagename_9999'))){//if there is an imagename_9999
					document.getElementById(a[0].djoUpId.replace('SubmitImgDiv','imagename_9999')).value = theName;//update the value
				}
			}
		}

		theMatrix.reset_name(o, o.el.value, theName);//reset the name

		for ( var x=0; x<theMatrix.loadBoxArr.length; x++ ) {
			var tmpObj = theMatrix.loadBoxArr[x];
			if ( tmpObj != o
				&& tmpObj.recordType == o.recordType
				&& tmpObj.getLi(o.el.value) ) {
				// if another association loader is of the same type ...
				theMatrix.reset_name(tmpObj, o.el.value, theName);
				if ( tmpObj.el.value == o.el.value ) {
					theMatrix.select(tmpObj); //if currently is accessing the same record select it to propogate the data
				}
			}
		}
		theMatrix.build_php_array();
	}

	this.reset_name = function(whichObj, whichVal, newName) {
		if ( whichObj.innerSelect ) {
			// select box
			whichObj.getLi(whichVal).text = newName;
		} else {
			whichObj.getLi(whichVal).innerHTML = newName;
		}
	}

	function starter_array(typ,which) {
		var mask = theMatrix.fieldMaskArr[typ].split('|');
		var newArr = new Array();
		var val = '';
		for ( var m=0; m<mask.length; m++ ) {
			val = '';
			if ( mask[m] == 'lastname_9999' || mask[m] == 'firstname_9999'
				|| mask[m] == 'company_9999' || mask[m] == 'thing_9999'
				|| mask[m] == 'prospectfirst_9999' || mask[m] == 'prospectlast_9999'
				|| mask[m] == 'prospectemail_9999' || mask[m] == 'prospectfax_9999') {
				val = '????';
			} else if ( which.el.value && mask[m] == 'image_9999' && !document.getElementById(which.el.id+"SubmitFile_"+which.el.value) ) {
			}
			newArr[mask[m]] = val;
		}
		return newArr;
	}

	this.reset_array_key = function(newId, which, type) { // reset id from NEW to valid db id
		if ( !newId ) return; // if no value loaded, do nothing!
		var oldId = which.el.value;
		if ( oldId == newId || (oldId+'').substring(0,3) != 'NEW' ) return true; //if no change or not a NEW record, do nothing!
		if ( which.getLi(newId) ) {
			top.changeMsg("Record has already been association to this field!", 3);
			return true;
		}
		if ( !top.frames["iManager"].document.getElementById(which.recordType+"LB") ) {
			return true; // record being loaded is not of the right type
		}
		var tmpLi = which.getLi(oldId);
		var txt = which.getLi(oldId).innerHTML;
		which.updateItem(txt, newId);
		which.set_input();
		accessId = newId;
		accessWhich = which; // set the active object for the connection
		accessMode = "ex"; // grab the array for the EXISTING data
		this.access_id(); // ajax call to grab the data array for the association
		if ( !inArr[type][newId] ) { //if the inArr doesn't already exist for this id, set it to the NEW[] arr
			inArr[type][newId] = inArr[type][oldId];
		} else { //otherwise append the NEW[] values to existing inArr for the loaded id
			for ( var r in inArr[type][oldId] ) {
				if ( !inArr[type][newId][r] ) inArr[type][newId][r] = inArr[type][oldId][r];
			}
		}

		tmpLi.setAttribute("name",oldId);
		YAHOO.util.Dom.removeClass(tmpLi,'isNew');
		YAHOO.util.Dom.addClass(tmpLi,'semiNew');
		return false;
	}

	this.reset_to_new = function(which, type) { // function to reset an associated record from valid to NEW
		var tmpLi = which.getLi(which.el.value);
		if ( !YAHOO.util.Dom.hasClass(tmpLi,'semiNew') ) return true; // go ahead and upload the item
		YAHOO.util.Dom.addClass(tmpLi,'isNew');
		YAHOO.util.Dom.removeClass(tmpLi,'semiNew');
		var txt = which.getLi(which.el.value).innerHTML;
		var oldId = tmpLi.getAttribute('name');
		if ( inArr[type][oldId]["image_9999"] ) inArr[type][oldId]["image_9999"] = "";
		which.updateItem(txt, oldId);
		which.select(which.el.value);
		return false;
	}

	this.update_data_pt = function(type, id, floc, val) {
		if(!inArr[type] || !inArr[type][id]) return;//test each part, if any are not true, just return
		inArr[type][id][floc] = val;

		var theName = assoc_name(inArr[type][id]);
		for ( var x=0; x<this.loadBoxArr.length; x++ ) {
			var tmpObj = this.loadBoxArr[x];
			if ( record_type_str_to_id(tmpObj.recordType) == type
				&& tmpObj.getLi(id) ) {
				// if another association loader is of the same type ...
				this.reset_name(tmpObj, id, theName);
				if ( tmpObj.el.value == id ) {
					this.select(tmpObj); //if currently is accessing the same record select it to propogate the data
				}
			}
		}
		this.build_php_array();
	}

	this.retrieve_data_pt = function(type, id, floc) {
		if ( !inArr[type] || !inArr[type][id] || !inArr[type][id][floc] ) return "";
		return inArr[type][id][floc];
	}
}

djo.imageUploader = function(whichId,attributes) {
	this.recordType = attributes.recordType;//set the record type
	this.el = document.getElementById(whichId);
	alert('imageUploader');
}

//***************
// quasiListBox *
//***************
//
// Purpose:
djo.quasiListBox = function(whichId, attributes) {
	this.recordType = attributes.recordType;
	this.el = document.getElementById(whichId);
	var tmpSelect = document.createElement('select');
	tmpSelect.setAttribute("size", 4);
	tmpSelect.className = "djo_selectbox";
	tmpSelect.id = whichId+"-selectbox";
	this.el.appendChild(tmpSelect);
	this.el.value = -1;
	this.innerSelect = tmpSelect;
	this.onChange = "";
	this.noDeleteArr = [];
	this.noDeleteMsg = 'This record cannot be deleted.';
	btnDiv = document.createElement("div");
	this.expanded = false;

	tmpNew = document.createElement("input");
	tmpNew.setAttribute("type", "button");
	tmpNew.id = whichId+"-djoNewBttn";
	tmpNew.className = "pubButton";
	tmpNew.setAttribute("value", "NEW");
	tmpNew.setAttribute("title", "NEW");
	tmpNew.className="djo_form_button tiny";

	tmpDel = document.createElement("input");
	tmpDel.setAttribute("type", "button");
	tmpDel.id = whichId+"-djoDelBttn";
	tmpDel.className = "pubButton";
	tmpDel.setAttribute("value", "DELETE");
	tmpDel.setAttribute("title", "DELETE");
	tmpDel.className="djo_form_button tiny";

	tmpExpand = document.createElement("input");
	tmpExpand.setAttribute("type", "button");
	tmpExpand.id = whichId+"-djoExpandBttn";
	tmpExpand.className = "pubButton";
	tmpExpand.setAttribute("value", "EXPAND");
	tmpExpand.setAttribute("title", "EXPAND");
	tmpExpand.className="djo_form_button tiny";

	tmpInput = document.createElement("input");
	tmpInput.setAttribute("type", "hidden");
	tmpInput.setAttribute("name", whichId);
	tmpInput.setAttribute("id", whichId+"inputValue");
	this.el.appendChild(tmpInput);
	this.inputEle = document.getElementById(whichId+"inputValue");

	btnDiv.appendChild(tmpNew);
	btnDiv.appendChild(tmpDel);
	btnDiv.appendChild(tmpExpand);
	this.el.appendChild(btnDiv);

	this.selectbox = document.getElementById(whichId+"-selectbox");
	this.newButton = document.getElementById(whichId+"-djoNewBttn");
	this.delButton = document.getElementById(whichId+"-djoDelBttn");
	this.expandButton = document.getElementById(whichId+"-djoExpandBttn");



	// //,this,false);
	this.setInput = function() {
		var str = "";
		for ( var s=0; s<this.innerSelect.length; s++ ) {
			str+=(str.length?"|":"") + this.innerSelect.options[s].value;
		}
		this.inputEle.setAttribute("value", str);
	}

	this.addItem = function() {
		var sCount = this.innerSelect.length;
		assocMaster.newRecordCounter++;
		var newId = "NEW"+assocMaster.newRecordCounter;
		this.innerSelect.options[sCount] = new Option("New record", newId);
		this.innerSelect.selectedIndex = sCount;
		this.select();
		this.expandBox(true);
	}

	this.deleteItem = function() {
		if ( !this.innerSelect.length || this.innerSelect.selectedIndex == -1 ) return;
		if ( this.noDeleteArr[this.el.value+""] ) { alert(this.noDeleteMsg); return; }
		//var delVal = this.innerSelect.options[this.innerSelect.selectedIndex].value;
		this.innerSelect.options[this.innerSelect.selectedIndex] = null;
		var imgBrowseInput = document.getElementById(this.el.id+"SubmitFile_"+this.el.value);
		if ( imgBrowseInput ) {
			imgBrowseInput.style.display='none'; ///hides the browseelement
		}
		if ( this.innerSelect.length ) this.innerSelect.selectedIndex = 0;
		this.select();
		this.expandBox(true);
	}

	this.expandBox = function(changeEvent) {
		theHeight = 54;//set default height
		theTime = 0;//set default anamation time

		//calculate selectbox height
		if((changeEvent==true && this.expanded) || (changeEvent!=true && !this.expanded)){//if this is a change event and it is expanded or is not a change event and is not expanded, expand the box
			if(this.selectbox.length){
				theHeight = (this.selectbox.length * 13) + 2;//set the height at elements x 13 plus 2 pixels
			}
			theHeight = theHeight<93?93:theHeight;//min out at 93px
			theHeight = theHeight>301?301:theHeight;//max out at 301px
			this.expanded = true;//set expanded to true
		}else{//collapse the box
			this.expanded = false;//set expanded to false
		}

		//calculate animation time
		if(changeEvent!=true){//if this was not a change event
			theTime = Math.sqrt(Math.abs(this.selectbox.offsetHeight - theHeight)) * .07;//calculate the time on a sliding scale 0.437 - 1.1 seconds
		}

		//animate the selectbox
		boxAnim = new YAHOO.util.Anim(this.selectbox, {
				height: { to: theHeight }
			}, theTime, YAHOO.util.Easing.easeOut);

		this.expandButton.setAttribute("value",(this.expanded?'COLLAPSE':'EXPAND'));
		boxAnim.animate();
	}

	YAHOO.util.Event.addListener(this.newButton,"click",this.addItem,this,true);
	YAHOO.util.Event.addListener(this.delButton,"click",this.deleteItem,this,true);
	YAHOO.util.Event.addListener(this.expandButton,"click",this.expandBox,this,true);

	this.addItems = function(arr) {
		var sCount = 0;
		if ( !arr || !arr.length ) return;
		for (var x in arr) {
			if(typeof(arr[x])=='function') continue;
			var attr = arr[x]; // an object
			this.innerSelect.options[sCount] = new Option(attr.text, attr.value);
			sCount++;
		}
		this.el.value = this.innerSelect.options[0].value;
		this.innerSelect.selectedIndex = 0;
		this.select(); //ensure that the first element is highlighted, executing select in the matrix
		this.expandBox(true);
	}

	this.setOnChange = function(action) {
		YAHOO.util.Event.addListener(this.innerSelect,"change",this.select,this.innerSelect,this,false);
		this.onChange = action;
	}

	this.select = function() {
		if ( this.innerSelect.length ) {
			this.el.value = this.innerSelect.options[this.innerSelect.selectedIndex].value;
		} else {
			this.el.value = "";
		}
		eval(this.onChange);
		this.setInput();
	}

	this.getLi = function(val) {
		for ( var x=0; x<this.innerSelect.length; x++ ) {
			if ( this.innerSelect.options[x].value == val ) {
				return this.innerSelect.options[x];
			}
		}
		return false;
	}

	this.length = function() {
		return this.innerSelect.length;
	}

	this.setNoDelete = function(id) {
		this.noDeleteArr[id] = true;
	}
}

//***********
// dateTime *
//***********
//
// Purpose: Create a date time field
djo.dateTime = function(divId, attributes) {
	if (!attributes) attributes = {};
	var theEle = document.getElementById(divId);
	var tmpMM = document.createElement("select");
	tmpMM.className = 'djoMM';
	tmpMM.setAttribute("id", divId+'~month');
	tmpMM.options[0] = new Option('', '');
	tmpMM.options[1] = new Option('January', 1);
	tmpMM.options[2] = new Option('February', 2);
	tmpMM.options[3] = new Option('March', 3);
	tmpMM.options[4] = new Option('April', 4);
	tmpMM.options[5] = new Option('May', 5);
	tmpMM.options[6] = new Option('June', 6);
	tmpMM.options[7] = new Option('July', 7);
	tmpMM.options[8] = new Option('August', 8);
	tmpMM.options[9] = new Option('September', 9);
	tmpMM.options[10] = new Option('October', 10);
	tmpMM.options[11] = new Option('November', 11);
	tmpMM.options[12] = new Option('December', 12);
	var tmpDD = document.createElement("select");
	tmpDD.options[0] = new Option('', '');
	for ( var dd=1; dd<=31; dd++ ) {
		tmpDD.options[dd] = new Option(dd, dd);
	}
	tmpDD.className = 'djoDD';
	tmpDD.setAttribute("id", divId+'~day');

	var yrSelectArr = [];
	var tmpYY ={};
	if ( attributes.yrArr && attributes.yrArr.length ) {
		//tmpYY.setAttribute("type","hidden");
		tmpYY = document.createElement("select");
		for ( var yy=0; yy<attributes.yrArr.length; yy++ ) {
			tmpYY.options[yy] = new Option(attributes.yrArr[yy],attributes.yrArr[yy]);
			yrSelectArr[attributes.yrArr[yy]] = yy;
		}
		tmpYY.className = 'djoYY';
		//tmpYYsel.setAttribute("onchange","document.getElementById('"+divId+"~year').value = this.value");
		//YAHOO.util.Event.addListener(tmpYYsel,"change",this.set_value,this,true);
	} else {
		tmpYY = document.createElement("input");
		tmpYY.setAttribute("type", "text");
		tmpYY.className = 'djoYY';
		tmpYY.setAttribute("onkeypress", "return force_integer(event);");
		tmpYY.setAttribute("maxlength", 4);
	}
	tmpYY.setAttribute("id", divId+'~year');
	var tmpVal = document.createElement("input");
	tmpVal.setAttribute("id", divId+'~value');
	tmpVal.setAttribute("type", "hidden");
	tmpVal.setAttribute("name", divId);
	if ( YAHOO.util.Dom.hasClass(theEle, 'required') ) { //if the parent div has the required class, add it to the input so it is picked up by the reqArr
		YAHOO.util.Dom.addClass( tmpVal, 'required' );
		tmpVal.setAttribute("text", theEle.getAttribute("text"));
	}
	this.valueEle = tmpVal;
	this.mmEle = tmpMM;
	this.ddEle = tmpDD;
	this.yyEle = tmpYY;
	this.onChangeJs = '';
	this.eleId = divId;
	this.yrSelectArr = yrSelectArr;
	this.valStyle = attributes.valStyle?attributes.valStyle:'M/D/YYYY';

	if ( this.valStyle.indexOf('D') == -1 ) {
		this.ddEle.style.display = 'none'; //hide the day element
	}

	this.set_value = function() {
		if ( this.valStyle == 'YYYYMM' ) {
			var mm = this.mmEle.options[this.mmEle.selectedIndex].value;
			if ( (mm+'').length == 1 ) mm = '0'+mm;
			var val = this.yyEle.value+mm;
		} else {
			var val = this.mmEle.options[this.mmEle.selectedIndex].value + '/' + this.ddEle.options[this.ddEle.selectedIndex].value	+ ((this.yyEle.value+'').length?'/'+this.yyEle.value:'');
		}
		this.valueEle.value = val=='/'?'':val;
		if ( this.onChangeJs.length ) {
			eval(this.onChangeJs);
		}
	}

	this.select_value = function(theVal) {
		if ( this.valStyle == 'YYYYMM' ) {
			theVal = theVal+'';//convert to string
			var mm = theVal.substring(4,6)+'';
			if (mm.substring(0,1) == '0') mm = mm.substring(1);
			theVal = mm+'/1/'+theVal.substring(0,4);
		}
		var dtArr = (theVal+'').split('/');
		this.mmEle.selectedIndex = 0;
		this.ddEle.selectedIndex = 0;
		this.yyEle.value = "";
		for ( var x=0; x<this.mmEle.length; x++ ) { if ( this.mmEle.options[x].value==dtArr[0] ) { this.mmEle.selectedIndex = x; break; }}
		for ( x=0; x<this.ddEle.length; x++ ) { if ( this.ddEle.options[x].value==dtArr[1] ) { this.ddEle.selectedIndex = x; break; }}
		if ( dtArr[2] ) {
			if ( this.yrSelectArr.length ) {
				this.yyEle.selectedIndex = this.yrSelectArr[dtArr[2]];
			} else {
				this.yyEle.value = dtArr[2];
			}
		}
		this.set_value();
	}

	this.set_onChange = function(str) {
		this.onChangeJs = str;
	}

	this.set_disabled = function(mod) {
		this.mmEle.disabled = mod;
		this.ddEle.disabled = mod;
		this.yyEle.disabled = mod;
		this.select_value("");
	}

	YAHOO.util.Event.addListener(tmpMM,"change",this.set_value,this,true);
	YAHOO.util.Event.addListener(tmpDD,"change",this.set_value,this,true);
	YAHOO.util.Event.addListener(tmpYY,"change",this.set_value,this,true);

	theEle.appendChild(tmpMM);
	theEle.appendChild(tmpDD);
	theEle.appendChild(tmpYY);
	theEle.appendChild(tmpVal);
}

//************
// valueList *
//************
//
// Purpose: Create a value list field
djo.valueList = function(divId, attributes) {
	var theEle = document.getElementById(divId);
	this.isHierarchy = false;
	var thisVL = this;
	if(!theEle){
		return false;
	}
	this.theEle = theEle;
	var dataStr = theEle.getAttribute("name");
	var tmpArr = explode_with_key(dataStr);
	var dataArr = [];
	var dataCount = 0;
	for ( var i in tmpArr ) {
		if(typeof(tmpArr[i])=='function') continue;
		dataArr[dataCount] = [];
		var dValArr = (i+'').split('`');
		dataArr[dataCount]["VALUE"] = dValArr[0];
		dataArr[dataCount]["NAME"] = (tmpArr[i]+'').split('`')[0];
		dataArr[dataCount]["DEPTH"] = dValArr.length>1&&dValArr[1]?dValArr[1]:0;
		dataCount++;
	}
	var parentEle = theEle.parentNode;
	var vlObj = this;
	var columnCount;

	if ( parentEle.offsetWidth > 400 ) {
		columnCount = 3;
	} else if ( parentEle.offsetWidth > 250 ) {
		columnCount = 2;
	} else {
		columnCount = 1;
	}

	if ( !attributes ) attributes = {};
	this.attributes = attributes;
	if ( !this.attributes.depth ) this.attributes.depth = 0; // starts at depth 0
	this.deepValArr = []; //all available options inside hierarchy
	this.innerValArr = []; //inner checked off values
	if ( YAHOO.util.Dom.hasClass(theEle, 'djoHierarchy') ) {
		this.isHierarchy = true;
	}
	var tmpTbl = document.createElement("table");
	var tmpTbody = document.createElement("tbody");
	tmpTbl.setAttribute("id", divId+'tbl');
	var rowCount = Math.ceil(dataCount / columnCount);
	this.checkboxArr = [];
	this.activeTd = null;
	this.setHierarchy = function(e) {
		var e = e || window.event;
		var tgtEle = e.target || e.srcElement;
		this.buildHierarchy(tgtEle, false);
	}
	this.buildHierarchy = function(tgtEle, initStr) {
		var tgtTdId = tgtEle.getAttribute("name");
		var val = tgtEle.getAttribute("text");
		var tdEle = document.getElementById(tgtTdId);
		if ( this.activeTd !== null ) {
			this.clearActiveTd();
		}
		var wrapper = document.createElement('div');
		wrapper.className = 'vlInnerDiv depth'+(this.attributes.depth+1);
		var div = document.createElement('div');
		div.setAttribute('id', tgtTdId+'~div');
		var baseClass = this.attributes.radio?'djoBoolean':'djoValueList';
		YAHOO.util.Dom.addClass(div, baseClass+' djoHierarchy');
		this.activeTd = tgtEle;
		YAHOO.util.Dom.addClass(this.activeTd.parentNode, 'innerOn'+this.attributes.depth);
		div.setAttribute('name', this.deepValArr[tgtEle.id]);
		wrapper.appendChild(div);
		tdEle.appendChild(wrapper);
		var vl = new djo.valueList(div.id, {depth:this.attributes.depth+1, radio:this.attributes.radio} ); //increment the depth
		vl.parentVL = this;
		if ( initStr ) {
			var theVal = initStr; //initialize with the full value passed to the parent
		} else {
			var theVal = (this.innerValArr[val]?this.innerValArr[val]:""); //subsequent calls take only the applicable values
		}
		vl.onChangeAction = 'this.parentVL.innerValArr["'+val+'"] = this.inputEle.value;this.parentVL.buildInput();this.parentVL.labelInnerSelected("'+tgtEle.id+'~whichChecked", this.inputEle.value);';
		vl.selectList(theVal); //select the applicable values
		if ( !document.getElementById(this.theEle.id+'`'+val).checked ) {
			vl.setDisabled(true);
		} else {
			vl.setDisabled(false);
		}
	}

	this.labelInnerSelected = function(whichId, str) {
		var ele = document.getElementById(whichId);
		var len = (str+'').length?str.split('`').length:0;
		ele.innerHTML = len>0?'('+len+')':"";
	}

	this.clearActiveTd = function() {
		if ( !this.activeTd ) return;
		var tgtTdId = this.activeTd.getAttribute("name");
		var tdEle = document.getElementById(tgtTdId);
		YAHOO.util.Dom.removeClass(this.activeTd.parentNode, 'innerOn'+this.attributes.depth);
		//this.activeTd = null;
		if ( tdEle ) {
			while ( tdEle.childNodes.length ) { //remove all children elements
				tdEle.removeChild(tdEle.firstChild);
			}
		}
	}

	this.hierarchyInputClick = function() {
		labelEle = document.getElementById(this.getAttribute("text"));
		thisVL.buildHierarchy(labelEle,false);
	}

	this.buildInput = function() {
		if ( this ) {
			var tgtEle = this;
		} else {
			var tgtEle = {};
		}

		var str = "";
		var txt = "";

		if ( tgtEle.id && vlObj.attributes.radio ) {
			tgtEle.checked = (vlObj.inputEle.value==tgtEle.value)?false:true;
		}
		for ( var i in vlObj.checkboxArr ) {
			if(typeof(vlObj.checkboxArr[i])=='function') continue;
			if ( vlObj.attributes.radio && tgtEle.id && vlObj.checkboxArr[i].id != tgtEle.id ) {
				vlObj.checkboxArr[i].checked = false;
			}
			var val = vlObj.checkboxArr[i].checked?vlObj.checkboxArr[i].getAttribute("value"):"";
			if ( val.length ) {
				str += (str.length?"`":"")+val;
				if ( thisVL.innerValArr[val] && (thisVL.innerValArr[val]+'').length ) {
					str += "`"+thisVL.innerValArr[val];
				}
				if ( this.attributes.mode != 'submit' ) {
					txt += (txt.length?"`":"")+vlObj.checkboxArr[i].getAttribute("value");
				}
			}
		}
		vlObj.inputEle.value = str;
		vlObj.inputVal.value = txt;
		thisVL.doOnChange();
	}

	this.doOnChange = function() {
		if ( this.onChangeAction ) {
			eval( this.onChangeAction );
		}
	}

	var dIndex = 0;
	var tmpP = {};
	for ( var r=0; r<rowCount; r++ ) {
		var tmpTr = document.createElement('tr');
		tmpTr.setAttribute("id", divId+'tr'+r);
		for ( var c=0; c<columnCount; c++ ) {
			var tmpTd1 = document.createElement('td');
			var tmpTd2 = document.createElement('td');
			if ( dIndex < dataCount ) {
				var val = dataArr[dIndex]["VALUE"];
				var nam = dataArr[dIndex]["NAME"];
				var depth = dataArr[dIndex]["DEPTH"];

				//if ( this.isHierarchy ) {
				if ( depth*1 == this.attributes.depth*1 ) {
					tmpP = document.createElement('p');
					var tmpCB = document.createElement('input');
					tmpP.setAttribute("name", divId+'td'+r+'~hierarchy');
					tmpP.setAttribute("text", val);
					tmpP.setAttribute("id", divId+'_'+r+'_'+c);
					topValue = val;
				} else { //greater depth
					if ( !this.deepValArr[tmpP.id] ) {
						YAHOO.util.Event.addListener(tmpP,"click",this.setHierarchy,this,true);
						YAHOO.util.Event.addListener(tmpCB,"click",this.hierarchyInputClick,this,false);
						YAHOO.util.Dom.addClass(tmpP, 'vlHasDepth');
						YAHOO.util.Dom.addClass(tmpP, 'depth'+(this.attributes.depth+1));
						this.deepValArr[tmpP.id] = '';
						tmpP.innerHTML += ' <span id="'+tmpP.id+'~whichChecked"></span>';
					}
					this.deepValArr[tmpP.id] += (this.deepValArr[tmpP.id].length?'|':'') + val+'`'+depth+'=>'+nam;
					dIndex++;
					c--;
					continue;
				}
				if ( this.isHierarchy ) { //ensure that the hirerachy display is wiped out regardless of whether option has children
					YAHOO.util.Event.addListener(tmpCB,"click",this.clearActiveTd,this,true);
				}
				//}

				tmpCB.setAttribute("type", (attributes.radio?"radio":"checkbox") );

				tmpCB.setAttribute("value", (attributes.radio?val:nam));
				if ( this.attributes.mode != 'submit' ) {
					tmpCB.setAttribute("name", (attributes.radio?nam+'_'+divId:val));
				}
				tmpCB.id = divId+"`"+val;
				tmpCB.setAttribute("text", divId+'_'+r+'_'+c);
				YAHOO.util.Event.addListener(tmpCB,"click",this.buildInput,this,false);//this.

				this.checkboxArr[dIndex] = tmpCB;

				tmpP.innerHTML = nam;
				tmpTd1.appendChild(tmpCB);
				tmpTd1.setAttribute("class", "vlTd1");
				tmpTd2.appendChild(tmpP);
				tmpTd2.setAttribute("class", "vlTd2");
			}
			tmpTr.appendChild(tmpTd1);
			tmpTr.appendChild(tmpTd2);
			dIndex++;
		}
		tmpTbody.appendChild(tmpTr);
		if ( this.isHierarchy ) {
			var hTr = document.createElement('tr');
			var hTd = document.createElement('td');
			hTd.setAttribute('colspan',columnCount*2); //colspan * 2 b/c two tds per "cell"
			hTd.setAttribute('id', divId+'td'+r+'~hierarchy');
			hTr.appendChild(hTd);
			tmpTbody.appendChild(hTr);
		}

	}
	tmpTbl.appendChild(tmpTbody);
	theEle.appendChild(tmpTbl);

	this.inputEle = document.createElement('input');
	this.inputEle.setAttribute("type", "hidden"); // change to hidden
	this.inputEle.setAttribute("name", divId); // change to hidden
	this.inputEle.setAttribute("id", divId+'input'); // change to hidden

	if ( YAHOO.util.Dom.hasClass(theEle, 'required') ) { //if the parent div has the required class, add it to the input so it is picked up by the reqArr
		YAHOO.util.Dom.addClass( this.inputEle, 'required' );
		this.inputEle.setAttribute("text", theEle.getAttribute("text"));
	}

	this.inputVal = document.createElement('Value');
	this.inputVal.setAttribute("type", "hidden"); // change to hidden
	this.inputVal.setAttribute("name", divId+'Value'); // change to hidden
	this.inputVal.setAttribute("id", divId+'Value'); // change to hidden
	theEle.appendChild(this.inputEle);


	this.buildInput();

	this.selectList = function(str) {
		if ( !str.length ) {
			var selArr = [];
		} else {
			var selArr = str.split('`');
		}

		for ( var i in this.checkboxArr ) {
			if(typeof(this.checkboxArr[i])=='function') continue;
			this.checkboxArr[i].checked = false;
			this.checkboxArr[i].disabled = false; //undo disabled if applicable
			for ( var s=0; s<selArr.length; s++ ) {
				if ( !this.checkboxArr[i].value ) continue;
				//if ( this.attributes.mode == "submit" || this.attributes.radio ) {
				var nam = this.checkboxArr[i].getAttribute("value");
				//} else {
				//	var nam = this.checkboxArr[i].getAttribute("name");
				//}
				if ( nam == selArr[s] ) {
					this.checkboxArr[i].checked = true;
				}
			}
		}
		this.buildInput();
		if ( this.isHierarchy ) { //if hierarchy, instantiate all inner options as well...
			for ( var z in this.deepValArr ) {
				//alert( z );
				this.buildHierarchy( document.getElementById(z), str ); //initialize
			}
			this.clearActiveTd();
		}
	}

	this.setDisabled = function(mod) {
		mod = mod?true:false;
		for ( var i in this.checkboxArr ) {
			if(typeof(this.checkboxArr[i])=='function') continue;
			this.checkboxArr[i].disabled = mod;
			if ( mod ) this.checkboxArr[i].checked = false; //if setting disabled on, uncheck it
		}
	}

	this.setOnChange = function(which){
		alert(which);
	}

	function explode_with_key(str,inglue,outglue){//used to turn an imploded string back into an associative array
		// see implode_with_key() in djoFunctions.inc for the php version of the reverse
		inglue = (inglue)?inglue:'|';
		outglue = (outglue)?outglue:'=>';
		str = str.replace(/^\s+|\s+$/g, ''); //trim the string for trailing spaces, etc.
		str = str.replace(/&gt;/g,'>');
		var startArr = str.split(inglue);//splint on the inglue
		var retArr = [];
		for(var i in startArr){
			if(typeof(startArr[i])=='string'){
				var tempArr = startArr[i].split(outglue);//split on the outglue
				retArr[tempArr[0]] = tempArr[1];//assign the array value
			}
		}
		return retArr;
	}

}

//***********
// setRange *
//***********
//
// Purpose:
djo.setRange = function(which) {
	var outEle = document.getElementById(which);
	var lowValEle = document.getElementById(which+'~low');
	var highValEle = document.getElementById(which+'~high');
	var lowVal = lowValEle&&(lowValEle.value+'').length?'>='+(lowValEle.value+'').replace(/,/g,''):'';
	var highVal = highValEle&&(highValEle.value+'').length?'<='+(highValEle.value+'').replace(/,/g,''):'';
	var outVal = lowVal + (lowVal.length&&highVal.length?'|':'') + highVal;
	outEle.value = outVal;
}

//***************
// setDateRange *
//***************
//
// Purpose:
djo.setDateRange = function(whichId) {
	var outEle = document.getElementById(whichId);
	var lowValEle = document.getElementById(whichId+'~start~value');
	var highValEle = document.getElementById(whichId+'~end~value');
	var lowVal = lowValEle&&(lowValEle.value+'').length?'>'+lowValEle.value:'';
	var highVal = highValEle&&(highValEle.value+'').length?'<'+highValEle.value:'';
	var outVal = lowVal + (lowVal.length&&highVal.length?'|':'') + highVal;
	outEle.value = outVal;
}


//****************
// force_numeric *
//****************
//
// Purpose: force an input value to become numeric
function force_numeric(e) {
	var tgtEle = e.target || e.srcElement;
	var allowStr = "0123456789,";
	if ( tgtEle && tgtEle.value.indexOf(".") == -1 ) {
		allowStr += ".";
	}
	if ( tgtEle && tgtEle.value.indexOf("-") == -1 ) {
		allowStr += "-";
	}
	return restrict_input(e, allowStr);
}

//*******
// trim *
//*******
//
// Purpose: trim characters off the left and right of a string
function trim(str, chars) {
	return ltrim(rtrim(str, chars), chars);
}

//********
// ltrim *
//********
//
// Purpose: trim characters off the left of a string
function ltrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

//********
// rtrim *
//********
//
// Purpose: trim characters off the right of a string
function rtrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

//*******************
// validate_numeric *
//*******************
//
// Purpose: set the value of an input to it's numeric representation
function validate_numeric(which) {
	var val = which.value;
	if ( val.length ) {
		which.value = djo.format_number(val);
	}
}

//*******************
// valuelistUpgrade *
//*******************
//
// Purpose:
djo.valuelistUpgrade = function(divId, attributes) {
	this.theEle = document.getElementById(divId);
	this.divId = divId;
	var theUpgrade = this;
	if ( !attributes ) attributes = {};
	if ( !attributes.flgArr ) attributes.flgArr = [];//'Agribusiness`Technology`Manufacturer';
	if ( !attributes.valStr ) attributes.valStr = '';//'Agribusiness=>gold|Manufacturer=>silver';
	if ( !attributes.upgStr ) attributes.upgStr = '';//'gold=>500|silver=>250|bronze=>100|basic=>0';
	if ( !attributes.levelStr ) attributes.levelStr = '';//'gold=>500|silver=>250|bronze=>100|basic=>0';
	if ( !attributes.freeListings ) attributes.freeListings = 0;
	if ( !attributes.ppListing ) attributes.ppListing = '';//100;
	this.defaultUpg = '';
	this.attributes = attributes;
	//this.flgArr = attributes.flgStr.split('`');
	this.flgArr = attributes.flgArr; //incoming json
	this.valArr = explode_with_key(attributes.valStr);
	this.upgArr = explode_with_key(attributes.upgStr);
	this.levelArr = explode_with_key(attributes.levelStr);
	this.divCounter = 0;
	this.usedFlgArr = []; //flags already selected
	this.listSelectArr = []; // array of select elements
	this.totalPrice = 0;
	this.cartItemArr = [];
	this.theValue = "";
	this.dataValue = "";

	this.build_valArr = function() {
		var val = '';
		var val2 = '';
		for( var i in this.listSelectArr) {
			var sel = this.listSelectArr[i];
			var listVal = sel.options[sel.selectedIndex].value;
			if ( !listVal.length ) continue;
			val += (val.length?'|':'')+ listVal +'=>'+(this.valArr[listVal]?this.valArr[listVal]:this.defaultUpg);
			val2 += (val2.length?'`':'') + listVal;
		}
		this.valArr = []; //destroy the array
		this.valArr = explode_with_key(val);
		this.theValue = val;
		this.dataValue = val2;
	}

	this.changeSelect = function() {
		this.build_valArr();
		this.build_box();
	}

	this.listingSelect = function(val) {
		var tmpSelect = document.createElement('select');
		tmpSelect.id = this.divId+'~listingSelect~'+this.divCounter;
		tmpPrice = 0;
		if ( this.attributes.freeListings < (this.divCounter+1) && this.attributes.ppListing > 0 ) {
			tmpSelect.className = 'upgradeOnly';
			tmpPrice = this.attributes.ppListing * 1;
		}
		if ( !val ) val = '';
		YAHOO.util.Event.addListener(tmpSelect,'change',this.changeSelect,tmpSelect.onchange,this,false);
		//tmpSelect.options[0] = new Option('- no selection -','');
		var opt = document.createElement('option');
		opt.innerHTML = '- no selection -';
		opt.value = '';
		tmpSelect.appendChild(opt);
		var selectCount=0;
		var sectArr = [];
		sectArr[0] = tmpSelect;
		for ( var i=0; i<this.flgArr.length; i++ ) {
			var flgVal = this.flgArr[i].name;
			var depth = this.flgArr[i].depth;
			var section = (this.flgArr[i+1]&&this.flgArr[i+1].depth > depth)?true:false;
			if ( val != flgVal && (this.valArr[flgVal] || !(this.valArr[flgVal]+'').length) ) continue;
			selectCount++;
			//var flgTxt = flgVal + (( this.divCounter < this.attributes.freeListings )?'Free':this.attributes.ppListing );
			//tmpSelect.options[selectCount] = new Option(flgVal+(tmpPrice?" - "+djo.format_currency(tmpPrice):""), flgVal);
			if ( section ) {
				opt = document.createElement('optgroup');
				opt.label = flgVal;
				sectArr[depth] = opt;
			} else {
				opt = document.createElement('option');
				opt.innerHTML = flgVal+(tmpPrice?" - "+djo.format_currency(tmpPrice):"");
				opt.value = flgVal;
				if ( flgVal == val ) {
					//tmpSelect.selectedIndex = selectCount;
					opt.selected = true;
				}
				sectArr[depth] = tmpSelect;
			}
			if ( depth == 0 || !sectArr[depth-1] ) {
				tmpSelect.appendChild(opt);
			} else {
				sectArr[depth-1].appendChild(opt);
			}
		}
		this.listSelectArr[this.divCounter] = tmpSelect;
		return tmpSelect;
	}

	this.setUpgrade = function() {
		var dId = this.id.split('~')[2];
		var upg = this.options[this.selectedIndex].value;
		var sel = theUpgrade.listSelectArr[dId];
		var cat = sel.options[sel.selectedIndex].value;
		theUpgrade.valArr[cat] = upg;
		theUpgrade.build_valArr();
		theUpgrade.build_box();
	}

	this.upgradeSelect = function(val) {
		var tmpSelect = document.createElement('select');
		tmpSelect.className = 'upgradeOnly';
		tmpSelect.id = this.divId+'~upgradeSelect~'+this.divCounter;
		if ( !val ) val = '';
		YAHOO.util.Event.addListener(tmpSelect,'change',this.setUpgrade,tmpSelect.onchange,tmpSelect,false);
		tmpSelect.options[0] = new Option('- no upgrade -','');
		var selectCount=1;
		for ( var upgId in this.upgArr ) {
			var upgPrice = this.upgArr[upgId];
			var upgName = this.levelArr[upgId];
			//if ( !this.defaultUpg.length ) this.defaultUpg = upgName; //instantiate the default upgrade
			tmpSelect.options[selectCount] = new Option(upgName + ' - ' +djo.format_currency(upgPrice), upgId);
			if ( upgId == val ) {
				tmpSelect.selectedIndex = selectCount;
			}
			selectCount++;
		}
		if ( !this.upgArr.length ) {
			tmpSelect.style.display = 'none';
		}
		return tmpSelect;
	}

	this.newCartItem = function() {
		var tmpArr = [];
		tmpArr["price"] = 0;
		tmpArr["count"] = 0;
		return tmpArr;
	}

	this.addRow = function(isLive, flg, upg) {
		var tmpDiv = document.createElement('div');
		tmpDiv.id = this.divId+'~'+this.divCounter;
		if ( !isLive ) tmpDiv.className = 'newRow';
		var countSpan = document.createElement('span');
		countSpan.className='countSpan';
		countSpan.innerHTML = isLive?(this.divCounter+1)+'.':'*';
		var tmpSelect = this.listingSelect(flg);
		var upgSelect = this.upgradeSelect(upg);
		var descriptionSpan = document.createElement('span');
		descriptionSpan.className = 'descriptionSpan';
		var priceSpan = document.createElement('span');
		priceSpan.className = 'priceSpan';
		var priceTotal = 0;
		var descr = '';
		if ( isLive ) { //if the row is not a newRow, handle the description, pricing
			if ( this.divCounter < this.attributes.freeListings || this.attributes.ppListing == 0 ) {
				descr += 'Free listing #'+(this.divCounter+1);
			} else {
				descr += 'Paid listing';
				priceTotal += this.attributes.ppListing*1;
				if ( !this.cartItemArr['listing'] ) this.cartItemArr['listing'] = this.newCartItem();
				this.cartItemArr['listing']["price"] += this.attributes.ppListing*1;
				this.cartItemArr['listing']["count"]++;
				this.cartItemArr['listing']["text"] = descr;
				this.cartItemArr['listing']["pprec"] = djo.format_currency(this.attributes.ppListing*1);
				//djo_upgrade_field(tmpDiv.id+'listing',priceTotal,1,this.attributes.ppListing,descr);
			}
			if ( upg && this.upgArr[upg] ) {
				var upgPrice = this.upgArr[upg];
				var descr2 = (upgPrice*1!=0?'Upgrade: '+this.levelArr[upg]+'':'');
				priceTotal += upgPrice*1;
				var overStr = 'YAHOO.util.Dom.addClass(document.getElementById(\'djoUpgradeDescr~'+upg+'\'),\'upgHover\');';
				var outStr = 'YAHOO.util.Dom.removeClass(document.getElementById(\'djoUpgradeDescr~'+upg+'\'),\'upgHover\');';
				descr += '<br /><a href="#" style="cursor:pointer;" onmouseout="'+outStr+'" onmouseover="'+overStr+'">'+descr2+'</a>';
				if ( !this.cartItemArr['upgrade-'+upg] ) this.cartItemArr['upgrade-'+upg] = this.newCartItem();
				this.cartItemArr['upgrade-'+upg]["price"] += upgPrice*1;
				this.cartItemArr['upgrade-'+upg]["count"]++;
				this.cartItemArr['upgrade-'+upg]["text"] = descr2;
				this.cartItemArr['upgrade-'+upg]["pprec"] = djo.format_currency(upgPrice*1);
				//djo_upgrade_field(tmpDiv.id+'upgrade',upgPrice,1,upgPrice,descr2);
			}
			descriptionSpan.innerHTML = descr;
			priceSpan.innerHTML = djo.format_currency(priceTotal);
		}
		this.totalPrice += priceTotal*1;
		tmpDiv.appendChild(countSpan);
		tmpDiv.appendChild(tmpSelect);
		if ( !isLive ) upgSelect.disabled = true;
		tmpDiv.appendChild(upgSelect);
		tmpDiv.appendChild(descriptionSpan);
		tmpDiv.appendChild(priceSpan);
		this.theEle.appendChild(tmpDiv);
		this.divCounter++;
	}

	this.addLabels = function() {
		var tmpDiv = document.createElement('div');
		tmpDiv.className = 'labelRow';
		tmpDiv.innerHTML = '<span class="categorySpan">Category</span><span class="upgradeSpan">'+(this.upgArr.length>0?'Upgrade':'&nbsp;')+'</span>';
		this.theEle.appendChild(tmpDiv);
	}

	this.addBreak = function(mod) {
		var tmpDiv = document.createElement('div');
		tmpDiv.className = 'breakRow';
		var htm = '';
		if ( mod == 'free' || this.attributes.ppListing == 0 ) {
			htm = 'Free listing';
			if ( this.attributes.freeListings > 1 ) {
				htm += '(s)';
				if ( this.attributes.ppListing > 0 ) {
					htm += ' - <span>up to '+this.attributes.freeListings+'</span>';
				}
			}
		} else {
			htm = 'Paid listing(s) - <span>'+djo.format_currency(this.attributes.ppListing)+' each</span>';
		}
		tmpDiv.innerHTML = htm;
		this.theEle.appendChild(tmpDiv);
		this.addLabels();
	}

	this.build_box = function() {
		this.divCounter = 0;
		this.totalPrice = 0;
		if ( djoUpgCart ) { //false on admin side
			for ( var v in this.cartItemArr ) {
				djoUpgCart.removeItem(this.divId+'~'+v);
				this.cartItemArr[v] = null;
			}
		}
		this.cartItemArr = []; //reset the cart item arr
		while ( this.theEle.childNodes.length ) { //remove all children elements
			this.theEle.removeChild(this.theEle.firstChild);
		}
		var rowCount = 0;
		if ( rowCount < this.attributes.freeListings ) {
			this.addBreak('free');
		}
		for ( var v in this.valArr ) {
			if ( !v ) continue;
			if ( rowCount == this.attributes.freeListings && this.attributes.ppListing > 0 ) this.addBreak('paid');
			this.addRow(true, v, this.valArr[v]);
			rowCount++;
		}
		if ( rowCount == this.attributes.freeListings && this.attributes.ppListing > 0 ) this.addBreak('paid');
		this.addRow(); //add the disabled row

		var tmpValInput = document.createElement('input');
		tmpValInput.id = this.divId+'~input';
		tmpValInput.setAttribute("name","upgradeString");
		tmpValInput.setAttribute("type","hidden");
		tmpValInput.value = this.theValue;
		this.theEle.appendChild(tmpValInput);

		var tmpValInput2 = document.createElement('input');
		tmpValInput2.id = this.divId+'~value';
		tmpValInput2.setAttribute("name",this.divId);
		tmpValInput2.setAttribute("type","hidden");
		tmpValInput2.value = this.dataValue;
		this.theEle.appendChild(tmpValInput2);

		var counter = 0;
		if ( djoUpgCart ) { //false on admin side
			for ( var v in this.cartItemArr ) {
				counter++;
				var obj = this.cartItemArr[v];
				var arr = [];
				arr["price"] = obj["price"];
				arr["count"] = obj["count"];
				arr["pprec"] = obj["pprec"];
				arr["text"] = obj["text"];
				djoUpgCart.addItem((this.divId+'~'+v),arr);
			}
			if ( counter == 0 ) djoUpgCart.buildCart(); //if no items in cart, exec buildCart()
		}
	}

	this.set_valTo = function(valStr) {
		this.valArr = explode_with_key(valStr);
		this.build_box();
		this.build_valArr();
		document.getElementById(this.divId+'~input').value = this.theValue;
		document.getElementById(this.divId+'~value').value = this.dataValue;
	}

	this.build_box();
	this.build_valArr();
	document.getElementById(this.divId+'~input').value = this.theValue; //these must be manually set on instantiation due to init exceptions
	document.getElementById(this.divId+'~value').value = this.dataValue; //(dynamically adjusted in build_box() subsequently)

	function explode_with_key(str,inglue,outglue){//used to turn an imploded string back into an associative array
		// see implode_with_key() in djoFunctions.inc for the php version of the reverse
		inglue = (inglue)?inglue:'|';
		outglue = (outglue)?outglue:'=>';
		str = str.replace(/^\s+|\s+$/g, ''); //trim the string for trailing spaces, etc.
		str = str.replace(/&gt;/g,'>');
		var startArr = str.split(inglue);//splint on the inglue
		var retArr = [];
		for(var i in startArr){
			if(typeof(startArr[i])=='string'){
				var tempArr = startArr[i].split(outglue);//split on the outglue
				retArr[tempArr[0]] = tempArr[1];//assign the array value
			}
		}
		return retArr;
	}
}


djo.richSelector = function(divId, attributes) {
	if ( !attributes ) attributes = {};
	this.selector = new YAHOO.widget.Menu(divId, attributes); //{ fixedcenter: true }
	this.setContent = function(arr) {
		oMenu.addItems(arr);
	}
	this.render = function() {
		this.selector.render();
	}
}

//***********
// miniCart *
//***********
//
// Purpose:
djo.miniCart = function() {
	this.cart = [];
	this.currencySymbol = '$';
	var initCart = true;
	this.newItem = function(txt,pprec) {
		var it = {};
		it.price = 0;
		it.count = 0;
		it.iprice = 0;
		it.icount = 0;
		it.pprec = pprec;
		it.text = txt;
		return it;
	}
	this.addItem = function(key,arr) {
		if ( !this.cart[key] ) {
			this.cart[key] = this.newItem(arr["text"],arr["pprec"]);
		}
		if ( initCart ) {
			this.cart[key].iprice = arr["price"]*1;
			this.cart[key].icount = arr["count"]*1;
		}
		this.cart[key].price = arr["price"]*1;
		this.cart[key].count = arr["count"]*1;
		this.cart[key].text = arr["text"];
		this.cart[key].pprec = arr["pprec"];
		if ( !initCart ) this.buildCart();
	}
	this.removeItem = function(key) {
		if ( this.cart[key] ) {
			this.cart[key].count = 0;
			this.cart[key].price = 0;
		}
	}
	this.buildRow = function(obj) {
		var htm = "<tr"+(obj.price<0?" class=djoDiscount":"")+">";
		htm += "<td>"+obj.text+"</td>";
		htm += "<td>"+(obj.count*1-obj.icount*1)+" @ "+obj.pprec+"</td>";
		htm += "<td>"+djo.format_currency(obj.price*1-obj.iprice*1,this.currencySymbol)+"</td>";
		htm += "</tr>";
		return htm;
	}
	this.buildCart = function() {
		initCart = false;
		var htm = "";
		var total = 0;
		var descr = "";
		for ( var i in this.cart ) {
			if ( (this.cart[i].count*1 - this.cart[i].icount*1) != 0
				&& (this.cart[i].price*1 - this.cart[i].iprice*1) != 0 ) {
				htm += this.buildRow(this.cart[i]);
				total += this.cart[i].price*1-this.cart[i].iprice*1;
				descr += (descr.length?'; ':'') + this.cart[i].text + ': '+djo.format_currency(this.cart[i].price*1-this.cart[i].iprice*1,this.currencySymbol)+'';
			}
		}
		var totalTbl = document.getElementById("djoTotalTable");
		var totalDiv = document.getElementById("djoTotalDescr");
		if ( htm.length && total > 0 ) { /* do not do anything if total less than 0 :: no credits!!! */
			htm += '<tr id="djoTotalRow"><td colspan="2" id="djoTotalLabel">Total:</td><td>'+djo.format_currency(total,this.currencySymbol)+'</td></tr>';
			totalDiv.innerHTML = "<table>"+htm+"</table>";
			if ( document.getElementById("djoSubmitPrice") )document.getElementById("djoSubmitPrice").value=total;
			totalTbl.style.display="";
			if ( document.getElementById("djoSubmitButton") ) document.getElementById("djoSubmitButton").value = 'Add to cart'; //customform only
		} else {
			if ( document.getElementById("djoSubmitPrice") ) document.getElementById("djoSubmitPrice").value=0;
			totalDiv.innerHTML = "";
			totalTbl.style.display="none";
			if ( document.getElementById("djoSubmitButton") ) document.getElementById("djoSubmitButton").value = 'Submit'; //customform only
		}
		if ( document.getElementById("djoSubmitDescription") ) {
			document.getElementById("djoSubmitDescription").value = descr;
		}
	}
	this.alertCart = function(key) {
		var str = '';
		for ( var key in this.cart ) {
			str += key + ':\n';
			str += 'count=>'+this.cart[key].count+', ';
			str += 'icount=>'+this.cart[key].icount+', ';
			str += 'price=>'+this.cart[key].price+', ';
			str += 'iprice=>'+this.cart[key].iprice+', ';
		}

		alert(str);
	}
}

if(!djo.upgrade){
	djo.upgrade = {};
}

//**************
// priceMatrix *
//**************
//
// Purpose:
djo.priceMatrix = function() {
	var assocArr = [];
	var priceArr = [];
	this.addAssoc = function(key,arr) {
		assocArr[key] = arr;
	}
	this.runAssoc = function(which,floc,rtyp,price,label,aroot,publicMode){
		var newCount=0;
		var assocCount=0;
		if ( assocArr[aroot] ) { /* the association zone is priced per entry */
			//djoTotalEleArr[aroot] = null;
			djoUpgCart.removeItem(aroot);
		}
		//djoTotalEleArr[aroot+"-"+floc] = null;
		djoUpgCart.removeItem(aroot+"-"+floc);

		if ( publicMode ) {
			sel = which.innerSelect;
			for ( var i=0; i<sel.length; i++ ) {
				val = assocMaster.retrieve_data_pt(rtyp,sel.options[i].value,floc);
				if ( val ) {
					newCount++;
				}
				assocCount++;
			}
		} else {
			var liArr = which.getLiArr();
			for ( var i=0; i<liArr.length; i++ ) {
				val = assocMaster.retrieve_data_pt(rtyp,liArr[i].itemValue,floc);
				if ( val ) {
					newCount++;
				}
				assocCount++;
			}
		}
		var eleArr = [];
		if ( assocCount >0 && assocArr[aroot] ) {
			eleArr["price"] = assocCount*assocArr[aroot]["price"]*1;
			eleArr["count"] = assocCount*1;
			eleArr["pprec"] = djo.format_currency(assocArr[aroot]["price"]);
			eleArr["text"] = assocArr[aroot]["label"];
			//djoTotalEleArr[aroot] = eleArr;
			djoUpgCart.addItem(aroot,eleArr);
		}
		if ( newCount > 0 ) {
			eleArr = [];
			eleArr["price"] = newCount*price;
			eleArr["count"] = newCount;
			eleArr["pprec"] = djo.format_currency(price);
			eleArr["text"] = label;
				//djoTotalEleArr[aroot+"-"+floc] = eleArr;
			djoUpgCart.addItem(aroot+"-"+floc, eleArr);
		}
		if ( assocCount == 0 && newCount == 0 ) {
			djoUpgCart.buildCart(); //ensures that if the assoc zone is cleared the cart reflects this
		}
	//djoBuildTotals();
	}
	this.initItem = function(key,arr) {
		priceArr[key] = arr;
	}
	this.addToggleItem = function(key) {
		if ( !djoUpgCart ) return false;
		djoUpgCart.addItem(priceArr[key]["key"], priceArr[key]);
	}
	this.addItem = function() {
		var key = this.id;
		var val = '';
		if ( document.getElementById(this.id+'input') ) { //valuelist or boolean
			val = document.getElementById(this.id+'input').value;
		} else if ( this.value ) {
			val = this.value;
		}
		if ( val.length ) {
			djoUpgCart.addItem(key, priceArr[key]);
		} else {
			djoUpgCart.removeItem(key);
			djoUpgCart.buildCart();
		}
	}
	this.addItemByKey = function(key) {
		if ( !priceArr[key] ) return;
		djoUpgCart.addItem(key, priceArr[key]);
	}
	this.alertPriceArr = function(key) {
		var str = '';
		for ( var key in priceArr ) {
			str += key + '\n';
		}
		for ( var i in priceArr[key] ) {
			str += i+'=>'+priceArr[key][i]+'\n';
		}
		alert(str);
	}
}

//******************
// format_currency *
//******************
//
// Purpose: format a number as a currency
djo.format_currency = function(num, currency) {
	if ( !currency || currency == null ) currency = '$';
	if ( num*1 < 0 ) {
		return "("+currency+(djo.format_number(num*-1))+")";
	} else {
		return currency+djo.format_number(num);
	}
}

//****************
// format_number *
//****************
//
// Purpose: format a number
djo.format_number = function(val) {
	//prep the val
	val = val+""; //force to string
	val = val.replace(/[^\d\-.]/g,'');//replace everything but digits, -'s and .'s with nothing
	if ( !val.length ) { return ''; }//if it's length is 0, return an empty string

	//decide if it's a neg number and remove any -'s
	var isNeg = (val.charAt(0)=='-'?true:false);//if the first character is -, set isNeg to true, else set it to false
	val = val.replace(/-/g,'');//remove any dashes from number

	//get the base number and decimal
	var datArr = [];//init datArr
	if ( val.indexOf(".") != -1 ) {//if there is a period
		datArr = val.split('.');//split on the period
	} else {
		datArr[0] = val;//set the whole part to the value
		datArr[1] = false;//set the decimal to false
	}

	//prep the whole number - LTrim 0's and set to just 0 if there is nothing left
	datArr[0] = ltrim(datArr[0]+'','0');//trim any 0's off the front of the whole number
	datArr[0] = !(datArr[0]+'').length?'0':datArr[0];//if ther is no length left in whole part, set to 0, else set to itself

	//build the whole part adding commas
	var newVal = '';//set ne val to nothing
	var iCount = 0;//set the count to 0
	for ( var i=datArr[0].length-1; i>=0; i-- ) {//for each char in the whole string, moving from last to first
		iCount++;//iterate the count
		newVal = datArr[0].charAt(i) + '' + newVal;//add the character to newVal
		if ( iCount == 3 && i > 0 ) {//if we have added three characters and ther are characters left
			newVal = ',' + newVal;//add a comma to the new val
			iCount = 0;//reset the count to 0
		}
	}

	//put the number back together
	//if there isNeg add a dash, add the base number andif there is a des., add it
	val = (isNeg?'-':'')+newVal+(datArr[1]?'.'+datArr[1]:'');
	return (val=='-'?'':val);//if val is just a -, return nothing, else return the val
}

//****************
// force_integer *
//****************
//
// Purpose: force the input to only be numbers
function force_integer(e) {
	return restrict_input(e, "0123456789");
}

//*****************
// restrict_input *
//*****************
//
// Purpose: restrict a keypress event to be only a numeric
function restrict_input(e, chars) {
	var key, keychar;
	key = getkey(e);
	if (key == null){ return true; }

	// get character
	keychar = String.fromCharCode(key);
	keychar = keychar.toLowerCase();
	chars = chars.toLowerCase();

	// check goodkeys
	if (chars.indexOf(keychar) != -1){
		return true;
	}
	// control keys             Backspace Tab       Enter      Shift      Control    Alt        Capslock   Escape     End        Home       Insert    Delete     Start Lft  Start Rt   Context    Numberlock
	if ( key==null || key==0 || key==8 || key==9 || key==13 || key==16 || key==17 || key==18 || key==20 || key==27 || key==35 || key==36 || key==45 ||key==46 || key==91 || key==92 || key==93 || key==144 ){
		return true;
	}
	//cut, copy, paste key combinations
	if(e.ctrlKey && (key==86 || key==67 || key==88 || key==99 || key== 118 || key==120)){
		return true;
	}

	// else return false
	return false;
}

//*********
// getkey *
//*********
//
// Purpose: translate the key that was pressed
function getkey(e) {
	if (window.event){
		return window.event.keyCode;
	}else if (e){
		return e.which;
	}else{
		return null;
	}
}

//**************
// djoDateTime *
//**************
//
// Purpose:
function djoDateTime(fLoc, readIt) {
	var mmEle = document.getElementById(fLoc+'~month');
	var ddEle = document.getElementById(fLoc+'~day');
	var yyEle = document.getElementById(fLoc+'~year');
	var fLoc = document.getElementById(fLoc);
	if ( readIt ) {
		var theVal = fLoc.value;
		var dtArr = (theVal+'').split('/');
		for ( var x=0; x<mmEle.length; x++ ) { if ( mmEle.options[x].value==dtArr[0] ) { mmEle.selectedIndex = x; break; }}
		for ( x=0; x<ddEle.length; x++ ) { if ( ddEle.options[x].value==dtArr[1] ) { ddEle.selectedIndex = x; break; }}
		if ( dtArr[2] && yyEle.value != dtArr[2] ) yyEle.value = dtArr[2];
	} else {
		fLoc.value = mmEle.options[mmEle.selectedIndex].value + '/' + ddEle.options[ddEle.selectedIndex].value	+ ((yyEle.value+'').length?'/'+yyEle.value:'');
	}
}

//****************
// textarea_edit *
//****************
//
// Purpose: turns a text area into an edit panel
djo.textarea_edit = function(el,mode,label,limit,attributes){//function for textarea popup edit box
	attributes = attributes?attributes:{};
	var limitJs = ' onKeyPress="return limit_entry(event, this, '+limit+');" onKeyUp="enforce_charlimit(this, '+limit+');" onChange="enforce_charlimit(this, '+limit+');"';
	var limitHtml = '<span style="color:purple;'+((mode==''||mode=='process')?'float:right;':'')+'" id="djoEditTextarea~charlimit">Characters: '+(el.value+'').length+' (max: '+limit+')</span>';
	if(mode==''||mode=='process'){//if this is the admin tool
		top.modalInit('Edit',(limit?limitHtml:'')+'<span style="font-size:18px;">'+label+'</span>','<textarea'+(limit?limitJs:'')+' id="djoEditTextarea" class="djoFormTextarea" style="width:557px;height:259px;margin-top:14px;font-family:verdana,sans serif;font-size:11px;">'+el.value+'</textarea> <div class="djoBtnBorder" style="margin-right:3px;margin-top:3px;float:right"><div class="djoButton" onclick="modalKill();frames.iContent.document.getElementById(\''+el.id+'\').focus();" onmouseout="this.style.borderColor=\'#7FA97A\';" onmouseover="this.style.borderColor=\'white\';">Cancel</div></div><div class="djoBtnBorder" style="margin-right:3px;margin-top:3px;float:right;"><div class="djoButton" onclick="frames.iContent.document.getElementById(\''+el.id+'\').value = document.getElementById(\'djoEditTextarea\').value;modalKill();frames.iContent.document.getElementById(\''+el.id+'\').focus();" onmouseout="this.style.borderColor=\'#7FA97A\';" onmouseover="this.style.borderColor=\'white\';">OK</div></div>',600,300);
	}else if(mode=='public'){//if this is public
		// Instantiate a Panel from markup
		djo.djoEdit = new YAHOO.widget.Panel("djoEdit", {
				width:"400px",
				visible:true,
				draggable:false,
				modal:true,
				fixedcenter:true
			} );
		if ( limit ) label+= ' - ' + limitHtml;
		djo.djoEdit.setHeader('Edit - '+label);
		var startVal = attributes.startVal&&attributes.startVal.length?attributes.startVal:el.value;
		var ht = '300';
		var msg = '';
		if ( attributes.msg && attributes.msg.length ) {
			ht = '200';
			msg = '<p style="margin-bottom:8px;font-weight:bold;">'+attributes.msg+'</p>';
		}
		djo.djoEdit.setBody(msg+'<textarea id="djoEditTextarea"'+(limit?limitJs:'')+' style="height:'+ht+'px;width:100%;margin:0px;font-family:verdana,sans serif;font-size:11px;">'+startVal+'</textarea>');
		var onOk = attributes.onOk?attributes.onOk:'return djo.textarea_ok(document.getElementById(\''+el.id+'\'),document.getElementById(\'djoEditTextarea\').value);';
		var onKill = attributes.onKill?attributes.onKill:'return djo.textarea_kill(document.getElementById(\''+el.id+'\'));';
		djo.djoEdit.setFooter('<div style="text-align:right;width:100%;font-weight:bold;"><a href="#" onclick="'+onOk+'" class="djo_form_button tiny">OK</a>&nbsp;&nbsp;<a href="#" onclick="'+onKill+'" class="djo_form_button tiny">Cancel</a></div>');

		var djoContent = document.getElementById('djo_content');
		YAHOO.util.Dom.addClass(djoContent,'yui-skin-sam');
		djo.djoEdit.render(djoContent);
		document.getElementById('djoEditTextarea').focus();
	}
}

//**************
// textarea_ok *
//**************
//
// Purpose: event handler for the ok button on the text area
djo.textarea_ok = function(el,value){
	el.value = value;
	return djo.textarea_kill(el);
}

//****************
// textarea_kill *
//****************
//
// Purpose: kill the modal box that is the text area
djo.textarea_kill = function(el){
	el.focus();
	djo.djoEdit.hide();
	djo.djoEdit.destroy();
	el.focus();
	return false;
}


if(!djo.list){
	djo.list = {};
}

//*****************
// expanding List *
//*****************
//
// Purpose:
djo.list.expandingList = function(el,attributes){
	// The element to be turned into a ListBox
	var tmpEl = YAHOO.util.Dom.get(el);

	if(!tmpEl){//make sure we have a valid object
		return false;
	}

	//if the structure is passed via javascript function, build it this way
	if(attributes && attributes.structure){
		//build the parentUL
		var tmpUl = document.createElement('ul');
		tmpUl.id = tmpEl.id + "Ul";
		tmpUl.className = "expandingList";
		tmpEl.appendChild(tmpUl);
	}

	//build the input
	var tmpInput = document.createElement('input');
	tmpInput.type = "hidden";
	tmpInput.id = tmpEl.id + "Input";
	tmpInput.name = tmpEl.id + "Input";
	tmpInput.value = -1;
	tmpEl.appendChild(tmpInput);

	//collect info
	this.el = document.getElementById(tmpEl.id);
	this.ul = document.getElementById(tmpEl.id + 'Ul');
	this.input = document.getElementById(tmpInput.id);
	this.HTML = "";

	//set event listeners
	YAHOO.util.Event.addListener(this.ul,"click",this.item_click,this,true); //check for item click
	YAHOO.util.Event.addListener(this.ul,"dblclick",this.item_click,this,true); //check for item dblclick

	attributes = attributes || {};
	this.expanded = attributes.expanded || {};
	this.ids = attributes.ids || {};

	this.count = 0;
	//set the attributes including building the UL structure
	this.set_attributes(attributes);

	if(attributes.onload){
		eval(attributes.onload);
	}
}
djo.list.expandingList.prototype = {
	el: null,
	ul: null,
	HTML: null,
	count: 0,
	expanded:null,
	onChange: null,
	radio: false,
	set_attributes: function (attributes) { //sets the attributes and runs the read_obj function
		//start the function off and running
		if(attributes.structure){
			this.read_obj(attributes.structure);
			//append the HTML to the UL (or maybe just build as you go...
			this.ul.innerHTML = this.HTML;
		}
		if(attributes.onChange){
			this.onChange = attributes.onChange;
		}
		if(attributes.radio){
			this.radio = attributes.radio;
		}
		//change input name for custom inputs
		if(attributes.inputName != null){
			this.input.id = attributes.inputName;
			this.input.name = attributes.inputName;
		}
	},
	read_obj: function (obj) { //recursive method for iterating through the multi-demensional associative array
		//read the object, iterate the children, write to this.HTML
		var exp = this.expanded;
		var ids = this.ids;
		this.count++;
		for(var i in obj){//for each item in the object
			if(typeof(obj[i]) == 'object'){//there are child nodes
				this.spaces();
				var dir = (exp[i])?"Open":"Closed";
				var id = (ids[i] != null)?ids[i]:i;
				this.input.value = (exp[i])?id:this.input.value;
				this.HTML += '<li class="li'+dir+'" id="'+id+'">'+i+'<ul class="ul'+dir+'">\n';//start the li
				this.read_obj(obj[i]);//iterate through the next object
				this.spaces();
				this.HTML += '</ul></li>\n';//close the li
			}else{//no child nodes
				this.spaces();
				this.HTML += '<li class="liNoExpand">'+i+'</li>\n';//start and close the li
			}
		}
		this.count--;
	},
	spaces: function(){
		for(var j=1;j<this.count;j++){
			this.HTML += "  ";
		}
	},
	getUl: function(li){
		var i=0;
		while(li.childNodes[i].tagName != 'UL'){
			i++;
		}
		return li.childNodes[i];
	},
	getLi: function (value) {
		var liArr = this.getLiArr();
		value = value+'';//force value to be a string
		//try to find based on value, exclude+value, or ex:+value
		for (var i = 0;i < liArr.length;i++) {
			if (liArr[i].id+"" == value) {//if the values match
				return liArr[i];//return this item
			}
		}
		return false;//nothing found, return false
	},
	//get the array of LI items
	getLiArr: function () {
		liArr = [];
		j=0;
		var children = this.ul.getElementsByTagName('li');
		for(var i = 0;i < children.length;i++){//for each item in the array
			if(YAHOO.util.Dom.hasClass(children[i],'liOpen') || YAHOO.util.Dom.hasClass(children[i],'liClosed')){//if it's an open/close item
				liArr[j] = children[i];
				j++;
			}
		}
		return liArr;
	},
	select: function (id) {
		if(this.getLi(id)){//if it was a valid click on an Li
			document.body.focus();//inserted to fix the issue with text getting selected preventing scroll bars from scrolling
			listItem = this.getLi(id);
			if(listItem.className == 'liClosed'){//if closed, open
				if(this.radio){//if the radio attribute is set to true, close all li's
					this.input.value = listItem.id;
					liArr = YAHOO.util.Dom.getElementsByClassName('liOpen','li',this.el);
					for(var i = 0;i < liArr.length;i++){
						liArr[i].className = 'liClosed';
						this.getUl(liArr[i]).className = 'ulClosed';
					}
				}
				listItem.className = 'liOpen';
				this.getUl(listItem).className = 'ulOpen';
			}else if(listItem.className == 'liOpen'){// && !this.radio){//if open, and this.radio is not true, close
				listItem.className = 'liClosed';
				this.getUl(listItem).className = 'ulClosed';
			}else{
				return true;
			}
			eval(this.onChange);
		}
	},
	item_click: function (ev,obj){
		ev = ev || window.event;
		var listItem = (ev.target || ev.srcElement);
		return this.select(listItem.id);
	}
}

djo.modalAlert = function(msg) {
	var djoContent = document.getElementById('djo_content'); //exists if public side
	if( !djoContent ){//if this is the admin tool
		top.modalInit('Alert','', msg,300,100);
	}else {//if this is public
		// Instantiate a Panel from markup
		djo.djoEdit = new YAHOO.widget.Panel("djoEdit", {
				width:"300px",
				height:"150px",
				visible:true,
				draggable:false,
				modal:true,
				fixedcenter:true,
				close:false
			} );
		djo.djoEdit.setHeader('&nbsp;');
		djo.djoEdit.setBody(msg);
		//var onOk = attributes.onOk?attributes.onOk:'return djo.textarea_ok(document.getElementById(\''+el.id+'\'),document.getElementById(\'djoEditTextarea\').value);';
		//var onKill = attributes.onKill?attributes.onKill:'return djo.textarea_kill(document.getElementById(\''+el.id+'\'));';
		//djo.djoEdit.setFooter('<div style="text-align:right;width:100%;font-weight:bold;"><a href="#" onclick="'+onOk+'" class="djo_form_button tiny">OK</a>&nbsp;&nbsp;<a href="#" onclick="'+onKill+'" class="djo_form_button tiny">Cancel</a></div>');


		YAHOO.util.Dom.addClass(djoContent,'yui-skin-sam');
		djo.djoEdit.render(djoContent);
	}
}

djo.modalKill = function() {
	if ( djo.djoEdit ) {
		djo.djoEdit.hide();
		setTimeout( 'djo.djoEdit.destroy();', 500 ); //for some reason this is needed or a YAHOO undefined error thrown ??
	} else {
		top.modalKill();
	}
}

//***********
// uploader *
//***********
//
// Purpose: Handle file uploades using YUI's uploader flash utility
//
// Resource Requirements: Yahoo, Dom, Event, Element, Uploader, common.js (this file), & survey.css
//
// User Requirements: Flash 9.0.45 or higher on the users browser
//
// Use Example: djo.uploader( Id of element to use, domain to use for resources, file size limit (opt.), file type filter (opt.), upload start js (opt.), upload success js (opt.), post vars (opt.) )
//		myUploader = new djo.uploader('djoUploader','http://joe4-jacob.datajoe.com',1045504,[{description:"Images", extensions:"*.jpg;*.png;*.gif"},{description:"Videos", extensions:"*.avi;*.mov;*.mpg"}], 'onUploadStart();', 'onUploadSuccess(event.data);', {'myPostVar':'myVal'});
djo.uploaderScope = [];
djo.uploaderEvent = function(id,fnc){
	eval("djo.uploaderScope['"+id+"']."+fnc);
}
djo.uploader = function(uploaderDivId, uploadURL, fileSizeLimit, fileTypeFilterArr, uploadStartJs, uploadSuccessJs, postArr){
	this.uploaderDivId = uploaderDivId;
	this.recordType = 'image';//added for the assocMatrix
	this.target = {};//added for the assocMatrix
	this.domain = uploadURL
	this.sizeLimit = fileSizeLimit-0 && typeof(fileSizeLimit-0) == "number"?fileSizeLimit:false;//if fileSizeLimit is a number, set it to self, else set to false
	this.typeFilterArr = typeof(fileTypeFilterArr) == "object" && fileTypeFilterArr.length?fileTypeFilterArr:false;//if this is an array, set it to self, else set to false
	this.postArr = typeof(postArr) == "object" && postArr.length?postArr:{};//if this is an array, set it to self, else set to an empty array
	this.fileID = null;
	this.contentReady = false;
	this.set_onUploadStart(uploadStartJs);
	this.set_onUploadSuccess(uploadSuccessJs);

	//create html structure
	this.uploaderDiv = document.getElementById(uploaderDivId);

	var tmpProgress = document.createElement('div');
	tmpProgress.id = uploaderDivId+"_djoFileProgress";
	tmpProgress.className = "djoFileProgress";
	var tmpName = document.createElement('div');
	tmpName.id = uploaderDivId+"_djoFileName";
	tmpName.className = "djoFileName";
	var tmpBar = document.createElement('div');
	tmpBar.id = uploaderDivId+"_djoProgressBar";
	tmpBar.className = "djoProgressBar";
	var tmpFill = document.createElement('div');
	tmpFill.id = uploaderDivId+"_djoProgressBarFill"
	tmpFill.className = "djoProgressBarFill";

	var tmpUI = document.createElement('div');
	tmpUI.id = uploaderDivId+"_djoBrowseButton";
	tmpUI.className = "djoBrowseButton";
	var tmpUlBtn = document.createElement('a');
	tmpUlBtn.id = uploaderDivId+"_djoUploadButton";
	tmpUlBtn.className = "djoUploadButton";
	//tmpUlBtn.style.backgroundImage =  this.domain + '/common/images/uploadFileButton.png';

	tmpProgress.appendChild(tmpName);
	tmpBar.appendChild(tmpFill);
	tmpProgress.appendChild(tmpBar);
	this.uploaderDiv.appendChild(tmpProgress);
	this.uploaderDiv.appendChild(tmpUI);
	this.uploaderDiv.appendChild(tmpUlBtn);

	this.fileNameDiv = document.getElementById(uploaderDivId+'_djoFileName');
	this.progressBarDiv = document.getElementById(uploaderDivId+'_djoProgressBar');
	this.progressBarFillDiv = document.getElementById(uploaderDivId+'_djoProgressBarFill');
	this.browseButtonDiv = document.getElementById(uploaderDivId+'_djoBrowseButton');
	this.uploadButtonDiv = document.getElementById(uploaderDivId+'_djoUploadButton');

	//instantiate the uploader
	YAHOO.widget.Uploader.SWFURL = this.domain + "/common/scripts/yui/build2.7.0b/uploader/assets/uploader.swf";
	this.control = new YAHOO.widget.Uploader(uploaderDivId+'_djoBrowseButton', this.domain + '/common/images/selectFileButton.png');
	//add event listeners
	this.control.addListener('contentReady',this.onContentReady,this,true);
	this.control.addListener('fileSelect',this.onFileSelect,this,true);
	this.control.addListener('uploadStart',this.onUploadStart,this,true);
	this.control.addListener('uploadProgress',this.onUploadProgress,this,true);
	this.control.addListener('uploadCancel',this.onUploadCancel,this,true);
	this.control.addListener('uploadComplete',this.onUploadComplete,this,true);
	this.control.addListener('uploadCompleteData',this.onUploadCompleteData,this,true);
	this.control.addListener('uploadError',this.onUploadError,this,true);
	YAHOO.util.Event.addListener(this.uploadButtonDiv,'click',this.onUploadClick,this,true);
}

djo.uploader.prototype = {
	byte_convert: function(bytes){//converts bytes to KB, MB, GB, etc...
		var symbol = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
		var exp = 0;
		var converted_value = 0;
		if( bytes > 0 ){
			exp = Math.floor( Math.log(bytes)/Math.log(1024) );
			converted_value = ( bytes / Math.pow( 1024 , Math.floor( exp )) );
		}
		return Math.round(converted_value) + symbol[exp];
	},
	set_onUploadStart: function(jsFunction){
		this.onUploadStartCallback = jsFunction;
	},
	set_onUploadSuccess: function(jsFunction){
		this.onUploadSuccessCallback = jsFunction;
	},
	reset: function(){
		this.controlClear();//clear the file list
		this.fileID = null;//set the fileID to null
		this.fileNameDiv.innerHTML = "";//clear the inner HTML
		this.progressBarFillDiv.style.width = "0px";//set the progress bar to nothing
	},
	disable: function(){
		this.reset();
		this.controlDisable();

		YAHOO.util.Dom.addClass(this.uploadButtonDiv,'disabled');
	},
	enable: function(){
		this.controlEnable();
		YAHOO.util.Dom.removeClass(this.uploadButtonDiv,'disabled');
	},
	controlClear: function(){
		if(this.contentReady){
			this.control.clearFileList();//clear the file list
		}else{
			djo.uploaderScope[this.uploaderDivId] = this;
			setTimeout('djo.uploaderEvent("'+this.uploaderDivId+'","controlClear();");', 50);
		}
	},
	controlDisable: function(){
		if(this.contentReady){
			this.control.disable();
		}else{
			djo.uploaderScope[this.uploaderDivId] = this;
			setTimeout('djo.uploaderEvent("'+this.uploaderDivId+'","controlDisable();");', 50);
		}
	},
	controlEnable: function(){
		if(this.contentReady){
			this.control.enable();
		}else{
			djo.uploaderScope[this.uploaderDivId] = this;
			setTimeout('djo.uploaderEvent("'+this.uploaderDivId+'","controlEnable();");', 50);
		}
	},

	//event methods
	onContentReady: function(){//When contentReady event is fired, call methods on the uploader
		djo.uploaderScope[this.uploaderDivId] = this;
		setTimeout('djo.uploaderEvent("'+this.uploaderDivId+'","contentReady = true;");', 200);
		this.control.setAllowLogging(true);
		if(this.typeFilterArr !== false){//If there was a passed filter array, apply the file filters to the uploader
			this.control.setFileFilters(this.typeFilterArr);
		}
	},
	onFileSelect: function(event){
		for(var item in event.fileList){//for each item in the even file list
			if(typeof(event.fileList[item])=='function') continue;//if this is an function, skip it
			//test size limit
			if(this.sizeLimit && event.fileList[item].size > this.sizeLimit){
				alert('You can only upload files of sizes less than '+this.byte_convert(this.sizeLimit));//throw an error
				this.control.clearFileList();
				this.fileID = null;
				return false;
			}

			var isValid = false;
			var extArr = [];
			for(var i in this.typeFilterArr){//for each extention group
				var tmpArr = this.typeFilterArr[i].extensions.split(';');//split the extetions
				if(!tmpArr.length) continue;//if there is an array
				for(k=0;k<tmpArr.length;k++){//for each extension
					var tmpVal = tmpArr[k].split('.')[1];//get just the ext
					if(tmpVal){//if this ext has not been added to the array
						extArr.push('*.'+tmpVal);//add it to the array
					}
					if(event.fileList[item].name.toLowerCase().indexOf('.'+tmpVal)!=-1){//if this ext is part of the filename
						isValid = true;//set valid to true
					}
				}
			}
			if(!isValid){//if the ext was not found
				alert('You can only upload files of types: '+extArr);//throw an error
				this.control.clearFileList();
				this.fileID = null;
				return false;
			}

			this.fileID = event.fileList[item].id;//get the Id
		}
		this.fileNameDiv.innerHTML = event.fileList[this.fileID].name + ' - ' + this.byte_convert(event.fileList[this.fileID].size);//set the file name
		this.progressBarFillDiv.style.width = "0px";//set the progress bar to nothing
	},
	onUploadClick: function(){
		if (this.fileID != null) {
			this.control.upload(this.fileID, this.domain + '/common/uploader.php', 'POST', this.postArr);
			this.fileID = null;
		}
	},
	onUploadStart: function(event){
		if(this.onUploadStartCallback!=null){
			eval(this.onUploadStartCallback);
		}
	},
	onUploadProgress: function(event){//on upload progress
		this.progressBarFillDiv.style.width = Math.round(this.progressBarDiv.offsetWidth*(event['bytesLoaded']/event['bytesTotal'])) + "px";//set the width of the fill bar to that % complete
	},
	onUploadCancel: function(){},
	onUploadComplete: function(event){
		this.control.clearFileList();
		this.fileID = null;
		this.progressBarFillDiv.style.width = this.progressBarDiv.offsetWidth + "px";//set the width of the fill bar to the width of the progress bar
	},
	onUploadCompleteData: function(event){
		this.target.value = event.data;//update the target value for the assoc matrix
		if(event.data && this.onUploadSuccessCallback != null){
			eval(this.onUploadSuccessCallback);
		}
	},
	onUploadError: function(){}
}

djo.adjust_preview_size = function(theImg,height,width){
	theImg = document.getElementById(theImg);//get the image
	if(theImg && (theImg.height > height || theImg.width > width)){//if the height or width exceeds the height or width passed
		if((theImg.height*width)/theImg.width > height){
			theImg.height = height;
		}else{
			theImg.width = width;
		}
	}
	if(theImg && theImg.height < height){//if the new image height is less than the passed height
		theImg.style.paddingTop = ((height - theImg.height )/2) + 'px';
	}
}

function limit_entry(e, ele, limit) {
	var key;
	key = getkey(e);
	if (key == null){ return true; }
	// control keys             Backspace Tab       Enter      Shift      Control    Alt        Capslock   Escape     End        Home       Insert    Delete     Start Lft  Start Rt   Context    Numberlock
	if ( key==null || key==0 || key==8 || key==9 || key==13 || key==16 || key==17 || key==18 || key==20 || key==27 || key==35 || key==36 || key==45 ||key==46 || key==91 || key==92 || key==93 || key==144 ){
		return true;
	}
	//cut, copy, paste key combinations
	if(e.ctrlKey && (key==86 || key==67 || key==88 || key==99 || key== 118 || key==120)){
		return true;
	}
	if ( ele.value.length >= limit ) return false;
	return true;
}

function enforce_charlimit(ele, limit) {
	var altEle = document.getElementById(ele.id+'~charlimit');
	var len = ele.value.length;
	var msg = 'Characters: '+len+' (max: '+limit+')';
	altEle.innerHTML = msg;
	ele.value = (ele.value+'').substring(0,limit);
}
