/*
 * File: core.js
 * Created: March, 2009
 * Author: Wes Jones
 * Purpose: To provide functions that are used on a consistent 
 *    basis or that do not belong to any particular class
 */

String.prototype.ucfirst = function(){
     return this.toLowerCase().replace(/\w+/g,function(s){
          return s.charAt(0).toUpperCase() + s.substr(1);
     })
}

String.prototype.ucwords = function(){
     return this.toLowerCase().replace(/\w+/g,function(s){
          var a = s.split(' ');
          for(var i = 0; i < a.length; ++i) {
             s = s.replace(a[i],a[i].ucfirst());
          }
          return s;
     })
}

String.prototype.charpac = function(n){
      var str = '';
      for(var i = 0; i < n; ++i) { str += this; }
      return str;
}

String.prototype.trim = function() {
    str = this != window? this : str;
    return str.replace(/^\s+/, '').replace(/\s+$/, '');
}

// depricated use toFixed and toPrecision
Number.prototype.decimals = function(n){
   return this.toFixed(n);
}

function clone (obj,deep,simplify) {
  /*
   * Since javascript passes by reference it can be difficult to get a copy
   * of something. This will return a copy. You must pass 1 or 2 parameters.
   * the first parameter is the object you want to clone. The second is weather
   * or not you want to copy the whole thing or just the top level of it.
   * if you just copy the top level the other elements in the array will still
   * be associated by reference. 
   */
  var objectClone = (simplify != null ? new Object() : new obj.constructor());
  for (var property in obj)
    if (!deep) {
      objectClone[property] = obj[property];
    } else if (typeof obj[property] == 'object') {
      objectClone[property] = clone(obj[property],deep);
    } else if(simplify == null || typeof(obj[property]) != 'function') {
      objectClone[property] = obj[property];
    }
  return objectClone;
}

var LOADQUEUE = new OnLoadQueue();
window.onload = LOADQUEUE.start;
function OnLoadQueue() {
	this.list = new Array();
	this.add = function (fr) {
		if(typeof(fr) == 'function') {
			this.list.push(fr);
		} else {
			alert('You can only pass function references to LOADQUEUE');
		}
	}
	this.start = function() {
		for(var i in LOADQUEUE.list) {
			LOADQUEUE.list[i]();
		}
	}
}

function getPageWidth() {
   /*
    * get the width of the page. Cross Browser compatible.
    */
   return getPageDimensions().width;
}

function getPageHeight() {
   /*
    * get the height of the page. Cross Browser compatible.
    */
   return getPageDimensions().height;
}

function getPageDimensions() {
   /*
    * must be executed after body tag
    * this is used by getPageWidth and getPageHeight to get the actual dimentions
    * of the current window. It checks browser versions to be compatible.
    */
   if (parseInt(navigator.appVersion)>3) {
       if (navigator.appName=="Netscape") {
         winW = window.innerWidth;
         winH = window.innerHeight;
       }
       if (navigator.appName.indexOf("Microsoft")!=-1) {
         winW = document.body.offsetWidth;
         winH = document.body.offsetHeight;
      }
   }
   return new Object({'width':winW,'height':winH});
}

function getDocumentWidth() {
	return getPageSizeWithScroll()[0];
}

function getDocumentHeight() {
	return getPageSizeWithScroll()[1];
}

function getPageSizeWithScroll(){
	if (window.innerHeight && window.scrollMaxY) {// Firefox
		yWithScroll = window.innerHeight + window.scrollMaxY;
		xWithScroll = window.innerWidth + window.scrollMaxX;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		yWithScroll = document.body.scrollHeight;
		xWithScroll = document.body.scrollWidth;
	} else { // works in Explorer 6 Strict, Mozilla (not FF) and Safari
		yWithScroll = document.body.offsetHeight;
		xWithScroll = document.body.offsetWidth;
  	}
	arrayPageSizeWithScroll = new Array(xWithScroll,yWithScroll);
	//alert( 'The height is ' + yWithScroll + ' and the width is ' + xWithScroll );
	return arrayPageSizeWithScroll;
}

function count(__object__){
   /*
    * php has a nice function for determining the length of an object.
    * so I made one so javascript could do the same.
    */
   var len = 0; for(var i in __object__) { len += 1; }; return len;
}

var PO = new ParseObj();

