function findObj(n, d) { //v4.01
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
  if(!x && d.getElementById) x=d.getElementById(n); return x;
}

/* INCLUDES */
includePath = "";
includedFiles = new Array();
includedCounter = 0;
function setIncludePath (path) {
	if (path.substring(path.length-1)!='/') path+='/';
	includePath = path;
	//alert(includePath);
}

function include_once(src,pth)
{
	filepath = get_path(src,pth);
	if (!in_array(filepath, includedFiles)) {
		include (src, pth);
	}
}
function include (src,pth) {
	filepath = get_path(src,pth);
	document.write('<script type="text/javascript" src="'+filepath+'"><\/script>');
	track_included(filepath);
}
function include_css_once(src,pth)
{
	filepath = get_path(src,pth);
	if (!in_array(filepath, includedFiles)) {
		include_css (src, pth);
	}
}
function include_css (src,pth) {
	filepath = get_path(src,pth);
	//document.write('<script type="text/javascript" src="'+filepath+'"><\/script>');
	document.write('<style type="text/css"><!-- @import url("'+filepath+'"); --></style>');
	track_included(filepath);
}
function get_path(src,pth)
{
	var path=pth||includePath||'';
	//alert(path);
	return path+src;
}
function track_included(src)
{
	includedFiles[includedCounter++] = src;
}
/* INCLUDES */




// 1k DHTML API - standards version
d=document;l=d.layers;op=navigator.userAgent.indexOf('Opera')!=-1;px='px';
function gE(e,f){if(l){f=(f)?f:self;var V=f.document.layers;if(V[e])return V[e];for(var W=0;W<V.length;)t=gE(e,V[W++]);return t;}if(d.all)return d.all[e];return d.getElementById(e);}
function sE(e){l?e.visibility='show':e.style.visibility='visible';}
function hE(e){l?e.visibility='hide':e.style.visibility='hidden';}
function sZ(e,z){l?e.zIndex=z:e.style.zIndex=z;}
function sX(e,x){l?e.left=x:op?e.style.pixelLeft=x:e.style.left=x+px;}
function sY(e,y){l?e.top=y:op?e.style.pixelTop=y:e.style.top=y+px;}
function sW(e,w){l?e.clip.width=w:op?e.style.pixelWidth=w:e.style.width=w+px;}
function sH(e,h){l?e.clip.height=h:op?e.style.pixelHeight=h:e.style.height=h+px;}
function sC(e,t,r,b,x){l?(X=e.clip,X.top=t,X.right=r,X.bottom=b,X.left=x):e.style.clip='rect('+t+px+' '+r+px+' '+b+px+' '+x+px+')';}
//function wH(e,h){if(l){Y=e.document;Y.open();Y.write(h);Y.close();}if(e.innerHTML)e.innerHTML=h;}
function wH(e,h){if(l){Y=e.document;Y.open();Y.write(h);Y.close();}else if(e.innerHTML)e.innerHTML=h;else return false; return true;}




/////////////////////////////////////////////////////////////////
/**
 * a ClassObject should be extended by any object that needs setters and getters (then use addProperty to set these up)
 * use extends_ClassObject(this) at the top of the object constructor.
 */
function ClassObject ()
{
	this.addProperty = function (sType, sName, vValue) {
       
       if (fullTypeOf (vValue) != sType) {
           alert("Property " + sName + " must be of type " + sType + ".");
           return;
       }
     
       this[sName] = vValue;
       
       var sFuncName = sName.charAt(0).toUpperCase() + sName.substring(1, sName.length);
       
       this["get"+sFuncName] = function () { return this[sName] };
       this["set"+sFuncName] = function (vNewValue) {

                if (fullTypeOf (vNewValue) != sType) {
                   alert("Property "+sName+" must be of type "+sType+".");
                   return;
               }

               var vOldValue = this["get" + sFuncName]();
               var oEvent = {  
                       propertyName: sName,  
                       propertyOldValue: vOldValue,  
                       propertyNewValue: vNewValue,  
                       returnValue: true  
                       };
               this.onpropertychange(oEvent);
               if (oEvent.returnValue) {
                       this[sName] = oEvent.propertyNewValue;
               }

       };
	}

	//default onpropertychange() method – does nothing
	this.onpropertychange = function (oEvent) {
		 
	}
} // end class classObject

