﻿
function HTMLEncode(str) {
    if (str == null)
        return "";
   var comp="";
   var i = str.indexOf("&", 0);
  while (i > -1) {
    comp += str.substring(0, i+1) + "amp;";
    str = str.substring(i+1, str.length);
    i = str.indexOf("&", 0);
  }
    str = comp + str;
  while (str.indexOf("<", 0) > -1)
    str = str.replace("<", "&lt;");
  while (str.indexOf(">", 0) > -1)
    str = str.replace(">", "&gt;");
  while (str.indexOf('"', 0) > -1)
    str = str.replace('"', '&quot;');
  return str;
} 

function PadLeft(String,Length,PadChar)
{
 // **********************************************************
 // Placed in the public domain by Affordable Production Tools
 // April 1, 1998
 // Web site: http://www.aptools.com/
 //
 // December 2, 1998 -- Modified to allow specification of
 // pad character.
 //
 // This function accepts a number or string, and a number
 // specifying the desired length. If the length is greater
 // than the length of the value passed, the value is padded
 // with spaces (default) or the specified pad character
 // to the length specified.
 //
 // The function is useful in right justifying numbers or
 // strings in HTML form fields.
 // **********************************************************
 String += ""       // Force argument to string.
 Length += ""       // Force argument to string.
 PadChar += ""      // Force argument to string.
 if((PadChar == "") || (!(PadChar.length == 1)))
  PadChar = " "
 var Count = 0
 var PadLength = 0
 Length = parseInt(0 + Length,10)
 if(Length <= String.length) // No padding necessary.
  return(String)
 PadLength = Length - String.length
 for(Count = 0; Count < PadLength; Count++)
  String = PadChar + String
 return(String)
}

function TrimZeros(str) {
  var ss = str.split('.');
  if (ss.length == 2) {
    var allZeros = true;
    for (var i=0; i<ss[1].length; i++) {
      if (ss[1].charAt(i) != '0') {
        allZeros = false;
        break;
      }
    }
    if (allZeros) {
      return ss[0];
    }
  }
  return str;
}

function FormatNumberTrim(Number,Decimals,Separator) 
{
 var str = FormatNumber(Number,Decimals,Separator);
 return TrimZeros(str);
}

function GetDecimalSeperator() {
    if (typeof (StrUtils_DecimalSeparator) != "undefined")
        Separator = StrUtils_DecimalSeparator;
    else
        Separator = ".";
}

function FormatNumber(Number,Decimals,Separator)
{
 // **********************************************************
 // Placed in the public domain by Affordable Production Tools
 // March 21, 1998
 // Web site: http://www.aptools.com/
 //
 // November 24, 1998 -- Error which allowed a null value
 // to remain null fixed. Now forces value to 0.
 //
 // October 28, 2001 -- Modified to provide leading 0 for fractional number
 // less than 1.
 //
 // This function accepts a number to format and number
 // specifying the number of decimal places to format to. May
 // optionally use a separator other than '.' if specified.
 //
 // If no decimals are specified, the function defaults to
 // two decimal places. If no number is passed, the function
 // defaults to 0. Decimal separator defaults to '.' .
 //
 // If the number passed is too large to format as a decimal
 // number (e.g.: 1.23e+25), or if the conversion process
 // results in such a number, the original number is returned
 // unchanged.
 // **********************************************************
 Number += ""          // Force argument to string.
 Decimals += ""        // Force argument to string.
 Separator += ""       // Force argument to string.
 if ((Separator == "") || (Separator.length > 1)) {
     if (typeof (StrUtils_DecimalSeparator) != "undefined")
         Separator = StrUtils_DecimalSeparator;
     else
         Separator = ".";
 }
 if(Number.length == 0)
  Number = "0"
 var OriginalNumber = Number  // Save for number too large.
 var Sign = 1
 var Pad = ""
 var Count = 0
 // If no number passed, force number to 0.
 if(parseFloat(Number)){
  Number = parseFloat(Number)} else {
  Number = 0}
 // If no decimals passed, default decimals to 2.
 if((parseInt(Decimals,10)) || (parseInt(Decimals,10) == 0)){
  Decimals = parseInt(Decimals,10)} else {
  Decimals = 2}
 if(Number < 0)
 {
  Sign = -1         // Remember sign of Number.
  Number *= Sign    // Force absolute value of Number.
 }
 if(Decimals < 0)
  Decimals *= -1    // Force absolute value of Decimals.
 // Next, convert number to rounded integer and force to string value.
 // (Number contains 1 extra digit used to force rounding)
 Number = "" + Math.floor(Number * Math.pow(10,Decimals + 1) + 5)
 if((Number.substring(1,2) == '.')||((Number + '')=='NaN'))
  return(OriginalNumber) // Number too large to format as specified.
 // If length of Number is less than number of decimals requested +1,
 // pad with zeros to requested length.
 if(Number.length < Decimals +1) // Construct pad string.
 {
  for(Count = Number.length; Count <= Decimals; Count++)
   Pad += "0"
 }
 Number = Pad + Number // Pad number as needed.
 if(Decimals == 0){
  // Drop extra digit -- Decimal portion is formatted.
  Number = Number.substring(0, Number.length -1)} else {
  // Or, format number with decimal point and drop extra decimal digit.
 Number = Number.substring(0,Number.length - Decimals -1) +
          Separator +
          Number.substring(Number.length - Decimals -1,
          Number.length -1)}
 if((Number == "") || (parseFloat(Number) < 1))
  Number="0"+Number // Force leading 0 for |Number| less than 1.
 if(Sign == -1)
  Number = "-" + Number  // Set sign of number.
 return(Number)
}

