var browser_type = '';
if( navigator.userAgent.indexOf( 'Opera' ) != -1 )
   browser_type = 'Opera';
else if( navigator.userAgent.indexOf( 'Safari' ) != -1 )
   browser_type = 'Safari';
else if( navigator.userAgent.indexOf( 'Gecko' ) != -1 )
   browser_type = 'Gecko';
else if( navigator.userAgent.indexOf( 'MSIE' ) != -1 )
   browser_type = 'IE';  
else
   browser_type = 'NS';

String.prototype.trim = function() {
  return this.replace(/^\s+|\s+$/g, '');
}

String.prototype.striphtml = function() {
	return this.replace(/(<([^>]+)>)/ig,"");
}

String.prototype.stripjs = function() {
	var tmp = this.replace(/(<script[^>]*>.*<\/script[^>]*>)*/ig,'');
	tmp = tmp.replace(/<script[^>]*>/ig,'');
	return tmp;
}

Number.prototype.format =  function(decimalNum, bolCommas) { 
	if (isNaN(parseInt(this))) 
		return "";
	var tmpNum = this;
	var iSign = this < 0 ? -1 : 1; /* Get sign of number*/
	
	/* Adjust number so only the specified number of numbers after the decimal point are shown.*/
	tmpNum *= Math.pow(10,decimalNum);
	tmpNum = Math.round(Math.abs(tmpNum))
	tmpNum /= Math.pow(10,decimalNum);
	tmpNum *= iSign; /* Readjust for sign*/
	
	/* Create a string object to do our formatting on*/
	var tmpNumStr = new String(tmpNum);

	/* See if we need to put in the commas*/
	if (bolCommas && (this >= 1000 || this <= -1000)) {
		var iStart = tmpNumStr.indexOf(".");
		if (iStart < 0)
			iStart = tmpNumStr.length;

		iStart -= 3;
		while (iStart >= 1) {
			tmpNumStr = tmpNumStr.substring(0,iStart) + "," + tmpNumStr.substring(iStart,tmpNumStr.length)
			iStart -= 3;
		}		
	}

	return tmpNumStr; /* Return our formatted string!*/
}


if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

Array.prototype.removeAllEntries = function(c) {
	for (var f=this.length-1; f>=0; f--) {
		if (this[f]==c) {
			this.splice(f,1);
		}
	}
}

/*************
this function will take a string and split it into equal specified parts and return as array
**************/
function splitN(intext, splitlen) {
	var tmparr = new Array();
	var textLen = intext.length;
	if (textLen > splitlen) {
		var si = 0;
		var ei = splitlen;
		while (si < textLen) {
			if (ei > textLen) 
				ei = textLen;
			tmparr.push(intext.substring(si, ei));
			si = ei;
			ei = ei + splitlen;
		}
	}	else {
		tmparr.push(intext);
	}
	return tmparr;
}

/*************
this function will take any object, expand and display the content to the browser)
**************/
function explain(obj,rec){
	var s = "";
	s += explaininner(obj,0,rec);
	alert(s);
}
/*************
this function is a recursive subset for the function above ... only call above function
**************/
function explaininner(obj,lvl,rec) {
	var rx = "";
	var sp = lvl+"";
	for (x=1; x<=lvl; x++) {
		sp+="    ";
	}
	for (var key in obj) {
		var k = obj[key]; 
	  if (typeof k.length == "number") {
			rx += "\n"+sp+"-"+key+":"+k.toString();
		} else if (typeof k == "object") {
			rx += "\n"+sp+"-"+key;
			if (rec || (!rec && lvl==0))
				rx += explaininner(k, lvl+1, rec);
		} else {
			rx += "\n"+sp+"-"+key+":"+k;
		}
	}
	return rx;
}	

/*************
this removes x'' from a string
**************/
function rmxId(rstr){
	return rstr.substring(0,2)=="x'"?rstr.substring(2,rstr.length-1):rstr;
}

