window.onload=onloadPageInit;
// --- global vars --- //
var loadedDetailsID=-1;
var aContentTypes=[];
var aContentProducts=[];
var aDownloads=[];
var myRequest;
var iTotalRecords=0;
var iSearchOptionNo=4;
var iCurrentRecIndex=0;
var iResultsRecTotal=0;
var sSearchForInData='';
var sWMR='';
var iVertScrollPos=0;
// --- user vars --- //
var sXmlDataFile='/apps/dlcenter/dcgroups.xml';
var sXmlDataFile2='/apps/dlcenter/dcdownloads.xml';
var sDownloadsRootURI='ftp://ftp1.adept.com';

function getXMLHTTPRequest() {
  var req=false;
  if(window.XMLHttpRequest) {
    try {req=new XMLHttpRequest();} catch(e) { req = false; }
  }else if(window.ActiveXObject){try{req=new ActiveXObject('Msxml2.XMLHTTP');}catch(e){
    try{req=new ActiveXObject('Microsoft.XMLHTTP');}catch(e){req=false;}
  }}
  return req;
}
function onloadPageInit(){
  //LOAD XML DATA
  myRequest=getXMLHTTPRequest();
  if (myRequest!=false) {
    //continue!
    loadXmlData(sXmlDataFile,'reqHandler');
  }else{
    //error! DEV-NOTE: This is not called when the XML doc is missing!
//#    alert('Sorry... an error occurred while loading the parts catalog data. Please close this webpage and try again. If you are still having problems, please contact the Webmaster.');
    document.getElementById('PageLoading').innerHTML='<center style="padding-top:50px;"><b><h3>PROBLEM LOADING PAGE</h3></b><br /><br />Sorry we had a problem loading the page properly. Please retry again and if you continue to have problem, please contact the webmaster and refer to ERROR CODE 1.</center>';
  }
}
function onloadPageInit2(){
  //LOAD MAIN DOWNLOADS XML DATA
  loadXmlData(sXmlDataFile2,'reqHandler2');
}
function onloadPageInit3(){
  //means we have successfully loaded Groups and Downloads - Finish Page initialization and get ready for use
  aContentTypes.sort(arraySortAlpha); //sort array alpha
  aContentProducts.sort(arraySortAlpha); //sort array alpha
  var el1=document.getElementById('SearchType');
  for(var i=0;i<aContentTypes.length;i++){
    var nopt=new Option(aContentTypes[i],  //text prop
	                    aContentTypes[i],  //value prop
						false,             //default selected
						false);            // selected
	el1.options[el1.options.length]=nopt;
  }
  el1=document.getElementById('SearchProduct');
  for(var i=0;i<aContentProducts.length;i++){
    var nopt=new Option(aContentProducts[i],  //text prop
	                    aContentProducts[i],  //value prop
						false,             //default selected
						false);            // selected
	el1.options[el1.options.length]=nopt;
  }
  sWMR+='Total Content Types (Added to Select Box): '+aContentTypes.length+'\nTotal Content Products (Added to Select Box): '+aContentProducts.length+'\n';
  var qs=new Querystring();if(qs.contains("debug")){var v1=qs.get("debug");if(v1=='true'){alert('WEBMASTER DEBUG REPORT\n\n'+sWMR);}}sWMR='';
  aContentTypes.length=0; //Cleanup Memory
  aContentProducts.length=0; //Cleanup Memory
  document.getElementById('PageLoading').style.display='none';
  document.getElementById('PageReady').style.display='';
}
function loadXmlData(url,ProcessedByHandler){
  myRand=parseInt(Math.random()*9999999999999999);
  var modurl=url+"?rand="+myRand;
  myRequest.open('GET', modurl, true);
  if(ProcessedByHandler=='reqHandler'){myRequest.onreadystatechange=reqHandler;}
  else{myRequest.onreadystatechange=reqHandler2;}
  myRequest.send('');
}
function reqHandler(){
  if (myRequest.readyState==4) {
    if (myRequest.status==200) {
      var xmlDocTmp=myRequest.responseXML;
      //DO ACTIONS AFTER SUCCESSFUL LOAD OF XML DATA!
	  var bSuccess=true;
	  bSuccess=processGroupsToArray(xmlDocTmp);
      //Check for error which would mean bad data in XML
	  if (bSuccess==true){
	    onloadPageInit2();
	  }else{
	    //Show problem loading page and give reason!
//#		alert('[DEBUG Unable to Parse XML Doc Result from AJAX Fetch');
	    document.getElementById('PageLoading').innerHTML='<center style="padding-top:50px;"><b><h3>PROBLEM LOADING PAGE</h3></b><br /><br />Sorry we had a problem loading the page properly. Please retry again and if you continue to have problem, please contact the webmaster and refer to ERROR CODE 12.</center>';
	  }
    }else{
	  //Unable to get XML document - i.e. missing or inaccessable!
//#	  alert('[DEBUG] Unable to load/access XML Doc: '+sXmlDataFile);
	  document.getElementById('PageLoading').innerHTML='<center style="padding-top:50px;"><b><h3>PROBLEM LOADING PAGE</h3></b><br /><br />Sorry we had a problem loading the page properly. Please retry again and if you continue to have problem, please contact the webmaster and refer to ERROR CODE 10.</center>';
	}
  }
}
function reqHandler2(){
  if(myRequest.readyState==4){
    if(myRequest.status==200){
      var xmlDocTmp=myRequest.responseXML;
	  var bSuccess=true;
	  bSuccess=processXmlToArray(xmlDocTmp);
      //Check for error which would mean bad data in XML
	  if (bSuccess==true){onloadPageInit3();}
	  else{
	    //Show problem loading page and give reason!
//#		alert('[DEBUG Unable to Parse XML Doc Result from AJAX Fetch');
 	    document.getElementById('PageLoading').innerHTML='<center style="padding-top:50px;"><b><h3>PROBLEM LOADING PAGE</h3></b><br /><br />Sorry we had a problem loading the page properly. Please retry again and if you continue to have problem, please contact the webmaster and refer to ERROR CODE 13.</center>';
	  }
    }else{
	  //Unable to get XML document - i.e. missing or inaccessable!
//#	  alert('[DEBUG] Unable to load/access XML Doc: '+sXmlDataFile2);
	  document.getElementById('PageLoading').innerHTML='<center style="padding-top:50px;"><b><h3>PROBLEM LOADING PAGE</h3></b><br /><br />Sorry we had a problem loading the page properly. Please retry again and if you continue to have problem, please contact the webmaster and refer to ERROR CODE 11.</center>';
	}
  }
}
function processXmlToArray(xmlDownloadsDoc){
  var ret=true,NodeRecCount=0,iRecErrCtr=0,bAdd=true,t,s,x,iDID;
  try{
    NodeRecCount=xmlDownloadsDoc.getElementsByTagName('di').length;
    if(NodeRecCount!=0){
      var rows=xmlDownloadsDoc.getElementsByTagName('di');
      for(var i=0,row;row=rows[i];i++){
	    bAdd=true;
        t=new Array();
	    try{ //These should never be blank!
		  x=1;
	      iDID=row.getElementsByTagName('did')[0].firstChild.nodeValue;
          t.did=iDID;
		  x=2;
	      s=row.getElementsByTagName('dtype')[0].firstChild.nodeValue;
	      s=s.trim();
          t.dtype=s;
		  x=3;
	      s=row.getElementsByTagName('dprod')[0].firstChild.nodeValue;
	      s=s.trim();
          t.dprod=s
		  x=4;
	      s=row.getElementsByTagName('dpriv')[0].firstChild.nodeValue;
          t.dpriv=s;
		  x=5;
	      s=row.getElementsByTagName('ddesc')[0].firstChild.nodeValue;
	      s=s.trim();
          t.ddesc=s;
		  x=6;
	      s=row.getElementsByTagName('dfn')[0].firstChild.nodeValue;
	      s=s.trim();
          t.dfn=s;
	      s='';
	    }catch(ex){
	      iRecErrCtr+=1;
		  bAdd=false;
		  if(iRecErrCtr==1){sWMR+='//---Downloads XML to Array Problem Records (Not Adding To Array)---//\n';}
		  sWMR+='('+iRecErrCtr+') DownloadID: '+iDID+', Required Field Missing/Invalid: ';
		  if(x==2){sWMR+='dtype (Type)';}
		  else if(x==3){sWMR+='dprod (Product)';}
		  else if(x==4){sWMR+='dpriv (PubPriv)';}
		  else if(x==5){sWMR+='ddesc (Description)';}
		  else if(x==6){sWMR+='dfn (Filename), Possible Cause: (1) Value Not Set (2) Type Does not match to anything';}
		  sWMR+='\n';
	    }
	    if(bAdd==true){
	      try{ //Process optionals
	        s=row.getElementsByTagName('dtitle')[0].firstChild.nodeValue;
	      }catch(ex){s='';}
	      t.dtitle=s;
	      try{s=row.getElementsByTagName('dimg')[0].firstChild.nodeValue;
	      }catch(ex){s='';}
	      t.dimg=s;
	      try{s=row.getElementsByTagName('dsr')[0].firstChild.nodeValue;
	      }catch(ex){s='';}
	      t.dsr=s;
	      try{s=row.getElementsByTagName('dfs')[0].firstChild.nodeValue;
	      }catch(ex){s='';}
	      t.dfs=s;
	    }
        if(bAdd==true){aDownloads[aDownloads.length]=t;}
      }
    }else{
	  ret=false;
	  //DEBUG alert('There are no Downloads XML Records!');
	}
  }catch(ex){alert('[DEBUG] Error (102): '+ex);ret=false;}
  iTotalRecords=aDownloads.length;
  sWMR+='\nTotal XML Records: '+NodeRecCount+'\nTotal XML Records Skipped Due To Errors: '+iRecErrCtr+'\nTotal Records In Array: '+iTotalRecords+'\n\n';
  return ret;
}
function processGroupsToArray(xmlGroupsDoc){
  var ret=true,s='',NodeRecCount=0,iRecCnt=0;
  try{
    //Process GroupTypes    
	NodeRecCount=xmlGroupsDoc.getElementsByTagName('contenttype').length;
    if(NodeRecCount!=0){
      var rows = xmlGroupsDoc.getElementsByTagName('contenttype');
      for(var i=0,row;row=rows[i];i++){
	    try{
		  s=row.getElementsByTagName('name')[0].firstChild.nodeValue;
		  s=s.trim();
		  if((s!='')&&(isblank(s)==false)){++iRecCnt;aContentTypes[aContentTypes.length]=s;}
		}catch(ex){;}
	  }
	  //Check for logical errors
	  if(iRecCnt==0){ret=false;}
	}else{
	  //Logical Problem - ContentTypes should not be blank as the search select box will not contain anything
	  ret=false;
	}
	if(ret){
    //Process GroupProducts    
	  NodeRecCount=xmlGroupsDoc.getElementsByTagName('product').length;
      if(NodeRecCount!=0){
        var rows = xmlGroupsDoc.getElementsByTagName('product');
        for(var i=0,row;row=rows[i];i++){
	      try{
		    s=row.getElementsByTagName('name')[0].firstChild.nodeValue;
		    s=s.trim();
		    if((s!='')&&(isblank(s)==false)){++iRecCnt;aContentProducts[aContentProducts.length]=s;}
		  }catch(ex){;}
	    }
	    //Check for logical errors
	    if(iRecCnt==0){ret=false;}
	  }else{
	    //Logical Problem - ContentTypes should not be blank as the search select box will not contain anything
	    ret=false;
	  }
	}
  }catch(ex){ret=false;}
  return ret;
}
function doSearch(){
  try{
    searchOptionChange(iSearchOptionNo);
    var s='',b=true,s2='';
	if(iSearchOptionNo==1){
	  s='Download ID';
	  s2=document.getElementById('downloadid').value;
	  s2=s2.trim();
	  if(s2==''){
	    s2='Download ID cannot be blank.';
		b=false;
	  }else{
	    if(isNaN(s2)){
		  s2='Download ID must be a number.';
		  b=false;
		}
	  }
	}else if(iSearchOptionNo==2){
	  s='Type or Product';
	  if((document.getElementById('SearchType').value=='')&&(document.getElementById('SearchProduct').value=='')){
	    s2='Select an option from either the "Types" or "Product" dropdown options';
		b=false;
	  }
	}else if(iSearchOptionNo==3){
	  s='Description';
	  s2=document.getElementById('textsearch').value;
	  s2=s2.trim();
	  if(s2==''){
	    s2='Search Description cannot be blank.';
		b=false;
	  }
	}else if(iSearchOptionNo==4){s='All Downloads';}
	else{b=false;}
	if(!b){
	  alert('Cannot begin search for the following reasons:\n\n'+s2);
	  sSearchForInData='';
	}else{
	  sSearchForInData=s2;
	  doSearchFor();
	}
  }catch(ex){alert('[DEBUG] Error (301): '+ex);}
  return false;
}
function doSearchFor(){
  iCurrentRecIndex=0;
  iResultsRecTotal=0;
  document.getElementById('SearchResults').innerHTML='';
  doWork(function (value,total){
    if(iCurrentRecIndex<iTotalRecords){
	  //Progress Code Updates Here
	  try{
	    document.getElementById('SearchResultsStatus').innerHTML='- Please wait... Search '+parseInt((100 * value / total))+'% Complete, Total Matches: '+iResultsRecTotal;
	  }catch(ex){;}
    }
  });
}
function doWork (progressFn) {
  // Initialize a few things here...
  var iCtr=0,iVal=-2,bIsMatch=false,sTmp,sTmp1='',htmlDynList='',bShowAll=false,iDID,iRecIdx=-1;
  if(iSearchOptionNo==2){
    var sType=document.getElementById('SearchType').value;
	var sProd=document.getElementById('SearchProduct').value;
  }
  var sVal=sSearchForInData;
  if(iSearchOptionNo==4){bShowAll=true;}
  htmlDynList='<table class="sortable">';
  htmlDynList+='<thead><tr><td class="tblsortableth1"><b>Download ID</b></td><td class="tblsortableth2"><b>Description</b></td></tr></thead>';
  htmlDynList+='<tbody>';
  try{
    sTmp='';
	matchexp=RegExp.escape(sVal);
    var re = new RegExp(matchexp,"i");
  }catch(ex){
    matchexp=sVal;
    alert('[DEBUG] Error (300): '+ex);
  }
  iCtr=0;
  (function () {
    //PROCESS 100 Records!
    var zEnd;
    if((iCurrentRecIndex+100)<iTotalRecords){zEnd=iCurrentRecIndex+100;}else{zEnd=iTotalRecords;}
    for(var x=iCurrentRecIndex;x<zEnd;x++){
      // --- DO WORK --------------------------- //
      bIsMatch=false;
      iDID=aDownloads[x].did;
      if(!bShowAll){
        if(iSearchOptionNo==1){
		  //Search for Download ID
		  if(iDID==sVal){bIsMatch=true;}
        }else if(iSearchOptionNo==2){
		  //Types and/or Product Match
		  if((sType=='')||(sProd=='')){
		    if(sType!=''){if(aDownloads[x].dtype==sType){bIsMatch=true;}}
		    if(sProd!=''){if(aDownloads[x].dprod==sProd){bIsMatch=true;}}
		  }else{
		    //exclusive match on both
			if((aDownloads[x].dtype==sType)&&(aDownloads[x].dprod==sProd)){bIsMatch=true;}
		  }
        }else if(iSearchOptionNo==3){
		  //Text Search Matching
		  try{
		  sTmp=aDownloads[x].dtitle;
		  if(sTmp.match(re)){bIsMatch=true;}
		  sTmp=aDownloads[x].ddesc;
		  if(sTmp.match(re)){bIsMatch=true;}
		  }catch(ex){;}
		}
	  }
      if((bIsMatch)||(bShowAll)){
        iCtr++;
		htmlDynList+='<tr valign="top">';
		sTmp='<a href="javascript:showDetails('+iDID+','+x+');">'+iDID+'</a>'; //iDID
		htmlDynList+='<td class="bottomline rightline">'+sTmp+'</td>'; //Download ID
		if(aDownloads[x].dtitle!=''){sTmp='<b>'+aDownloads[x].dtitle+'</b><br />'+aDownloads[x].ddesc;}else{sTmp=aDownloads[x].ddesc;}
		htmlDynList+='<td class="bottomline">'+sTmp+'</td></tr>'; //Description
        if(iSearchOptionNo==1){
		  //Download ID Search - We only expect to find one record
		  iRecIdx=x;
		  break;
		}
      }
      // ----------------------------------------- //
    }
    iCurrentRecIndex=zEnd;
    iResultsRecTotal=iCtr;
    if((iCurrentRecIndex<iTotalRecords)&&(iRecIdx==-1)){
      progressFn(iCurrentRecIndex, iTotalRecords); // Inform app of progress
      setTimeout(arguments.callee,0); // Process next chunk
    }else{
      //!
      // --- FINISHED PROCESSING ----------------- //
      if (iResultsRecTotal==0) {
        iResultsRecTotal=0;
        htmlDynList+='<tr valign=top>';
        htmlDynList+='<td colspan="2" height="60" align="center" valign="middle"><b>';
		if(iSearchOptionNo==1){htmlDynList+='No Downloads Found Matching the Download ID "'+sVal+'".';}
		else if(iSearchOptionNo==3){htmlDynList+='No Downloads Found Matching the Search "'+sVal+'".';}
		else{htmlDynList+='No Downloads Found Matching your Search Criteria';}
		htmlDynList+='</b></td>';
        htmlDynList+='</tr>';
      }
      htmlDynList+='</tbody></table>';
      document.getElementById('SearchResults').innerHTML=htmlDynList;
      htmlDynList='';
	  try{
	    document.getElementById('SearchResultsStatus').innerHTML='- Search Complete, Total Matches: '+iResultsRecTotal;
	  }catch(ex){;}
	  if((iSearchOptionNo==1)&&(iResultsRecTotal==1)){
	    //Download ID Search with 1 found record - Update Download Details Tab and Display?
		showDetails(aDownloads[iRecIdx].did,iRecIdx);
	  }
      // ------------------------------------------ //
    }
  })();
}
function searchDisplayAllDownloads(){
  searchOptionChange(4);
  doSearch();
}
function searchOptionChange(vSearchOptionNo){
  var s='';
  if(vSearchOptionNo!=iSearchOptionNo){
    //Highlight new search option section
	try{
	  s='searchOption'+vSearchOptionNo+'_txt';
	  CSSClass.add(document.getElementById(s),'blkclr');
	  s='searchOption'+vSearchOptionNo+'_no';
	  CSSClass.add(document.getElementById(s),'soActive');
	  s='searchOption'+vSearchOptionNo+'_no';
	  CSSClass.remove(document.getElementById(s),'soInactive');
	}catch(ex){;}
	//Unhighlight?
    if(iSearchOptionNo!=0){
	  //We need to unhighlight previously highlighted search option
	  try{
	    s='searchOption'+iSearchOptionNo+'_txt';
	    CSSClass.remove(document.getElementById(s),'blkclr');
	    s='searchOption'+iSearchOptionNo+'_no';
	    CSSClass.add(document.getElementById(s),'soInactive');
	    s='searchOption'+iSearchOptionNo+'_no';
	    CSSClass.remove(document.getElementById(s),'soActive');
	  }catch(ex){;}
	}
	iSearchOptionNo=vSearchOptionNo;
  }else{
	try{
	  s='searchOption'+vSearchOptionNo+'_txt';
	  CSSClass.add(document.getElementById(s),'blkclr');
	  s='searchOption'+vSearchOptionNo+'_no';
	  CSSClass.add(document.getElementById(s),'soActive');
	  s='searchOption'+vSearchOptionNo+'_no';
	  CSSClass.remove(document.getElementById(s),'soInactive');
	}catch(ex){;}
  }
}
function searchElementKeyPress(vSearchOptionNo){
  if(vSearchOptionNo!=iSearchOptionNo){searchOptionChange(vSearchOptionNo);}
}
function showDetails(vID,vRecIdx){
  //Check if we have loaded the details for this download
  if(loadedDetailsID!=vID){
    //IF NOT LOADED - LOAD DETAILS FOR vID AND THEN SHOW DETAILS TAB
    loadedDetailsID=vID;
    document.getElementById('DownloadInfo').innerHTML='Download Details (ID '+vID+')';
    buildDD(vID,vRecIdx);
  }
  //Get current position of results so we can go back to this position
  try{
    var scrolledY;
    if(self.pageYOffset){scrolledY=self.pageYOffset;}
    else if(document.documentElement && document.documentElement.scrollTop){scrolledY=document.documentElement.scrollTop;}
    else if(document.body){scrolledY=document.body.scrollTop;}
    iVertScrollPos=scrolledY;
  }catch(ex){iVertScrollPos=0;}
  showPane('DD');
}
function buildDD(vID,vRecIdx){
  var aLoadedDetailsItem=[];
  aLoadedDetailsItem=aDownloads[vRecIdx];
  var sFN=aLoadedDetailsItem.dfn;
  var s='<table class="ddtable"><tr>';
  s+='<td class="w150 bottomline rightline">Download ID</td>';
  s+='<td class="bottomline">'+aLoadedDetailsItem.did+'</td></tr><tr>';
  s+='<td class="w150 bottomline rightline">Title</td>';
  s+='<td class="bottomline">'+aLoadedDetailsItem.dtitle+'</td></tr><tr>';
  s+='<td class="w150 bottomline rightline">Description</td>';
  s+='<td class="bottomline">'+aLoadedDetailsItem.ddesc+'</td></tr><tr>';
  s+='<td class="w150 bottomline rightline">Download Type</td>';
  s+='<td class="bottomline">'+aLoadedDetailsItem.dtype+'</td></tr><tr>';
  s+='<td class="w150 bottomline rightline">Product</td>';
  s+='<td class="bottomline">'+aLoadedDetailsItem.dprod+'</td></tr><tr>';
  s+='<td class="w150 bottomline rightline">System Requirements</td>';
  s+='<td class="bottomline">'+aLoadedDetailsItem.dsr+'</td></tr><tr>';
  s+='<td class="w150 rightline">File Size</td>';
  s+='<td class="">'+aLoadedDetailsItem.dfs+'</td></tr></table>';
  //ActionBar  
  s+='<div style="display:block;padding-left:168px;margin-top:10px;margin-bottom:20px;">';
  s+='<div class="ddactionbar"><ul><li><a href="'+sDownloadsRootURI+aLoadedDetailsItem.dfn+'">Download</a></li><li><a href="javascript:showPane(\'DS\');">Back</a></li></ul></div></div>';
  document.getElementById('DetailsTable').innerHTML=s;
}
function showPane(vPane){
  ele1=document.getElementById('SearchTab');
  ele2=document.getElementById('DetailsTab');
  if(vPane=='DD'){
    if(ele2.style.display=='none'){
      ele1.style.display='none';
      ele2.style.display='';
	  try{
	    CSSClass.remove(document.getElementById('tabDownloadSearch'),'active');
	    CSSClass.add(document.getElementById('tabDownloadDetails'),'active');
      }catch(ex){;}
	  //Scroll to top of page
	  try{window.scroll(0,0);}catch(ex){;}
	}
  }else{
    if(ele1.style.display=='none'){
      ele2.style.display='none';
      ele1.style.display='';
	  try{
	    CSSClass.add(document.getElementById('tabDownloadSearch'),'active');
	    CSSClass.remove(document.getElementById('tabDownloadDetails'),'active');
      }catch(ex){;}
	  try{if(!isNaN(iVertScrollPos)){window.scroll(0,iVertScrollPos);}}catch(ex){alert('[DEBUG] Error (20): '+ex);}
	}
  }
}
// ---- common functions ---- //
var CSSClass={};
CSSClass.is=function(e,c){
  if(typeof e=="string")e=document.getElementById(e);
  var classes=e.className;
  if(!classes)return false;
  if(classes==c)return true;
  return e.className.search("\\b"+c+"\\b")!=-1;
};
CSSClass.add=function(e,c){
  if(typeof e=="string")e=document.getElementById(e);
  if(CSSClass.is(e,c))return;
  if(e.className)c=" "+c;
  e.className+=c;
};
CSSClass.remove=function(e,c){
  if(typeof e=="string")e=document.getElementById(e);
  e.className=e.className.replace(new RegExp("\\b"+c+"\\b\\s*","g"),"");
};  
function isblank(s) {
  for(var i=0; i<s.length;i++) {
    var c=s.charAt(i);
    if((c!=' ')&&(c!='\n')&&(c!='\t')) return false;
  }
  return true;
}
String.prototype.trim = function(){return this.replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,"");}
String.prototype.fulltrim = function(){return this.replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,"").replace(/\s+/g," ");}
function arraySortAlpha(a,b){
  //Sorts Array in case insensitive whereas default sort will be case sensitive!
  var al=a.toLowerCase();
  var bl=b.toLowerCase();
  if(al>bl){return 1;
  }else if(al<bl){return -1;
  }else{return 0;}
  //return a.toLowerCase()-b.toLowerCase(); //Problem with IE7 but works with IE8. Gives error at sort(thisfunc) as: Number Expected
}
function Querystring(qs) { // optionally pass a querystring to parse
  this.params={};
  if(qs==null) qs=location.search.substring(1,location.search.length);
  if(qs.length==0) return;
  // Turn <plus> back to <space>
  // See: http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4.1
  qs=qs.replace(/\+/g, ' ');
  var args=qs.split('&'); // parse out name/value pairs separated via &
  // split out each name=value pair
  for(var i=0;i<args.length;i++){
    var pair = args[i].split('=');
    var name = decodeURIComponent(pair[0]);
    var value = (pair.length==2) ? decodeURIComponent(pair[1]) : name;
    this.params[name]=value;
  }
}
Querystring.prototype.get = function(key, default_) {
  var value=this.params[key];
  return (value!=null) ? value : default_;
}
Querystring.prototype.contains = function(key) {
  var value=this.params[key];
  return (value!=null);
}
RegExp.escape = function(text){
  if(!arguments.callee.sRE){
    var specials=['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\', '$', '^', '=', ':', '"']; //ADDED $^=!:
    arguments.callee.sRE=new RegExp('(\\'+specials.join('|\\')+')','g');
  }
  return text.replace(arguments.callee.sRE,'\\$1');
}