function LeftTrim(String)
{
 String += ""         // Force argument to string.
 TrimChar = " "
 if(String.length == 0)
  return(String)
 var Count = 0
 for(Count = 0;Count < String.length;Count++)
 {
  if(!(String.charAt(Count) == TrimChar))
   return(String.substring(Count,String.length))
 }
 return("")
}

function RightTrim(String)
{
 String += ""        // Force argument to string.
 TrimChar = " "
 if(String.length == 0)
  return(String)
 var Count = 0
 for(Count = String.length -1;Count >= 0;Count--)
 {
  if(!(String.charAt(Count) == TrimChar))
   return(String.substring(0,Count + 1))
 }
 return("")
}

function Trim(String)
{
 return(RightTrim(LeftTrim(String)))
}

function GetTimeStr(time) {
   h = time.getHours();
   m = time.getMinutes();
   s = time.getSeconds();
   timeStr  =  (h > 12) ? h - 12 : h;
   if (timeStr == "0") timeStr = "12";
   timeStr += ((m < 10) ? ":0" : ":") + m;
   timeStr += ((s < 10) ? ":0" : ":") + s;
   timeStr +=  (h > 12) ? " PM": " AM";
   return timeStr
}

function GetDateStr(date) {
   m = date.getMonth()+1;
   d = date.getDate();
   y = takeYear(date);
   dateStr = ((m < 10) ? "0" : "") + m;
   dateStr += ((d < 10) ? "/0" : "/") + d;
   dateStr +=  (y < 10) ? "/0": "/" + y;
   return dateStr
}

// Use this to get the correct year after 1999
//http://www.quirksmode.org/js/introdate.html#year
function takeYear(theDate) {
	x = theDate.getYear();
	var y = x % 100;
	y += (y < 38) ? 2000 : 1900;
	return y;
}

function TimeSpanToString(duration,showSeconds) {
   var hours = Math.floor(duration / 3600);
   duration -= hours * 3600;
   var minutes;
   var seconds = 0;
   if (showSeconds)
   {
     minutes = Math.floor(duration / 60);
   }
   else
   {
     minutes = Math.round(duration / 60.0);
   }

   duration -= minutes * 60;
   seconds = duration;

   var str = "";
   if (hours != 0) str += hours + "h";
   if (minutes != 0)
   {
     if (hours > 0) str +=" ";
     str += minutes + "m";
   }
   else if (!showSeconds && (hours == 0) && (seconds > 0))
   {
     str += "<1m";
   }

   if (showSeconds && seconds != 0)
   {
     if (str.length > 0) str += " ";
     str += seconds + "s";
   }

   return str;

}

function TrimString(sInString) {
  sInString = sInString.replace( /^\s+/g, "" );// strip leading
  return sInString.replace( /\s+$/g, "" );// strip trailing
}