/*************
this adds x'' if necessary to a string
**************/
function xId(dstr){
	return dstr.substring(0,2)=="x'"?dstr:"x'"+dstr+"'";
}

function getWindowHeight() {
	var windowHeight=0;
	if (typeof(window.innerHeight)=='number')	{
		windowHeight=window.innerHeight;
	}	else {
		if (document.documentElement && document.documentElement.clientHeight){
			windowHeight = document.documentElement.clientHeight;
		} else {
			if (document.body && document.body.clientHeight) {
				windowHeight = document.body.clientHeight;
			}
		}
	}
	return windowHeight;
}

function getWindowWidth() {
	var windowWidth=0;
	if (typeof(window.innerWidth)=='number'){
		windowWidth=window.innerWidth;
	}	else {
		if (document.documentElement && document.documentElement.clientWidth)	{
			windowWidth = document.documentElement.clientWidth;
		}	else {
			if (document.body && document.body.clientWidth)	{
				windowWidth = document.body.clientWidth;
			}
		}
	}
	return windowWidth;
}

function changecss(theClass,element,value) {
	var cssRules;
	if (document.all) {
		cssRules = 'rules';
	}	else if (document.getElementById) {
		cssRules = 'cssRules';
	}
	for (var S = 0; S < document.styleSheets.length; S++){
		for (var R = 0; R < document.styleSheets[S][cssRules].length; R++) {
			if (document.styleSheets[S][cssRules][R].selectorText == theClass) {
				document.styleSheets[S][cssRules][R].style[element] = value;
			}
		}
	}	
}

function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}

/*************
Formats the date with the given date mask. The mask is returned and the internal date is not altered.
**************/
Date.prototype.formatDate = function(strMask){
	/* Create the values for each part of the potential date mask.*/
	var x = this.getMonth()+1;
	var objParts = {
		"d": this.getDate(),
		"dd": (this.getDate().toString().length == 1) ? ("0" + this.getDate()) : this.getDate(),
		"ddd": [ "Sun","Mon","Tue","Wed","Thu","Fri","Sat" ][ this.getDay() ],
		"dddd": [ "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday" ][ this.getDay() ],
		"m": x,
		"mm": (x.toString().length == 1) ? ("0" + x) : x,
		"mmm": [ "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" ][ this.getMonth() ],
		"mmmm": [ "January","February","March","April","May","June","July","August","September","October","November","December" ][ this.getMonth() ],
		"yy": this.getYear().toString().substring( 1, 3 ),
		"yyyy": this.getFullYear()
		}
	 
	/* Check to see if we have special date formatting options.*/
	switch ( strMask ){
		case "short":
			return( objParts[ "m" ] + "/" + objParts[ "d" ] + "/" + objParts[ "yyyy" ] );
			break;
		 
		case "medium":
			return( objParts[ "mmm" ] + " " + objParts[ "d" ] + ", " + objParts[ "yyyy" ] );
			break;
		 
		case "long":
			return( objParts[ "mmmm" ] + " " + objParts[ "d" ] + ", " + objParts[ "yyyy" ] );
			break;
		 
		case "full":
			return( objParts[ "dddd" ] + ", " + objParts[ "mmmm" ] + " " + objParts[ "d" ] + ", " + objParts[ "yyyy" ] );
			break;
		 
		default:
			/* There was no special date formatting, so just use the mask.*/
			return(
				strMask.replace(
					new RegExp( "(d{1,4}|m{1,4}|y{4}|y{2})", "gi" ),
					function( $1 ){
						return( objParts[ $1 ] );
						})
				);
			break;
	}
}