function traceAry(obj) {
   /*
    * Like print_p() in php except this ones is on the javascript side.
    * this is mainly used for a debugging function to view your objects.
    * use alert(traceAry(myObject)); to see how it works.
    */
   return PO.traceIt(obj);
}

function getCookie(cookieName) {
   /*
    * get a cookie by it's name. returns an object.
    */
   var nameEQ = name + "=";
   var cstr = document.cookie+'';
   cstr = cstr.replace(/\;(\s?|\n?|\r?)/,';'); // get rid of trailing space
   var obj = PO.parseIt(cstr,';');
   if(exists(obj,cookieName)) {
      return obj[cookieName];
   } else if (exists(obj,' '+cookieName)) {
      return obj[' '+cookieName];
   }
   return null;
}

function setCookie(cookieName,cookieValue,nDays) {
   /*
    * set a cookie. Name, value, and how many days it will stay in memory.
    */
   cookieName = cookieName.trim();
   deleteCookie(cookieName);
   var today = new Date();
   var expire = new Date();
   if (nDays==null || nDays==0) nDays=1;
   expire.setTime(today.getTime() + 3600000*24*nDays);
   document.cookie = cookieName+"="+escape(cookieValue)+ ";expires="+expire.toGMTString();
}

function deleteCookie(cookieName) {
   /*
    * delete a cookie by name
    */
   var c = new Date();
   document.cookie = cookieName+'=1;expires='+c.toGMTString()+';'+';';
}