function GetChaptersCoveredCondensed(chapters)
{
    var lastChapter, lastWrittenChapter;
    var w_Continue, w_StartPos, w_Length, w_Delimeter_pos, w_tmp_int;
    var w_tmp_num, w_tmp_txt, w_Delimeter_Len, p_Delimeter;
    var retval="";

    p_Delimeter = ",";
    lastChapter=-1;
    lastWrittenChapter=-1;
    w_tmp_int=-1;

    if (chapters.length==0)
    {
        w_Continue=0; //force early exit
    }
    else
    {
        //-- parse the original @p_SourceText array into a temp table
        w_Continue = 1;
        w_StartPos = 0;
        chapters = TrimString(chapters);
        w_Length   = chapters.length;
        w_Delimeter_Len = p_Delimeter.length;
    }
    var scount=0;
    
    while ((w_Continue == 1) && (scount<50))
    {
        w_Delimeter_pos=chapters.indexOf(p_Delimeter);
        if (w_Delimeter_pos > 0)  //-- delimeter(s) found, get the value
        {
            w_tmp_txt=chapters.substring(0, (w_Delimeter_pos));
            if (w_tmp_txt)
            {
                w_tmp_int = w_tmp_txt * 1;  //"cast" as int
                w_tmp_num = w_tmp_txt * 1;  //"cast" as int
            } //-- end if w_tmp_txt is numeric
            else
            {
                w_tmp_int =  null;
                w_tmp_num =  null;
            }
        }
        else //-- No more delimeters, get last value
        {
           w_tmp_txt=chapters;
           if (w_tmp_txt)
           {
            w_tmp_int = w_tmp_txt * 1;  //"cast" as int
            w_tmp_num = w_tmp_txt * 1;  //"cast" as int
           }
           else
           {
            w_tmp_int =  null;
            w_tmp_num =  null;
           }
           w_Continue = 0;
        }
    
    if (w_tmp_int < 0)
        w_tmp_int=w_tmp_int * -1;

    if (retval=="")
    {        
        retval=w_tmp_int;
        lastWrittenChapter=w_tmp_int;
    }
    else 
    {
        if (w_tmp_int > lastChapter + 1)
        {
            if (lastChapter !=lastWrittenChapter)
            {
                retval=retval + '-' + lastChapter;
                lastWrittenChapter=lastChapter;
            }
            retval=retval + ', ' + w_tmp_int;
            lastWrittenChapter=w_tmp_int;
        }
    }
    
    lastChapter=w_tmp_int;
    scount++;
    chapters=chapters.substring(chapters.indexOf(p_Delimeter) + 1, chapters.length);
} //--END WHILE LOOP

    if ((w_tmp_int>-1) && (lastWrittenChapter!=w_tmp_int))
    {
        if (lastWrittenChapter<lastChapter-1)
            retval=retval + '-' + w_tmp_int;
        else
            retval=retval + ', ' + w_tmp_txt;
    }
    
    return retval;

}