/*************
generic time format
**************/
Date.prototype.formatTime = function(){
	var a_p = "";
	var curr_hour = this.getHours();
	if (curr_hour < 12)
		a_p = "AM";
	else
		a_p = "PM";
	if (curr_hour == 0)
		curr_hour = 12;
	if (curr_hour > 12)
		curr_hour = curr_hour - 12;
	var curr_min = this.getMinutes();
	curr_min = curr_min + "";
	if (curr_min.length == 1)
		curr_min = "0" + curr_min;
	return curr_hour+":"+curr_min+" "+a_p;
}

function whoCalledMe(a) {
 	alert("Called by: \n" + a.callee.caller.toString()); 
 	for (var x=0; x<a.length; x++) { 
 		alert("Argument " + x + ": " + a[x]); 
 	}
}

/*************
converts a string to be safe for db, js, html, tech_id, int, decimal, date
**************/
String.prototype.quote = function( quotetype, default_value )
{
   if( !default_value )
      default_value = '';

	/* Database quote: ' -> ''*/
	if( quotetype == 'db' )
	{
	   var tmp = '' + this;
		return tmp.replace(/\'/g,"''");
   }

	/* Javascript quote: ' -> \' and " -> \" and \n --> \\n and \r --> \\r*/
	else if( quotetype == 'js' )
	{
	   var tmp = '' + this;
		return tmp.replace(/\\/g, "\\\\").replace(/\'/g, "\\'").replace(/\"/g, '\\"').replace(/\n/g, "\\n").replace(/\r/g, "\\r");
	}

   /* HTML quote: < to &lt; and > to &gt; and " to &quot; and & to &amp;*/
	else if( quotetype == 'html' )
	{
	   var tmp = '' + this;
	   return tmp.replace(/\</g, "&lt;").replace(/\>/g, "&gt;").replace(/\"/g, "&quot;").replace(/\&/g, "&amp;");
	}

	/* tech_id quote: make sure string is of format x'12345678901234567890123456'*/
	/* Returns "raw" tech_id on success, or blank string on failure*/
	else if( quotetype == 'tech_id' )
	{
	   var tmp = '' + this;
	   if( tmp.length != 26 && tmp.length != 29 )
	      return default_value;
	   tmp = rmxId( tmp );
	   for( var i = 0; i < 26; i++ )
	   {
	      var c = tmp.charAt(i);
	      if( c != '0' && c != '1' && c != '2' && c != '3' && c != '4' && c != '5' && c != '6' && c != '7' && c != '8' && c != '9' )
	         return default_value;
	   }
	   return xId(tmp);
	}
	
	/* int quote: make sure string only contains 0123456789-*/
	else if( quotetype == 'int' )
	{
	   var tmp = '' + this;
	   tmp = tmp.replace(/[^\d\-]/g,'');
	   var tmpint = parseInt( tmp );
	   if( isNaN( tmpint ) )
	      return default_value;
	   return tmpint;
	}

	/* decimal quote: make sure string only contains 0123456789-.*/
	else if( quotetype == 'decimal' )
	{
	   var tmp = '' + this;
	   tmp = tmp.replace(/[^\d\-\.]/g,'');
	   var tmpfloat = parseFloat( tmp );
	   if( isNaN( tmpfloat ) )
	      return default_value;
	   return tmpfloat;
	}

   /* date quote: accepts dates in any of these formats, with any delimiter character:*/
   /*             YYYY-MM-DD, MM-DD-YYYY, MM-DD-YY, YYYYMMDD, MMDDYY*/
   /* returns a blank string if date does not verify.*/
   else if( quotetype == 'date' )
   {
      var tmp = '' + this;
      tmp = tmp.trim().replace(/[\D]/g,'/');

	  /* make sure the user isn't submitting 00/00/0000.  CUR-3983 */
      zerotmp = tmp;
	  if (parseInt(zerotmp.replace(/\D/g,''),10) == 0)
		return '';
      
      if( tmp.length == 8 && tmp.indexOf('/') == -1 ) /* the date is in a format without delimiter characters*/
      {
         /* attempt to guess the proper date format*/
         if( tmp.charAt(0) == '2' && (tmp.charAt(1) == '0' || tmp.charAt(1) == '1' ) )
         {
            /* guessing that this is YYYY/MM/DD*/
            tmp = tmp.substr( 0, 4 ) + '/' + tmp.substr( 4, 2 ) + '/' + tmp.substr( 6, 2 );
         }
         /* Otherwise, assume MM/DD/YYYY or MM/DD/YY*/
         else
            tmp = tmp.substr( 0, 2 ) + '/' + tmp.substr( 2, 2 ) + '/' + tmp.substr( 4, 4 );
      }
      else if( tmp.length == 6 && tmp.indexOf('/') == -1 ) /* again, no delimiter characters*/
      {
         /* assume MM/DD/YY*/
         var tmpyear = parseInt( tmp.substr( 4, 2 ),10 );
         if( tmpyear < 75 )
            tmpyear += 2000;
         else
            tmpyear += 1900;
         tmp = tmp.substr( 0, 2 ) + '/' + tmp.substr( 2, 2 ) + '/' + tmpyear;
      }
      else if (tmp.match(/^[0-9]{1,2}\/[0-9]{1,2}\/[0-9]{1,2}$/)) {
     		var tmpyear = parseInt(tmp.substr(tmp.lastIndexOf("/")+1).replace(/^[^1-9]/,''));
         if( tmpyear < 75 )
            tmpyear += 2000;
         else
            tmpyear += 1900;
         tmp = tmp.substr( 0, tmp.indexOf("/") ) +"/"+ tmp.substr(  tmp.indexOf("/")+1, (tmp.lastIndexOf("/")- (tmp.indexOf("/")+1)))+"/" + tmpyear;
      }
   
      var tmpdate = new Date( tmp );
      if( isNaN( tmpdate ) )
         return default_value;
      else{
		var tmpyear = tmpdate.getFullYear();
		var stddate = (tmpdate.getMonth()+1) + '/' + tmpdate.getDate() + '/' + tmpyear;
		return stddate;
	}
   }
}

/*************
initialCaps - Capitalizes the first letter of all words in a String
**************/
String.prototype.initialCaps = function(){
	return this.replace( /\b\w+\b/g, function (word) { 
		return word.substring(0,1).toUpperCase() + 	word.substring(1).toLowerCase()  
	});			
}


/*************
MASK FUNCTION - used to format strings to specifications - http://jira.fbsdata.com/confluence/x/RR8
**************/
String.prototype.mask = function(mask) {
	if (!mask) return this;  // return original string if no mask is passed in
	
	// variables
	var newString = '';
	var reverse = (mask.match(/\!$/)) ? true : false ; // if there is a ! at the end of the mask, this must be processed from right to left
	
	// if reverse has been established, remove the ! at the end of the mask
	if (reverse)
		mask = mask.substring(0, mask.length-1);
	
	// establish beginning and ending of loop
	var loopPosition = (reverse) ? mask.length-1 : 0 ;
	var loopEnd = (reverse) ? -1 : mask.length ;
	var stringPosition = (reverse) ? this.length-1 : 0 ;
	var stringEnd = (reverse) ? -1 : this.length ;
	var caseModifier = null; // used if < or > are invoked, forcing characters to be all lower or upper case
	var absoluteModifier = false // used to detect (\\), which denote that then next character must be present
	var absoluteCharacter = null; // used as a placeholder to reduce code
	
	// setup loop
	while (loopPosition != loopEnd) {
		
		// find the next characters in the mask and the string
		var stringChar = (stringPosition == stringEnd) ? null : this.charAt(stringPosition) ;
		var maskChar = mask.charAt(loopPosition);
		
		// if this is reverse, look ahead one character to see if an absoute modifier is in place (\\)
		// also: don't check the first character in the mask, nothing can possibly proceed it
		if (reverse && loopPosition-1 != loopPosition && mask.charAt(loopPosition-1) == '\\')
			absoluteModifier = true;
		
		// if this is an absolute character (escaped by \\), set a placeholder variable and force the switch statement to default
		if (absoluteModifier) {
			absoluteCharacter = maskChar;
			maskChar = 'N';
		}
		
		// iterate here, as we may have a situation where a continue is called
		(reverse) ? loopPosition-- : loopPosition++ ;
				
		// process the mask character
		switch (maskChar) {
			
			case '>': // all characters after this must be uppercase
				caseModifier = 'uppercase';
				continue;
				break;
			
			case '<': // all characters after this must be lowercase
				caseModifier = 'lowercase';
				continue;
				break;
			
			case '\\': // the next character must be an exact match, used to escape
				absoluteModifier = (reverse) ? false : true;
				continue;
				break;
			
			case '0': // required digit
				if (stringChar) {
					var stringMatch = stringChar.match(/\d/);
					var stringToAdd = (stringMatch) ? stringChar : '0' ;
					newString = (reverse) ? stringToAdd + newString : newString + stringToAdd ;
					(reverse) ? stringPosition-- : stringPosition++ ;
				}
				else newString = (reverse) ? '0' + newString : newString + '0' ; // force zero if no digit is present
				break;
			
			case '9': // optional digit
				if (stringChar) {
					var stringMatch = stringChar.match(/\d/);
					if (stringMatch) {
						newString = (reverse) ? stringChar + newString : newString + stringChar ;
						(reverse) ? stringPosition-- : stringPosition++ ;
					}
				}
				break;
			
			case '#': // required digit, space, plus, or minus
				if (stringChar) {
					var stringMatch = stringChar.match(/\d|-|\+|\s/);
					var stringToAdd = (stringMatch) ? stringChar : ' ' ;
					newString = (reverse) ? stringToAdd + newString : newString + stringToAdd ;
					(reverse) ? stringPosition-- : stringPosition++ ;
				}
				else newString = (reverse) ? '0' + newString : newString + '0' ; // force zero if no digit is present
				break;
			
			case 'L': // required letter
				if (stringChar) {
					var stringMatch = stringChar.match(/[a-z]|[A-Z]/);
					if (stringMatch) {
						
						// handle any case modifiers (<) or (>)
						if (caseModifier == 'lowercase')
							newString = (reverse) ? stringChar.toLowerCase() + newString : newString + stringChar.toLowerCase() ;
						else if (caseModifier == 'uppercase')
							newString = (reverse) ? stringChar.toUpperCase() + newString : newString + stringChar.toUpperCase() ;
						else
							newString = (reverse) ? stringChar + newString : newString + stringChar ;
						
						(reverse) ? stringPosition-- : stringPosition++ ;
					}
					else { // force X if no letter is present
						if (caseModifier == 'lowercase')
							newString = (reverse) ? 'x' + newString : newString + 'x' ;
						else
							newString = (reverse) ? 'X' + newString : newString + 'X' ;
					}
				}
				break;
			
			case '?': // optional letter
				if (stringChar) {
					var stringMatch = stringChar.match(/[a-z]|[A-Z]/);
					if (stringMatch) {
						
						// handle any case modifiers (<) or (>)
						if (caseModifier == 'lowercase')
							newString = (reverse) ? stringChar.toLowerCase() + newString : newString + stringChar.toLowerCase() ;
						else if (caseModifier == 'uppercase')
							newString = (reverse) ? stringChar.toUpperCase() + newString : newString + stringChar.toUpperCase() ;
						else
							newString = (reverse) ? stringChar + newString : newString + stringChar ;
							
						(reverse) ? stringPosition-- : stringPosition++ ;
					}
				}
				break;
			
			case 'A': // required letter or digit
				if (stringChar) {
					var stringMatch = stringChar.match(/[a-z]|[A-Z]|\d/);
					if (stringMatch) {
						
						// handle any case modifiers (<) or (>)
						if (caseModifier == 'lowercase')
							newString = (reverse) ? stringChar.toLowerCase() + newString : newString + stringChar.toLowerCase() ;
						else if (caseModifier == 'uppercase')
							newString = (reverse) ? stringChar.toUpperCase() + newString : newString + stringChar.toUpperCase() ;
						else
							newString = (reverse) ? stringChar + newString : newString + stringChar ;
						
						(reverse) ? stringPosition-- : stringPosition++ ;
					}
					else { // force X if no letter is present
						if (caseModifier == 'lowercase')
							newString = (reverse) ? 'x' + newString : newString + 'x' ;
						else
							newString = (reverse) ? 'X' + newString : newString + 'X' ;
					}
				}
				break;
			
			case 'a': // optional letter or digit
				if (stringChar) {
					var stringMatch = stringChar.match(/[a-z]|[A-Z]|\d/);
					if (stringMatch) {
						
						// handle any case modifiers (<) or (>)
						if (caseModifier == 'lowercase')
							newString = (reverse) ? stringChar.toLowerCase() + newString : newString + stringChar.toLowerCase() ;
						else if (caseModifier == 'uppercase')
							newString = (reverse) ? stringChar.toUpperCase() + newString : newString + stringChar.toUpperCase() ;
						else
							newString = (reverse) ? stringChar + newString : newString + stringChar ;
							
						(reverse) ? stringPosition-- : stringPosition++ ;
					}
				}
				break;
			
			case '&': // required character or space
				if (stringChar) {
					var stringMatch = stringChar.match(/./);
					if (stringMatch) {
						
						// handle any case modifiers (<) or (>)
						if (caseModifier == 'lowercase')
							newString = (reverse) ? stringChar.toLowerCase() + newString : newString + stringChar.toLowerCase() ;
						else if (caseModifier == 'uppercase')
							newString = (reverse) ? stringChar.toUpperCase() + newString : newString + stringChar.toUpperCase() ;
						else
							newString = (reverse) ? stringChar + newString : newString + stringChar ;
						
						(reverse) ? stringPosition-- : stringPosition++ ;
					}
					else { // force X if no letter is present
						if (caseModifier == 'lowercase')
							newString = (reverse) ? 'x' + newString : newString + 'x' ;
						else
							newString = (reverse) ? 'X' + newString : newString + 'X' ;
					}
				}
				break;
			
			case 'C': // optional character or space
				if (stringChar) {
					var stringMatch = stringChar.match(/./);
					if (stringMatch) {
						
						// handle any case modifiers (<) or (>)
						if (caseModifier == 'lowercase')
							newString = (reverse) ? stringChar.toLowerCase() + newString : newString + stringChar.toLowerCase() ;
						else if (caseModifier == 'uppercase')
							newString = (reverse) ? stringChar.toUpperCase() + newString : newString + stringChar.toUpperCase() ;
						else
							newString = (reverse) ? stringChar + newString : newString + stringChar ;
							
						(reverse) ? stringPosition-- : stringPosition++ ;
					}
				}
				break;
			
			default: // exact match
				
				// if this is an absolute character (escaped by \\), use the placeholder variable and reset the absolute variables
				if (absoluteModifier) {
					maskChar = absoluteCharacter;
					absoluteModifier = false;
					absoluteCharacter = null;
				}
				
				if (stringChar) {
					var stringMatch = (stringChar.indexOf(maskChar) != -1);
					if (stringMatch) {
						newString = (reverse) ? stringChar + newString : newString + stringChar ;
						(reverse) ? stringPosition-- : stringPosition++ ;
					}
					else
						newString = (reverse) ? maskChar + newString : newString + maskChar ;
				}
				else
					newString = (reverse) ? maskChar + newString : newString + maskChar ;
				
				break;
		}
	}
	
	return newString;
}