function escapeHtml(str) {
   /*
    * Used like htmlspecial chars in php. It will convert most html special characters to their ascii format.
    */
   if(typeof(str) == 'string') {
      str = str.replace(/\</gi,'&lt;');
      str = str.replace(/\>/gi,'&gt;');
      str = str.replace(/\"/gi,'&quot;');
      str = str.replace(/\&/gi,'&amp;');
      str = str.replace(/\-/gi,'&ndash;');
      str = str.replace(/\_/gi,'&mdash;');
      str = str.replace(/\'/gi,'&lsquo;');
   }
   return str;
}

function unescapeHtml(str) {
   /*
    * Decode a string that is encoded using escapeHtml.
    */
   if(typeof(str) == 'string') {
      str = str.replace(/\&lt\;/gi,'<');
      str = str.replace(/\&gt\;/gi,'>');
      str = str.replace(/\&quot\;/gi,'"');
      str = str.replace(/\&amp\;/gi,'&');
      str = str.replace(/\&ndash\;/gi,'-');
      str = str.replace(/\&mdash\;/gi,'_');
      str = str.replace(/\&lsquo\;/gi,'\'');
      str = str.replace(/\&rsquo\;/gi,'\'');
   }
   return str;
}

function daysInMonth(year,month) {
   /*
    * Pass the year and month. It will tell you how many days are in that month.
    * Months are 0-11
    */
   var d= new Date();
   year = year ? year : d.getFullYear();
   var days = new Array(31,((year%4==0&& year%100!=0)||year%400==0?29:28),31,30,31,30,31,31,30,31,30,31);
   if (!isNaN(month)) { return days[month]; }
   else { return days; }
}

function dd(i,digits){ 
   /*
    * return double digits of numbers. Such as 01, 02, 03, ...
    */
   digits = digits ? digits : 2;
   i = i+'';
   i = charpac('0',digits-i.length)+i;
   return i;
}

function charpac(s,n) {
   /*
    * return a string with the s string repeated n times.
    */
   var str = '';
   for(var i = 0; i < n; ++i) { str += s; }
   return str;
}

function exists(obj,attribute) {
   /*
    * used to check if an attribute exists in an object. Use this if trying to
    * check by if(object.attribute) is throwing an error.
    */
   var e = false;
   for(var i in obj) {
      if(i == attribute) {
         e = true;
         break;
      }
   }
   return e;
}


function hideUnhide(divid) {
   /*
    * pass the divid and this will toggle that element displayable or not.
    * this is ideal for making menus that you want to conceal until they are clicked.
    */
   var div = document.getElementById(divid);
   div.style.display = div.style.display == 'inline' || div.style.display == 'block' ? 'none' : 'block';
}

function getKeyCode (e) {
   /*
    * returns the keyCode of a key pressed in IE or Mozilla Browsers
    */
   if(window.event) { // IE
      return e.keyCode;
   } else if (e.which) { // Netscape/Firefox/Opera
      return e.which;
   }
}

function secondstostr (s,chop) {
   /*
    * Pass a number of seconds to this and it will return it in a 
    * Y-m-d H:i:s format. Works great for a timer. secondstostr(90,1) = 1:30
    * if you pass the chop it will only show you what is there.
    * if you don't pass the chop it will show you the whole string. 0000-00-00 00:00:00
    */
   // convert a time in seconds to Y-m-d H:i:s
   if(s == 0) { return 0; }
   else {
      var negative = '';
      if(s<0) { s = Math.abs(s); negative='-'; }
      var tl = s;
      s = dd(s%60);
         tl = (tl-s)/60;
      var i = dd(tl%60);
         tl = (tl-i)/60;
      var h = dd(tl%24);
         tl = (tl-h)/24;
      var mydate = new Date();
         dim = daysInMonth(mydate.getFullYear(),mydate.getMonth());
      var d = dd(tl%dim);
         tl = (tl-d)/dim;
      var m = dd(tl%12); 
         tl = (tl-m)/12;
      var y = dd(tl);
      if(!chop) {
         return negative+y+'-'+m+'-'+d+' '+h+':'+i+':'+s;
      } else {
         str='';
         if(y>0||str){ str+=y+'-'; }
         if(m>0||str){ str+=m+'-'; }
         if(d>0||str){ str+=d+' '; }
         if(h>0||str){ str+=h+':'; }
         if(i>0||str){ str+=i+':'; }
         str+=s;
         return negative+str;
      }
   }
}

function ByteSize(bytes) {  
   /*
    * format sizes of bytes. Just pass a number and it will convert it to byte
    * notation. ByteSize(1048576) = 2MB;
    */
   size = bytes / 1024;  
   if(size < 1024){
       // kilobytes
       size = (parseInt((size)*100)/100)+'kb';  
   } else {  
       if(size / 1024 < 1024) {
           // megabytes
           size = size/1024;
           size = (parseInt((size)*100)/100)+'mb';  
       } else if(size/1024/1024 < 1024) {
           // gigabytes
           size = size/1024/1024;
           size = (parseInt((size)*100)/100)+'gb';  
       } else {  
           // terrabytes
           size = size/1024/1024/1024;  
           size = (parseInt((size)*100)/100)+'tb';  
       }  
   }  
   return size;  
}

function URLRequest() {
	/*
	 * Receives all of the arguments that need to be put into an object
	 * this will go through and pair each of the items to an object
	 */
	var obj = new Object();
	for(var i=0; i<arguments.length; i+=2) {
		obj[arguments[i]] = arguments[i+1];
	}
	return obj;
}

function ParseObj() {
/*
 * ParseObj.js
 * Created Sept 26, 2006
 * Author: Wes Jones
 * Purpose: take any url or query string and parse it into a hiearchal object return as array of objects
 * PO is already defined in this script so you don't define it. You just use
 * it.
 * Example: gets variables out of a query string
 *   var str = 'test=hello&user[id]=1&user[level]=2';
 *   var obj = PO.parseIt(str);
 *   alert(traceIt(obj)); // traces like print_r in php
 * Example 2: gets variables out of the url
 *   var urlvars = PO.getURL();
 *   alert(traceIt(urlvars));
 * Example 3: use the PO.toString(obj) to convert items to a url encoded string.
 * all objects passed through ajax are encoded this way automatically.
 */
   this.obj = new Object();
   this.unique_keys = new Object(); // for avoiding recursion when toString()
   this.getURL = function () { // get url and parseIt
      var str = document.location+'';
      var spobj = new Object();
      var sp = str.split('?');
      spobj.url = sp[0];
      spobj.query = this.parseIt(sp[1]);
      return spobj;
   }
   this.parseIt = function (vars,chr) {
      // parese query string into variable object and return it
      this.obj = new Object();
      chr = chr ? chr : '&';
      vars = (vars+'').trim();
      if(typeof(vars) != 'string') { vars = vars+''; }
      var v = vars.split(chr);
      for(var i in v) {
         v[i] = v[i].toString().split('=');
         var tmp = v[i][0].toString().split('[');
         if (tmp.length > 1) {
            if (this.obj[tmp[0]] == undefined) {
               this.obj[tmp[0]] = new Object();
            }
            var keys = v[i][0].toString().split('[');
            keys = keys.splice(1,keys.length-1);
            for(var j in keys) {
               keys[j] = keys[j].toString().replace(']','');
            }
            this.obj[tmp[0]] = this.addKV(this.obj[tmp[0]],keys,v[i][1]);
         } else {
            if (v[i][0]) {
               this.obj[v[i][0]] = unescape(v[i][1]);
            }
         }
      }
      return this.obj;
   }
   this.addKV = function (obj,keys,val) {
      // add sub child objects recursivly
      if(keys.length > 1) {
         if(!obj[keys[0]]) {
            obj[keys[0]] = new Object();
         }
         obj[keys[0]] = this.addKV(obj[keys[0]],keys.splice(1,keys.length-1),val);
      } else {
         val = unescape(val);
         if(!isNaN(val)) {
         	val = parseFloat(val);
         	val = isNaN(val) ? 0 : val;
         } else if (val.toLowerCase() == 'true') {
         	val = true;
         } else if (val.toLowerCase() == 'false') {
         	val = false;
         }
         obj[keys[0]] = val;
      }
      return obj;
   }
   this.charPac = function (c,d) {
      // add spacing for legibility
      var str = '';
      for(var i = 0; i < d; ++i) { str += c; }
      return str;
   }
   this.traceIt = function (obj,depth) {
      // recursivly trace the array and ouput in hiearchal string
      var str = '';
      depth = depth ? parseInt(depth) : 0;
      if((typeof(obj)+'').toLowerCase() == 'array') { //.length) {
         for(var i=0; i < obj.length; ++i) {
         	str += this.traceStr(obj,i,depth);
         }
      } else {
         for(var i in obj) {
            str += this.traceStr(obj,i,depth);
         }
      }
      return str;
   }
   this.traceStr = function (obj,i,depth) {
      str = '';
      type = (typeof(obj[i])+'').toLowerCase();
      var unique = true;//!exists(this.unique_keys,i);
      str += this.charPac('---',depth+1)+'['+i+'] '+(type == 'object' && unique  ? '= Object (\n'+this.traceIt(obj[i],depth+2) : ' = '+obj[i]+',')+'\n';
      str += type == 'object' && unique  ? this.charPac('---',depth+1)+'),\n' : '';
      if(type == 'object') { this.unique_keys[i] = 1; }
      return str;
   }
   this.toString = function (obj,name) {
      // make a query string
      // this will remove all functions that are in the object
      // since only simple objects can be passed.
      var str = '';
      for (i in obj) {
         if (typeof(obj[i]) != 'function') {
            if(typeof(obj[i]) == 'object' || typeof(obj[i]) == 'array') {
               if(!name) { // single dimentional
                  str += this.toString(obj[i],i);
               } else { // multi dimentional
	              str += this.toString(obj[i],name+'['+i+']');
               }
            } else if (name) {
               str += name+'['+i+']='+escape(obj[i])+'&';
            } else {
               str += i+'='+escape(obj[i])+'&';
            }
         }
      }
      return str;
   }
}

function addslashes(str) {
   /*
    * Similar to the php addslashses before quotes. You should use escape and unescape instead.
    */
   str=str.replace(/\'/g,'\\\'');
   str=str.replace(/\"/g,'\\"');
//   str=str.replace(/\\/g,'\\\\');
   str=str.replace(/\0/g,'\\0');
   return str;
}

function stripslashes(str) {
   /*
    * removes slashes from quotes.
    */
   str=str.replace(/\\'/g,'\'');
   str=str.replace(/\\"/g,'"');
   str=str.replace(/\\\\/g,'\\');
   str=str.replace(/\\0/g,'\0');
   return str;
}

function plural(n) {
   /*
    * Gramar weather to say 1 set or 2 sets. You would pass to this in a string
    * num+' set'+plural(num)+' and it will return an s if you need it.
    */
   // pass a number if == 1 it will return an 's'
   if(typeof(n)!='number') { n=parseFloat(n); }
   return n==1 ? '' : 's';
}

function getLimitTextArea(id,limit,txt,style) {
    /*
     * returns a textarea that will count with every character that you type and
     * will not allow you to type more than the limit of characters. They can
     * see the counter running below as well as the limit.
     */
	str = '<textarea id="'+id+'" style="'+(style ? style : 'color:#999999;width:230px;font-family:arial;font-size:9pt;')+'" onKeyDown="javascript:limitText(\''+id+'\',\''+id+'Count\','+limit+');" onfocus="preInputText(\''+txt+'\',this,\'focus\');" onBlur="javascript:preInputText(\''+txt+'\',this,\'blur\');limitText(\''+id+'\',\''+id+'Count\','+limit+');">'+txt+'</textarea><br />'+"\n"+
		'<font>(Limit: '+limit+') Characters Left: </font><input type="text" id="'+id+'Count" value="0" disabled>';
	return str;
}

function limitText(fieldId, limitCountId, limitNum) {
	/*
	 * Limit the number of characters in a text field. Text fiels will be truncated so 
	 * this lets user know where they will be so.
	 */
	var fld = document.getElementById(fieldId);
	var limitCount = document.getElementById(limitCountId);
	if (fld.value.length > limitNum) {
		fld.value = fld.value.substring(0, limitNum);
	} else {
		limitCount.value = limitNum - fld.value.length;
	}
}

function PopUp () {
   /*
    * Create a popup window. Specify the parameters you want.
    * it will alert if the popup is blocked letting the user know that their
    * popup blocker in enabled.
    */
   this.name = 'popup';
   this.toolbar = 'no';
   this.scrollbars = 'yes';
   this.status = 'no';
   this.resizable = 'no';
   this.menubar = 'no';
   this.width = 320;
   this.height = 240;
   this.win = null;
   this.url = null;
   this.go = function (url) {
      this.url = url;
      var reWork = new RegExp('object','gi');
      try {
         this.win=window.open(url,this.name,'toolbar='+this.toolbar+',scrollbars='+this.scrollbar+',status='+this.status+',resizable='+this.resizable+',menubar='+this.menubar+',width='+this.width+',height='+this.height);
      } catch (e) { }
      if(!reWork.test(String(this.win))) {
         alert('Your popup blocker is enabled.');
      } 
   }
   this.write = function (str) {
      this.win.document.write(str);
   }
}

function bubbleSort(inputArray, start, rest) {
	start = start == null ? 0 : start;
	rest = rest == null ? inputArray.length : rest;
	for (var i = rest - 1; i >= start;  i--) {
		for (var j = start; j <= i; j++) {
			if (inputArray[j+1] < inputArray[j]) {
				var tempValue = inputArray[j];
				inputArray[j] = inputArray[j+1];
				inputArray[j+1] = tempValue;
      		}
   		}
	}
	return inputArray;
}


// start php js simulated functions
function is_array(ary) {
	var type = typeof(ary);
	return type == 'array' || type == 'object' ? true : false;
}

function array_keys( input, search_value, argStrict ) {
    // http://kevin.vanzonneveld.net
    // +   original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // +      input by: Brett Zamir (http://brettz9.blogspot.com)
    // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
    // *     example 1: array_keys( {firstname: 'Kevin', surname: 'van Zonneveld'} );
    // *     returns 1: {0: 'firstname', 1: 'surname'}
    
    var tmp_arr = {}, strict = !!argStrict, include = true, cnt = 0;
    var key = '';
    
    for (key in input) {
        include = true;
        if (search_value != undefined) {
            if( strict && input[key] !== search_value ){
                include = false;
            } else if( input[key] != search_value ){
                include = false;
            }
        }
        
        if (include) {
            tmp_arr[cnt] = key;
            cnt++;
        }
    }
    
    return tmp_arr;
}
// end php js simulated functions

/************************************** BASE CLASS *******************************/
/**
 * Base class for inherriting event, and ajax call functions.
 */
var Base = function() {
	if (arguments.length) {
		if (this == window) { // cast an object to this class
			Base.prototype.extend.call(arguments[0], arguments.callee.prototype);
		} else {
			this.extend(arguments[0]);
		}
	}
};

Base.version = "1.0.1";

Base.prototype = {
	eventListeners: new Array(),
	
	extend: function(source, value) {
		var extend = Base.prototype.extend;
		if (arguments.length == 2) {
			var ancestor = this[source];
			// overriding?
			if ((ancestor instanceof Function) && (value instanceof Function) &&
				ancestor.valueOf() != value.valueOf() && /\bbase\b/.test(value)) {
				var method = value;
			//	var _prototype = this.constructor.prototype;
			//	var fromPrototype = !Base._prototyping && _prototype[source] == ancestor;
				value = function() {
					var previous = this.base;
				//	this.base = fromPrototype ? _prototype[source] : ancestor;
					this.base = ancestor;
					var returnValue = method.apply(this, arguments);
					this.base = previous;
					return returnValue;
				};
				// point to the underlying method
				value.valueOf = function() {
					return method;
				};
				value.toString = function() {
					return String(method);
				};
			}
			return this[source] = value;
		} else if (source) {
			var _prototype = {toSource: null};
			// do the "toString" and other methods manually
			var _protected = ["toString", "valueOf"];
			// if we are prototyping then include the constructor
			if (Base._prototyping) _protected[2] = "constructor";
			for (var i = 0; (name = _protected[i]); i++) {
				if (source[name] != _prototype[name]) {
					extend.call(this, name, source[name]);
				}
			}
			// copy each of the source object's properties to this object
			for (var name in source) {
				if (!_prototype[name]) {
					extend.call(this, name, source[name]);
				}
			}
		}
		return this;
	},

	base: function() {
		// call this method from any other method to invoke that method's ancestor
	},
	
	
	addEventListener: function (eventType,objectReference,objectFunction) {
		/**
		 * Add event listeners to this oject.
		 */
		this.eventListeners.push({'type':eventType,'ref':objectReference,'fctn':objectFunction});
	},
	
	dispatchEvent: function (eventType,params) {
		/**
		 * Dispatch an event for this object
		 */
		params = typeof(params) == 'object' ? params : null;
		var evt = {'type':eventType,'params':params,'target':this};
		for(var i in this.eventListeners) {
			if(this.eventListeners[i].type == eventType) {
				var itm = this.eventListeners[i];
				if(typeof(itm.ref[itm.fctn]) == 'function') {
					if(typeof(AJAXQue) != 'undefined' && AJAXQue.debug) {
						AJAXQue.addDebug('&nbsp;&nbsp;&nbsp;<font style="color:#0000ff;">'+(typeof(this['class']) == 'string' ? this['class'] : this.name)+'::dispatchEvent({type:'+eventType+',params:'+params+',target:'+this+'});</font>');
					}
					itm.ref[itm.fctn](evt)
				};
			}
		}
	}
};

Base.extend = function(_instance, _static) {
	var extend = Base.prototype.extend;
	if (!_instance) _instance = {};
	// build the prototype
	Base._prototyping = true;
	var _prototype = new this;
	extend.call(_prototype, _instance);
	var constructor = _prototype.constructor;
	_prototype.constructor = this;
	delete Base._prototyping;
	// create the wrapper for the constructor function
	var klass = function() {
		if (!Base._prototyping) constructor.apply(this, arguments);
		this.constructor = klass;
	};
	klass.prototype = _prototype;
	// build the class interface
	klass.extend = this.extend;
	klass.implement = this.implement;
	klass.toString = function() {
		return String(constructor);
	};
	extend.call(klass, _static);
	// single instance
	var object = constructor ? klass : _prototype;
	// class initialisation
	if (object.init instanceof Function) object.init();
	return object;
};

Base.implement = function(_interface) {
	if (_interface instanceof Function) _interface = _interface.prototype;
	this.prototype.extend(_interface);
};

var Core = Base.extend({
	type: "",
	
	constructor: function(c,cn) {
		this['class'] = typeof(c) == 'string' ? c : 'core';
		this['classname'] = typeof(cn) == 'string' ? cn : 'CORE';
	},
	
	call: function (divid,ur,callbkStr,disable) {
		/**
		 * This is how all ajax calls should be made for a class. pass the divid you want the data to be written to if you want it written to a div when the data comes back.
		 * If you do not then pass null to the divid. 
		 * ur is your parameters. It must always contain a type parameter.
		 * callbk is the function that you want called when your ajax call returns data. If you pass a divid you most likely wont use this.
		 * if you do not pass a divid this would be how you use the data that is returned.
		 */
		ur['class'] = this['class'];
		ur['classname'] = this['classname'];
		if(typeof(ur.type) != 'undefined') {
			AJAXQue.add(divid,AJAX_CONTROLLER_PATH,ur,callbkStr,disable,this);
		} else {
			alert('type cannot be null '+traceAry(ur));
		}
	},
	
	callLater: function (fctn) {
		/**
		 * Pass a function to this and it will call this function after all other functions in the queue have processed.
		 * this is mainly used if you need to make multiple ajax calls and need something to happen once all of those are done
		 * you would call each of those an then call this one.
		 */
		if(fctn) {
			var ur = new URLRequest('type','wait');
			this.call(null,ur,fctn);
		}
	}
	
});


/*EXAMPLE 
(no examples)
*/