function GetChaptersCoveredCondensedAlias(chapters, chapterAliasArray)
{
    var lastChapter, lastWrittenChapter;
    var w_Continue, w_StartPos, w_Length, w_Delimeter_pos, w_tmp_int;
    var w_tmp_num, w_tmp_txt, w_Delimeter_Len, p_Delimeter;
    var retval="";
    p_Delimeter = ",";
    lastChapter=-1;
    lastWrittenChapter=-1;
    w_tmp_int=-1;

    if (chapters.length==0)
    {
        w_Continue=0; //force early exit
    }
    else
    {
        //-- parse the original @p_SourceText array into a temp table
        w_Continue = 1;
        w_StartPos = 0;
        chapters = TrimString(chapters);
        w_Length   = chapters.length;
        w_Delimeter_Len = p_Delimeter.length;
    }
    var scount=0;
    
    while ((w_Continue == 1) && (scount<50))
    {
        w_Delimeter_pos=chapters.indexOf(p_Delimeter);
        if (w_Delimeter_pos > 0)  //-- delimeter(s) found, get the value
        {
            w_tmp_txt=chapters.substring(0, (w_Delimeter_pos));
            if (w_tmp_txt)
            {
                w_tmp_int = w_tmp_txt * 1;  //"cast" as int
                w_tmp_num = w_tmp_txt * 1;  //"cast" as int
            } //-- end if w_tmp_txt is numeric
            else
            {
                w_tmp_int =  null;
                w_tmp_num =  null;
            }
        }
        else //-- No more delimeters, get last value
        {
           w_tmp_txt=chapters;
           if (w_tmp_txt)
           {
            w_tmp_int = w_tmp_txt * 1;  //"cast" as int
            w_tmp_num = w_tmp_txt * 1;  //"cast" as int
           }
           else
           {
            w_tmp_int =  null;
            w_tmp_num =  null;
           }
           w_Continue = 0;
        }
    
    if (w_tmp_int < 0)
        w_tmp_int=w_tmp_int * -1;

    if (retval=="")
    {   
    
        if (chapterAliasArray[w_tmp_int])
            retval=chapterAliasArray[w_tmp_int]
        else
            retval=w_tmp_int;
        lastWrittenChapter=w_tmp_int;
    }
    else 
    {
        if (w_tmp_int > lastChapter + 1)
        {
            if (lastChapter !=lastWrittenChapter)
            {
                if (chapterAliasArray[lastChapter])
                    retval=retval + '-' + chapterAliasArray[lastChapter];
                else
                    retval=retval + '-' + lastChapter;
                    
                lastWrittenChapter=lastChapter;
            }
            if (chapterAliasArray[w_tmp_int])
                retval=retval + ', ' + chapterAliasArray[w_tmp_int];
            else
                retval=retval + ', ' + w_tmp_int;
            lastWrittenChapter=w_tmp_int;
        }
    }
    
    lastChapter=w_tmp_int;
    scount++;
    chapters=chapters.substring(chapters.indexOf(p_Delimeter) + 1, chapters.length);
} //--END WHILE LOOP

    if ((w_tmp_int>-1) && (lastWrittenChapter!=w_tmp_int))
    {
        if (lastWrittenChapter<lastChapter-1)
        {
            if (chapterAliasArray[w_tmp_int])
                retval=retval + '-' + chapterAliasArray[w_tmp_int];
            else
                retval=retval + '-' + w_tmp_int;
        }
        else
        {
            if (chapterAliasArray[w_tmp_int])
                retval=retval + ', ' + chapterAliasArray[w_tmp_int];
            else
                retval=retval + ', ' + w_tmp_txt;
        }
    }

    return retval;

}

// Returns true if a string contains only whitespace characters
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;
}


function isvaliddatetime(dateStr)
{
  return isvaliddate(dateStr,true);
}

function isvaliddate(dateStr,withTime)
{
  // Checks for the following valid date formats:
  // MM/DD/YY   MM/DD/YYYY   MM-DD-YY   MM-DD-YYYY
  // Also separates pieces into variables
  // Time formats are:
  // h:mm AM/PM hh:mm AM/PM h:mm:ss AM/PM hh:mm:ss AM/PM

  // TODO: 24 hour time support?

  var datePat;

  // To require a 4 digit year entry, use this line instead:
  // var datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{4})$/;
  if (withTime)
  	datePat = /^(\d{1,2})(\/)(\d{1,2})\2(\d{2}|\d{4})\s(\d{1,2}):(\d{2})(:(\d{2}))?\s(AM|PM)$/;
  	//datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{2}|\d{4})\s(\d{1,2}):(\d{2})(:(\d{2}))?\s(AM|PM)$/;
  else
    datePat = /^(\d{1,2})(\/)(\d{1,2})\2(\d{2}|\d{4})$/;
    //datePat = /^(\d{1,2})(\/|-)(\d{1,2})\2(\d{2}|\d{4})$/;

  var matchArray = dateStr.match(datePat); // is the format ok?
  if (matchArray == null) 
  {
    return false;
  }
  month = matchArray[1]; // parse date into variables
  day = matchArray[3];
  year = Number(matchArray[4]);
  if (year<80)
    year = 1900 + year;
  else if (year<100)
    year = 2000 + year;

  if (withTime)
  {
    hours = matchArray[5];
  	minutes = matchArray[6];
  	seconds = matchArray[8]; // optional
  	ampm = matchArray[9];

    // 0 is midnight according to SQL.  Let them put it in
    if (hours<0 || hours > 12)
    {
    return false;
    }
  	if (minutes <0 || minutes > 59)
  	{
  	  return false;
  	}
  	if (seconds!='' && (seconds<0 || seconds > 59) )
  	{
  	  return false;
  	}
  }

  if (month < 1 || month > 12) 
  {
    return false;
  }
  if (day < 1 || day > 31) 
  {
    return false;
  }
  if ((month==4 || month==6 || month==9 || month==11) && day==31) 
  {
    return false
  } 
  if (month == 2) // check for leap year
  { 
    var isleap = (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0));
    if (day>29 || (day==29 && !isleap)) 
    {
      return false;
    }
  }
  if (year > 2078 || year < 1900) {
    return false;
  }  
  return true;
}



