﻿//Object.prototype.merge=function(obj){
//    if((typeof this=="object")&&(obj)&&(typeof obj=="object"))
//        for(var arg in obj)
//            if((typeof obj[arg]=="object")&&(!obj[arg].length)){
//                if(!this[arg])this[arg]={};
//                this[arg].xpMerge(obj[arg]);
//            }else{this[arg]=(this[arg]||obj[arg]);}
//}
function xpMergeObjects(a,b){
    if((a)&&(typeof a=="object")&&(b)&&(typeof b=="object"))
    for(var arg in b)
        if((typeof b[arg]=="object")&&(!b[arg].length)){
            if(!a[arg])a[arg]={};
            xpMergeObjects(a[arg],b[arg]);
        }else{a[arg]=(a[arg]||b[arg]);}
}
if(typeof String.prototype.trim==="undefined"){String.prototype.trim=function(){return this.replace(/^[\xA0\s]*|[\xA0\s]*$/g,"");}}
function xpAssert(cond,msg,func){if(!cond){if(typeof func==="function")func();throw new Error(msg);}}
function xpCanConfigure(w){try{return(((w===null)||(typeof w==="undefined"))?0:((!w.xpConfigure)?0:1));}catch(ex){return 0;}}
function xpCanHandleEvent(w){try{return(((w===null)||(typeof w==="undefined"))?0:((!w.xpHandleEvent)?0:1));}catch(ex){return 0;}}
function xpCreateFormField(form,id,val){if(!form)return false;var e=document.createElement("input");e.type="hidden";e.id=id;e.name=id;e.value=val;form.appendChild(e);return e;}
function xpEmpty(o){return((o===null)||(typeof o==="undefined")||((typeof o==="string")&&(o.trim().length===0)))?1:0;}
function xpGet(id,w){if(!w)w=window;if(w.document.getElementById)return w.document.getElementById(id);return xpGetNonIE(id,w);}
function xpGetElementByName(n){if(document.getElementsByName)return document.getElementsByName(n);return xpGetNonIE(n);}
function xpGetElementsByClassName(cn,tn){ // cn = "class name", tn = "tag name"
    var a=[],b=[],r=new RegExp('\\b'+cn+'\\b');
    if(xpEmpty(tn))tn="*";
    var b=document.getElementsByTagName(tn);
    for(var i=0,imax=b.length;i<imax;i++){if(r.test(b[i].className))a.push(b[i]);}
    return a;
};
function xpGetFrameByName(n){for(var i=0,imax=window.frames.length;i<imax;i++)if(window.frames[i].name===n)return window.frames[i];return null;}
function xpGetFullYear(dt){var y=dt.getYear();if(y<1000)y+=1900;return y;}
function xpGetNonIE(id,w){if(!w)w=window;if(w.document.all)return w.document.all[id];if(w.document.layers){for(var i=0,imax=w.document.forms[0].length;i<imax;i++)if(w.document.forms[0].elements[i].name==id){return w.document.forms[0].elements[i];}}return null;}
function xpGetPageNameFromURL(url,sep){if(!sep)sep="/";var pos1=url.lastIndexOf(sep),pos2=url.indexOf("?");return(pos1==-1)?url:url.slice(pos1+1,((pos2!=-1)?pos2:url.length));}
function xpGetQueryStringValue(qs,key){if(xpEmpty(qs))return null;return xpParseQueryString(qs)[key];}
function xpGetRadioValue(n){var e=xpGetElementByName(n),val=null;if(!e)return null;for(var i=0,imax=e.length;i<imax;i++)if(e[i].checked)return e[i].value;return null;}
function xpGetSelectValue(ref,src){
    var e=((typeof ref==="object")?ref:xpGet(ref)),s="";if(!e||!e.options)return null;
    if(xpEmpty(src))src="value";
	for(var i=0,j=0,imax=e.options.length;i<imax;i++)if(e.options[i].selected){s+=((j>0)?",":"")+((src==="text")?e.options[i].text:e.options[i].value);j++;}
	return s;
}
function xpIndexOfArray(ary,itm){for(var i=ary.length-1;i>=0;i--)if(ary[i]===itm)return i;return -1;}
function xpIsChecked(id){var e=xpGet(id);if(!!e)return e.checked;return false;}
function xpIsNumeric(txt,validchars){
    if(!txt||(txt.length===0))return false;
	var chr,chars=(!!validchars)?validchars:"0123456789.",isnum=true,ftest=0;
	if(txt.length===0)return false;
	for(var i=txt.length-1;(i>=0)&&(isnum===true);i--){chr=txt.charAt(i);if(chars.indexOf(chr)===-1)isnum=false;}
    if(!isnum){ftest=parseFloat(txt);if((ftest!==0)&&(!isNaN(ftest)))isnum=true;}
	return isnum;
}
function xpIsWindow(o){return(xpTypeOf(o)==="object"&&!!o.setTimeout);}
function xpMergeQueryStrings(qs1,qs2,sort){
    if(!qs1&&!qs2)return "";
    try{
        if(!qs1)qs1="";if(!qs2)qs2="";
        var a1=qs1.split("&"),a2=qs2.split("&"),a3=[],aK=[],aV=[],aF=[],i,imax,pos,str="";
        for(i=0,imax=a1.length;i<imax;i++){
            a3=a1[i].split("=");
            if(xpEmpty(a3[0]))continue;
            aK[aK.length]=a3[0];
            aV[aV.length]=((!!a3[1])?a3[1]:"");
        }
        for(i=0,imax=a2.length;i<imax;i++){
            a3=a2[i].split("=");
            if(xpEmpty(a3[0]))continue;
            pos=xpIndexOfArray(aK,a3[0]);
            if(pos>=0){aV[pos]=((!!a3[1])?a3[1]:"");} // Overwrite the value in the 1st array
            else{aK[aK.length]=a3[0];aV[aV.length]=((!!a3[1])?a3[1]:"");}
        }
        if(sort){
            for(i=0,imax=aK.length;i<imax;i++)aF[aF.length]=aK[i]+"="+aV[i];
            aF.sort();
            for(i=0,imax=aF.length;i<imax;i++)str+=((i>0)?"&":"")+aF[i];
        }
        else{for(i=0,imax=aK.length;i<imax;i++)str+=((i>0)?"&":"")+aK[i]+"="+aV[i];}
        return str;
    }catch(ex){return "";}
}
function xpPadString(s,len,pc,dir){if(xpEmpty(s))s="";if(xpEmpty(pc))pc=" ";if(xpEmpty(dir)||((dir!=="r")&&(dir!=="l")))dir="r";while(s.length<=len){if(dir==="r"){s+=pc;}else{s=pc+s;}}return(s);}
function xpParseBoolean(s){if(xpEmpty(s))return 0;if(typeof s==="boolean")return ((s===true)?1:0);switch(s.toLowerCase()){case "0":case "false":return 0;case "1":case "true":return 1;default:return 1;}}
function xpParseQueryString(str){var a1=str.split("&"),a2=[],a3=[];for(var i=0,imax=a1.length;i<imax;i++){a2=a1[i].split("=");a3[a2[0]]=((!xpEmpty(a2[1]))?a2[1]:"");}return a3;}
function xpParseUri(sourceUri){
    // Adapted from the following article: http://badassery.blogspot.com/2007/02/parseuri-split-urls-in-javascript.html
    var uriPartNames=["source","protocol","authority","domain","port","path","directoryPath","fileName","query","anchor"],uri={},pos;
    var uriParts=new RegExp("^(?:([^:/?#.]+):)?(?://)?(([^:/?#]*)(?::(\\d*))?)?((/(?:[^?#](?![^?#/]*\\.[^?#/.]+(?:[\\?#]|$)))*/?)?([^?#/]*))?(?:\\?([^#]*))?(?:#(.*))?").exec(sourceUri);
    for(var i=0;i<10;i++){uri[uriPartNames[i]]=(uriParts[i]?uriParts[i]:"");}
    // Always end directoryPath with a trailing backslash if a path was present in the source URI.
    // Note that a trailing backslash is NOT automatically inserted within or appended to the "path" key
    if(uri.directoryPath.length>0){uri.directoryPath=uri.directoryPath.replace(/\/?$/, "/");}
    if(uri.fileName.length>0){pos=uri.fileName.lastIndexOf(".");uri.fileNameNoExt=uri.fileName.substring(0,((pos==-1)?uri.fileName.length.length:pos));}
    return uri;
}
function xpPrefixArrayItems(ary,prefix){for(var i=ary.length-1;i>=0;i--)ary[i]=prefix+ary[i];}
function xpProcessQueryStringItem(qs,key,func){
    if(xpEmpty(func))return "";
    var pairs=null,pair=null,keys=[],vals=[];
    if(!xpEmpty(qs))
        pairs=qs.split("&")
        if(!!pairs){
            for(var i=0,imax=pairs.length;i<imax;i++){
                pair=pairs[i].split("=");
                keys[keys.length]=pair[0];
                vals[vals.length]=((!xpEmpty(pair[1]))?pair[1]:"");
            }
        }
    var pos=xpIndexOfArray(keys,key);
    return func(keys,vals,pos);
}
function xpQueryStringAddItem(qs,key,val){return xpQueryStringSetItem(qs,key,val,true);}
// Example call: xpQueryStringAssemble(["key1","key2"],["value2","value2"]);
function xpQueryStringAssemble(keys,vals){if(xpEmpty(keys))return "";for(var i=0,imax=keys.length,pair=null,qs="";i<imax;i++){pair=keys[i]+"="+vals[i];qs+=((i>0)?"&":"")+pair;}return qs;}
function xpQueryStringItemExists(qs,key){return xpProcessQueryStringItem(qs,key,function(keys,vals,pos){if(pos!=-1)return true;return false;});}
function xpQueryStringSetItem(qs,key,val,add){return xpProcessQueryStringItem(qs,key,function(keys,vals,pos){if(pos!==-1){vals[pos]=val;}else if(add){keys[keys.length]=key;vals[vals.length]=val;}return xpQueryStringAssemble(keys,vals);});}
function xpQueryStringDeleteItem(qs,key){return xpProcessQueryStringItem(qs,key,function(keys,vals,pos){if(pos!==-1){keys.splice(pos,1);vals.splice(pos,1);}return xpQueryStringAssemble(keys,vals);});}
function xpRaiseEvent(eid,esender,edata,win){
    try{
        if(typeof edata==="string")edata=encodeURIComponent(edata);
        if((!xpEmpty(win))&&(xpCanHandleEvent(win))){win.xpHandleEvent(eid,esender,edata);return;}
        if((parent!=self)&&(xpCanHandleEvent(parent)))parent.xpHandleEvent(eid,esender,edata);
        if(xpCanHandleEvent(opener))opener.xpHandleEvent(eid,esender,edata);
        for(var i=0,imax=self.frames.length;i<imax;i++)if(xpCanHandleEvent(self.frames[i]))self.frames[i].xpHandleEvent(eid,esender,edata);
    }catch(ex){alert(ex.name+" in xpRaiseEvent(): "+ex.message+" ("+eid+")");}
}
function xpReplaceStringInArrayItems(aryIn,str,strReplace){var ary=aryIn.concat();for(var i=ary.length-1;i>=0;i--)if(typeof ary[i]==="string")ary[i]=ary[i].replace(str,strReplace);return ary;}
function xpSetElementValue(ref,val){
    var e=((typeof ref==="object")?ref:xpGet(ref));
    if(!e&&!!document.forms[0])e=xpCreateFormField(document.forms[0],ref,val);
    if((!!e)){e.value=val;if(e.value===val)return 1;}
    return 0;
}
function xpShow(r,s){ //r: ref,s: state
	var e=((typeof r==="object")?r:xpGet(r)),es; //es: endstate
	if(!e)return false;
	if(e.nodeType!=1)return false; // Only handle element nodes
	s=(((s===null)||(typeof s==="undefined"))?-1:s);
	if(typeof s==="boolean")s=xpParseBoolean(s);
	var tag=e.tagName;if(!tag)tag="unknown";
	switch(tag.toLowerCase()){
		case "input":e.checked=(s===-1)?((e.checked===false)?true:false):((s===1)?true:false);es=e.checked;break;
		default:e.style.display=(s===-1)?((e.style.display==="none")?"":"none"):((s===1)?"":"none");es=(e.style.display==="");
		break; //Works for <table>, too.
	}
	return es;
}
function xpTransferStyle(styleID,targetWin){
    try{
        var srcStyle=xpGet(styleID);
        if(!srcStyle||xpEmpty(srcStyle.innerHTML)||!targetWin){return false;}
        var targetDoc=targetWin.document;if(!targetDoc){return false;}
        var cssStr=srcStyle.innerHTML; // Get the style definitions in the source window
        var head2=targetDoc.getElementsByTagName("head");if(!head2||!head2[0])return false; // Get the -head- node of the target window
        var style2=targetDoc.createElement("style");style2.setAttribute("type","text/css");style2.setAttribute("id","inheritedStyle");
        if(style2.styleSheet){style2.styleSheet.cssText=cssStr;} // IE
        else{style2.appendChild(targetDoc.createTextNode(cssStr));} // w3c
        head2[0].appendChild(style2);
    }catch(ex){/*ignore any errors*/}
}
function xpTrim(s){return s.replace(/^[\xA0\s]*|[\xA0\s]*$/g,"");}
function xpTypeOf(o){
    if(o===null)return "null";
    if(typeof o==="undefined")return "undefined";
    if(typeof o==="object"){
        try{
            if(!!o.typeOf)return(o.typeOf);
            if((o.constructor===null)||(typeof o.constructor==="undefined"))return("object");
            var c=o.constructor.toString(),i1=c.indexOf("function"),i2=c.indexOf("("),r;
            if((i1>=0)&&(i2>=0)){r=c.substring(i1+"function".length,i2).trim();return((!xpEmpty(r))?r:(o.constructor.toString()));}
            return "object";
        }catch(ex){return("object");}
    }
    return (typeof o);
}
function xpValue(id){var e=xpGet(id);return((!!e)?e.value:null);}
function xpVisible(ref){
	var e=((typeof ref==="object")?ref:xpGet(ref)),visible;
	if(!e)return false;
	if(e.nodeType!==1)return false; // Only handle element nodes
	if(!e.style||!e.style.display||e.style.display==="")return true; // Display style is not defined, so default state is visible.
	var tag=e.tagName;if(!tag)tag="unknown";
	switch(tag.toLowerCase()){
		case "div":if(e.style.display==="block")return true;
		case "img":if(e.style.visibility==="visible")return true;
		case "table":if(e.style.display==="table"||e.style.display==="block")return true;
		default:return false;
	}
}
//------------------------------>>>
//    Class: XpObjectArray
//  Purpose: Represents an array of XpPortal objects.
// Requires: 
//   Author: Shawn McClure
//------------------------------>>>
function XpObjectArray(key){this.key=key;this.items=new Array();this.bindProperties();return this.items;}
XpObjectArray.prototype.add=function(o){if((o===null)||(typeof o==="undefined"))return false;this[this.length]=o;if((!xpEmpty(this.key))&&(!xpEmpty(o[this.key])))this[o[this.key]]=o;}
XpObjectArray.prototype.bindProperties=function(){for(p in this)if(p!=="items")this.items[p]=this[p];}
XpObjectArray.prototype.createHashTable=function(propName){for(var i=0,imax=this.length;i<imax;i++)this[this[i][propName]]=this[i];}
XpObjectArray.prototype.__createHashTable__=function(propName){for(i=0,imax=this.items.length;i<imax;i++)this.items[this.items[i][propName]]=this.items[i];}