/**
 * allows exension of objects
 */
function inheritFrom(/* Object */ aThis, /* Object */ aParent)
{
  var excp;
  for (var property in aParent) {
    try {
      aThis[property] = aParent[property];
    } catch(excp) {
    }
  }
}
function extends_ClassObject (aThis)
{
	inheritFrom(aThis, new ClassObject());
}

/////////////////////////////////////////////////////////////////

function isAlien(a) {
   return isObject(a) && typeof a.constructor != 'function';
}

function isArray(a) {
    return isObject(a) && a.constructor == Array;
}

function isBoolean(a) {
    return typeof a == 'boolean';
}

function isEmpty(o) {
    var i, v;
    if (isObject(o)) {
        for (i in o) {
            v = o[i];
            if (isUndefined(v) && isFunction(v)) {
                return false;
            }
        }
    }
    return true;
}

function isFunction(a) {
    return typeof a == 'function';
}

function isNull(a) {
    return typeof a == 'object' && !a;
}

function isNumber(a) {
    return typeof a == 'number' && isFinite(a);
}

function isInteger(a) {
	return isNumber(a) && a % 1 == 0
}

function isFloat(a) {
	return isNumber(a) && a % 1 != 0
}

function isObject(a) {
    return (a && typeof a == 'object') || isFunction(a);
}

function isString(a) {
    return typeof a == 'string';
}

function isUndefined(a) {
    return typeof a == 'undefined';
}

function fullTypeOf(a)
{
	if (isUndefined(a))	return 'undefined';
	if (isString(a))	return 'string';
	if (isArray(a))		return 'array';
	if (isNull(a))		return 'null';
	if (isObject(a))	return 'object';
	if (isInteger(a))	return 'integer';
	if (isFloat(a))		return 'float';
	if (isBoolean(a))	return 'boolean';
	return typeof a;
}


/** PHP SUBSTITUTES 
 * Missing some PHP functions when working in javascript? Here are some substitutes.
 */
function str_replace(iSearch, iReplace, iSubject)
{
	if (isArray(iSearch)) {
		if (isArray(iReplace)) {
			// if not same number of elements in search and replace, fail!
			if (iSearch.length != iReplace.length) return false;
			
			for (key in iSearch) {
				iSubject = single_replace (iSearch[key], iReplace[key], iSubject);
			}
			return iSubject;
		} else if (isString(iReplace)) {
			for (key in iSearch) {
				iSubject = single_replace (iSearch[key], iReplace, iSubject);
			}
			return iSubject;
		} else {
			return false;
		}
	} else if (isString(iSearch)) {
		return (isString(iReplace))?single_replace (iSearch, iReplace, iSubject):false;
	} else {
		return false;
	}
}

function single_replace (iSearch, iReplace, iSubject)
{
	reg = new RegExp (iSearch, 'gi');
	return iSubject.replace(reg, iReplace);
}

/**
 * Searches haystack for needle and returns TRUE  if it is found in the array, FALSE otherwise.
 * If the third parameter strict is set to TRUE then the in_array() function will also check the types of the needle in the haystack.
 * Note: If needle is a string, the comparison is done in a case-sensitive manner. 
 */
function in_array(needle, haystack, bool_strict)
{
	strict = bool_strict||false;
	if (strict) {
		for (key in haystack) {
			if (needle == haystack[key] && fullTypeOf(needle) == fullTypeOf(haystack[key])) {
				return true;
			}
		}
	} else {
		for (key in haystack) {
			 if (needle == haystack[key]) {
				return true; 
			 }
		}
	}
	return false;
}
/* PHP SUBSTITUTES */