// 1: valid
// 0:  blank
// -1: not an integer
// -2: less than min
// -3: greater than max
function isvalidinteger(value,min,max) {
var v;

  v = parseInt(value);

  if (value=="")
    return 0;
  else if (isNaN(v) || value!=v)
    return -1;
  else if (min && v<min)
    return -2;  
  else if (max && v>max)
    return -3;
  else
    return 1;
}

// 1: valid
// 0:  blank
// -1: not an integer
// -2: less than min
// -3: greater than max
function isvalidfloat(value,min,max) {
var v;

  v = parseFloat(value);

  if (value=="")
    return 0;
  else if (isNaN(v) || value!=v)
    return -1;
  else if (min && v<min)
    return -2;
  else if (max && v>max)
    return -3;
  else
    return 1;
}

function showProps(o, objName) {
  var win
  win = window.open("",objName,"width=300,height=300,resizable,scrollbars")
  win.document.open();
  win.document.write("<HTML>");
  win.document.write("<XMP>")
  var result = ""
  count = 0
  for (var i in o) {
    result = objName + "." + i + "=" + o[i] + "\n"
         win.document.write(result)
  }
  win.document.write("</XMP>")
  win.document.close()
}

// Remove parameter from reqstr
function removeParam(reqstr,param)
{
  var evstr, dest;
  dest = new String(reqstr); 

  // strip out existing parameter
  //FOUND A BUG MAD 10/25/00
  //Routine did not handle "param=" at end of string
  //evstr = "dest = dest.replace(/[\\?|\\&]"+param+"=[^\\&]+/ig,\"\");"
  // AAL 09/29/03 Wasn't handling blank params, removed $
  //evstr = "dest = dest.replace(/[\\?|\\&]"+param+"=(([^\\&]+)|\s*$)/ig,\"\");"
  // AAL 4/6/05 if needed I think we can use this to not require a ? or & at start
  // evstr = "regexp = /[\\?|\\&]*"+param+"=([^\\&]+)/;"  
  evstr = "dest = dest.replace(/[\\?|\\&]"+param+"=(([^\\&]+)|\s*)/ig,\"\");"
  eval(evstr);

  // if we stripped out the first param, make the following param have the ampersand
  if (dest.indexOf("?")==-1 && dest.indexOf("&")!=-1)
    dest = dest.replace(/\&/,"?");

  return dest;
}

function InitCap(str) {
    /* First letter as uppercase, rest lower */
    var str = str.substring(0, 1).toUpperCase() + str.substring(1, str.length).toLowerCase();

    return str;
}

// CA Delimited string functions originating from SiteBuilderNet
function buildDelimittedString(array) {
    var i;
    var sList = new Array();
    var str;
    for (i = 0; i < array.length; i++) {
        str = String(array[i]);
        sList.push(str.length);
        sList.push("|");
        sList.push(str);
    }
    return sList.join("");
}

function parseDelimittedString(str) {
    var sList = new Array();
    var pos;
    var lastPos = 0;
    var nChars;

    if (str && str.length > 0) {
        do {
            pos = str.indexOf("|", lastPos);
            if (pos >= 0) {

                nChars = parseInt(str.substr(lastPos, pos - lastPos));

                sList.push(str.substr(pos + 1, nChars));
                lastPos = pos + nChars + 1;
            }

        } while (pos >= 0);
    }

    return sList;
}