﻿//---------->>>  Global Variables  <<<----------//
var XpDebug=true;
//---------->>>  Miscellaneous Methods  <<<----------//
function xpAssert(cond,msg,func){if(!cond){if(typeof func=="function")func();throw new Error(msg);}}
function xpIndexOfArray(ary,itm){for(var i=ary.length-1;i>=0;i--)if(ary[i]==itm)return i;return -1;}
function xpNoEnter(){return !(window.event&&window.event.keyCode==13);}
//---------->>>  Window Methods  <<<----------//
function xpCanConfigure(win){try{return(((win==null)||(typeof win=="undefined"))?0:((!win.xpConfigure)?0:1));}catch(ex){return 0;}}
function xpCanReceive(win){try{return(((win==null)||(typeof win=="undefined"))?0:((!win.xpReceive)?0:1));}catch(ex){return 0;}}
function xpTransmit(id,data,url){
    try{
        if((parent!=self)&&(xpCanReceive(parent)))parent.xpReceive(id,data,url);
        if(xpCanReceive(opener))opener.xpReceive(id,data,url);
        for(var i=0,imax=self.frames.length;i<imax;i++)if(xpCanReceive(self.frames[i]))self.frames[i].xpReceive(id,data,url);
    }catch(ex){alert(ex.name+" in xpTransmit(): "+ex.message);}
}
function xpOpenWindow(code,open){
    if(!code||(code.length==0))code="separate";
    if(!open||(open.length==0))open=false;
    var w="_blank",options="resizable=yes,menubar=yes,titlebar=yes,scrollbars=yes,toolbar=yes,status=yes,location=yes,width=700,height=500";
    switch(code.toLowerCase()) {
        case "same":w="_self";break;
	    case "separate":w="XpResults";if(open)window.open("about:blank","XpResults",options);break;
	    case "multiple":tmpName="XpResults"+Math.round(Math.random()*10);w=tmpName;if(open)window.open("about:blank",tmpName,options);break;
    }
    return w;
}
//---------->>>  Date Methods  <<<----------//
function xpGetFullYear(dt){var y=dt.getYear();if(y<1000)y+=1900;return y;}
//---------->>>  String Methods  <<<----------//
function xpGetBaseURL(url){var pos=url.indexOf("?");return(url.substring(0,((pos==-1)?url.length:pos)));}
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 xpIsEmpty(o){return((o==null)||(typeof o=="undefined"))?1:0;}
function xpIsEmptyString(o){return((o==null)||(typeof o=="undefined")||(o.length==0))?1:0;}
function xpIsNumeric(txt,validchars) {
    if(!txt||(txt.length==0))return false;
	var chr,chars=(!!validchars)?validchars:"0123456789.",isnum=true;
	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;}
	return isnum;
}
function xpPadString(s,len,pc,dir){
    if(s==null)s="";
    if(pc==null)pc=" ";
    if(dir==null)dir="r";
    if((dir!="r")&&(dir!="l"))dir="r";
    while(s.length<=len){
        if(dir=="r"){s+=pc;}
        else{s=pc+s;}
    }
    return(s);
}
function xpParseBoolean(str){if(xpIsEmptyString(str))return 0;switch(str.toLowerCase()){case "0":case "false":return 0;case "1":case "true":return 1;default:return 1;}}
function xpTrim(s){return s.replace(/^[\xA0\s]*|[\xA0\s]*$/g,"");}
//---------->>>  QueryString Methods  <<<----------//
function xpGetQueryStringValue(qs,key){if(xpIsEmptyString(qs))return null;return xpParseQueryString(qs)[key];}
function xpMergeQueryStrings(qs1,qs2){
    if(!qs1&&!qs2)return "";
    try{
        var a1=qs1.split("&"),a2=qs2.split("&"),a3=[],aK=[],aV=[],i,imax,pos,str="";
        for(i=0,imax=a1.length;i<imax;i++){
            a3=a1[i].split("=");
            if(xpIsEmptyString(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(xpIsEmptyString(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]:"");}
        }
        for(i=0,imax=aK.length;i<imax;i++)str+=((i>0)?"&":"")+aK[i]+"="+aV[i]; // Construct query string
        return str;
    }catch(ex){alert(ex.name+" in xpMergeQueryStrings(): "+ex.message);}
}
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]]=((!xpIsEmptyString(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={};
    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(/\/?$/, "/");}
    return uri;
}
function xpProcessQueryStringItem(qs,key,func){
    if(xpIsEmptyString(qs)||xpIsEmpty(func))return false;
    var pairs=qs.split("&"),pair=null,keys=[],vals=[];
    for(var i=0,imax=pairs.length;i<imax;i++){
        pair=pairs[i].split("=");
        keys[keys.length]=pair[0];
        vals[vals.length]=((!xpIsEmpty(pair[1]))?pair[1]:null);
    }
    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(xpIsEmpty(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);});
}
//---------->>>  DOM Methods  <<<----------//
function xpAddSelectOption(list,val,txt,idx){
    if(!list)return null;
    if(!idx)idx=-1;
    o=document.createElement("option");
    o.value=val;o.text=txt;
    list.add(o,idx);
}
function xpClearSelect(list){
    if(!list)return null;
    while(list.options.length)list.remove(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 xpGetElementNonIE(id){
    if(document.all)return document.all[id];
	if(document.layers){for(var i=0,imax=document.forms[0].length;i<imax;i++)if(document.forms[0].elements[i].name==id){return document.forms[0].elements[i];}}
	return null;
}
function xpGetElement(id){if(document.getElementById)return document.getElementById(id);return xpGetElementNonIE(id);}
function xpGetElementsByAttribute(att,val)
{
    var aryElm=new Array(),aryMatch=new Array(),pattern;
    aryElm=((document.all)?document.all:document.getElementsByTagName("*"));
    for(var i=0,imax=aryElm.length;i<imax;i++){
        if(att=="class"){
            pattern=new RegExp("(^| )"+val+"( |$)");
            if(aryElm[i].className.match(pattern))aryMatch[aryMatch.length]=aryElm[i];
        }
        else if(att=="for"){
            if(aryElm[i].getAttribute("htmlFor")||aryElm[i].getAttribute("for")){
                if(aryElm[i].htmlFor==val)aryMatch[aryMatch.length]=aryElm[i];
            }
        }
        else if(aryElm[i].getAttribute(att)==val)aryMatch[aryMatch.length]=aryElm[i];
  }
  return aryMatch;
}
function xpGetElementByName(n){if(document.getElementsByName)return document.getElementsByName(n);return xpGetElementNonIE(n);}
function xpGetElementValue(id){var e=xpGetElement(id);return((!!e)?e.value:null);}
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 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 xpGetSelectedItems(ref,src){
    var e=((typeof ref=="object")?ref:xpGetElement(ref)),s="";
	if(!e||!e.options)return false;
	if(!!src){switch(src.toLowerCase()){case "value","text":break;default:src="value";break;}}
    else{src="value";}
	for(var i=0,j=0,imax=e.options.length;i<imax;i++)if(e.options[i].selected){s+=((j>0)?",":"")+((src=="value")?e.options[i].value:e.options[i].text);j++;}
	return s;
}
function xpGetSelectValue(ref){
    var e=((typeof ref=="object")?ref:xpGetElement(ref)),s="";
	if(!e||!e.options)return false;
	for(var i=0,j=0,imax=e.options.length;i<imax;i++)if(e.options[i].selected){s+=((j>0)?",":"")+e.options[i].value;j++;}
	return s;
}
function xpSetElementValue(ref,val){
    var e=((typeof ref=="object")?ref:xpGetElement(ref));
    if(!e&&!!document.forms[0])e=xpCreateFormField(document.forms[0],ref,val);
    if((!!e)&&(!!e.value)){e.value=val;if(e.value==val)return 1;}
    return 0;
}
function xpIsChecked(id){var e=xpGetElement(id);if(!!e)return e.checked;return false;}
//---------->>>  HTML Forms  <<<----------//
function xpSubmitForm(formref,action,method,target,reqstr){
    try{
        xpAssert(!xpIsEmpty(action),"Argument 'action' cannot be empty.");
        var form=xpLoadForm(formref,reqstr);
        if(!!form){form.action=action;form.target=target;form.submit();return true;}
        return false;
    }catch(ex){alert(ex.name+" in xpSubmitForm(): "+ex.message);}
}
//---------->>>  DHTML Positioning and Sizing  <<<----------//
function xpGetElementHeight(elmRef){
    var h=0,elm=((typeof elmRef=="object")?elmRef:xpGetElement(elmRef));
    if(!elm)return -1;
    if(elm.offsetHeight){h=elm.offsetHeight;}
    else if(elm.clip&&elm.clip.height){h=elm.clip.height;}
    else if(elm.style&&elm.style.pixelHeight){h=elm.style.pixelHeight;}
    return parseInt(h);
}
function xpGetElementWidth(elmRef){                                                                                                                                        
    var w=0,elm=((typeof elmRef=="object")?elmRef:xpGetElement(elmRef));
    if(!elm)return -1;
    if(elm.offsetWidth){w=elm.offsetWidth;}
    else if(elm.clip&&elm.clip.width){w=elm.clip.width;}
    else if(elm.style&&elm.style.pixelWidth){w=elm.style.pixelWidth;}
    return parseInt(w);
}
function xpGetScrollingPosition(){
    var xy=[0,0];
    if(window.pageYOffset)xy=[window.pageXOffset,window.pageYOffset];
    if(document.documentElement&&document.documentElement.scrollTop&&document.documentElement.scrollTop>0)
        {xy=[document.documentElement.scrollLeft,document.documentElement.scrollTop];}
    else if(document.body.scrollTop)
        {xy=[document.body.scrollLeft,document.body.scrollTop];}
    return xy;
}
// Get the size of the browser window
function xpGetWindowSize(win){
    if(xpIsEmpty(win))win=window;
    var xy=[0,0],doc=win.document;
    if (win.innerWidth)
        {xy=[win.innerWidth,win.innerHeight];}
    else if(doc.documentElement&&doc.documentElement.clientWidth&&doc.documentElement.clientWidth!=0)
        {xy=[doc.documentElement.clientWidth,doc.documentElement.clientHeight];}
    else
        {xy=[doc.getElementsByTagName('body')[0].clientWidth,doc.getElementsByTagName('body')[0].clientHeight];}
    return xy;
}
function xpToggleElement(ref,state){
	var e=((typeof ref=="object")?ref:xpGetElement(ref));
	if(!e)return false;
	if(e.nodeType!=1)return false; // Only handle element nodes
	state=(((state==null)||(typeof state=="undefined"))?-1:state);
	var tagName=e.tagName;if(!tagName)tagName="unknown";
	switch(tagName.toLowerCase()){
		case "div":e.style.display=(state==-1)?((e.style.display=="none")?"block":"none"):((state==1)?"block":"none");break;
		case "img":e.style.visibility=(state==-1)?((e.style.visibility=="hidden")?"visible":"hidden"):((state==1)?"visible":"hidden");break;
		case "input":e.checked=(state==-1)?((e.checked==false)?true:false):((state==1)?true:false);break;
		default:e.style.display=(state==-1)?((e.style.display=="none")?"":"none"):((state==1)?"":"none");break;
	}
}
function xpGetFormString(id){
    var e=xpGetElement(id),s="";
    if(!e||!e.elements||!e.elements.length)return false;
    for(var i=0,j=0,imax=e.elements.length;i<imax;i++){
        f=e.elements[i];if(!f.id||f.id=="__VIEWSTATE")continue;
        switch(f.tagName.toLowerCase()){
		    case "select":s+=((j>0)?"&":"")+f.id+"="+xpGetSelectValue(f);j++;break;
		    default:break;
	    }
    }
    return s;
}
//---------->>>  Style Methods  <<<----------//
function xpGetStyleClass(doc,className){
    //URL: http://www.faqts.com/knowledge_base/view.phtml/aid/2147/fid/128
    var sh=doc.styleSheets,s,r;
    if(!sh)return false;
	for(s=0;s<sh.length;s++){
        if(sh[s].rules){for(r=0;r<sh[s].rules.length;r++)if(sh[s].rules[r].selectorText=='.'+className)return sh[s].rules[r];}
		else if(sh[s].cssRules){for(r=0;r<sh[s].cssRules.length;r++)if(sh[s].cssRules[r].selectorText=='.'+className)return sh[s].cssRules[r];}
	}
	return null;
}
function xpTransferStyle(srcWin,targetWin){
    if(!srcWin||!targetWin)return false;
    var doc1=srcWin.document,doc2=targetWin.document;
    if(!doc1||!doc2)return false;
    var style1=doc1.getElementsByTagName("style"); // Get the -style- node of the source window
    if(!style1||!style1[0]||xpIsEmptyString(style1[0].innerHTML))return; // Exit if there are no style definitions to transfer
    var cssStr=style1[0].innerHTML; // Get the style definitions in the source window
    var head2=doc2.getElementsByTagName("head");if(!head2||!head2[0])return; // Get the -head- node of the target window
    var style2=doc2.createElement("style");style2.setAttribute("type","text/css");
    if(style2.styleSheet){style2.styleSheet.cssText=cssStr;} // IE
    else{style2.appendChild(doc2.createTextNode(cssStr));} // w3c
    head2[0].appendChild(style2);
}
//---------->>>  Event Methods  <<<----------//
function xpAddEventHandler(o,e,h){ //o=(Object to attach event to),e=(Event name, like "onclick"),h=(Handler function)
    if(!o||!e||!h)return false;
    if(o.addEventListener){o.addEventListener(e,h,false);}else if(o.attachEvent){o.attachEvent(e,h);}else{o[e]=h;}
}
function xpRemoveEventHandler(o,e,h){
    if(!o||!e||!h)return false;
    if(o.removeEventListener){o.removeEventListener(e,h,false);}else if(o.detachEvent){o.detachEvent(e,h);}else{o[e]=null;}
}
//------------------------------>>>
//    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(); // Attach any child class properties to the Array object
    return this.items;
}
XpObjectArray.prototype.add=function(o){
    if((o==null)||(typeof o=="undefined"))return false;
    this[this.length]=o;
    if((!xpIsEmpty(this.key))&&(!xpIsEmpty(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(propertyName){
    for(var i=0,imax=this.length;i<imax;i++)this[this[i][propertyName]]=this[i];
}
XpObjectArray.prototype.__createHashTable__=function(propertyName){
    for(i=0,imax=this.items.length;i<imax;i++)this.items[this.items[i][propertyName]]=this.items[i];
}