/* ********************************************************** */
/* Global Variables and Constants *************************** */
/* ********************************************************** */

var digits = "0123456789";
var lowercaseLetters = "abcdefghijklmnopqrstuvwxyz"
var uppercaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
var blanks = " \t\n\r";  // aka whitespace chars

// decimal point character differs by language and culture
var decimalPointDelimiter = "."

// negative sign
var negativeSign = "-"

// non-digit characters allowed in phone numbers
var phoneNumberDelimiters = "()- ";

// characters allowed in US phone numbers
var validUSPhoneChars = digits + phoneNumberDelimiters;

// U.S. phone numbers have 10 digits, formatted as ### ### #### or (###)###-####
var digitsInUSPhoneNumber = 10;

// non-digit characters which are allowed in ZIP Codes
var ZIPCodeDelimiters = "-";

// our preferred delimiter for reformatting ZIP Codes
var ZIPCodeDelimeter = "-"

// U.S. ZIP codes have 5 or 9 digits, formatted as ##### or #####-####
var digitsInZIPCode1 = 5
var digitsInZIPCode2 = 9

// Valid U.S. Postal Codes for states, territories, armed forces, etc.
// See http://www.usps.gov/ncsc/lookups/abbr_state.txt
var USStateCodeDelimiter = "|";
var USStateCodes = "AL|AK|AS|AZ|AR|CA|CO|CT|DE|DC|FM|FL|GA|GU|HI|ID|IL|IN|IA|KS|KY|LA|ME|MH|MD|MA|MI|MN|MS|MO|MT|NE|NV|NH|NJ|NM|NY|NC|ND|MP|OH|OK|OR|PW|PA|PR|RI|SC|SD|TN|TX|UT|VT|VI|VA|WA|WV|WI|WY|AE|AA|AE|AE|AP|al|ak|as|az|ar|ca|co|ct|de|dc|fm|fl|ga|gu|hi|id|il|in|ia|ks|ky|la|me|mh|md|ma|mi|mn|ms|mo|mt|ne|nv|nh|nj|nm|ny|nc|nd|mp|oh|ok|or|pw|pa|pr|ri|sc|sd|tn|tx|ut|vt|vi|va|wa|wv|wi|wy|ae|aa|ae|ae|ap"

// NPWP delimiter
var npwpdelimiter = "./-";

// NPWP set
var pwpn = digits + npwpdelimiter;
/* ********************************************************** */
/* Functions ************************************************ */
/* ********************************************************** */


// Returns true if string s is empty

function isEmpty(s)
  {
  return ((s == null) || (s.length == 0));
  }


// Returns true if string s is empty or all blank chars

function isBlank(s)
  {
  var i;

  // Is s empty?
  if (isEmpty(s))
    return true;

  // Search through string's chars one by one until we find first
  // non-blank char, then return false; if we don't, return true
  for (i=0; i<s.length; i++)
    {
    // Check that current character isn't blank
    var c = s.charAt(i);
    if (blanks.indexOf(c) == -1)
      return false;
    }
  // All characters are blank
  return true;
  }


// Removes all characters which appear in string bag from string s

function stripCharsInBag (s, bag)
  {
  var i;
  var returnString = "";

  // Search through string's characters one by one;
  // if character is not in bag, append to returnString
  for (i = 0; i < s.length; i++)
    {
    // Check that current character isn't blank
    var c = s.charAt(i);
    if (bag.indexOf(c) == -1)
      returnString += c;
    }
  return returnString;
  }


// Removes all characters which do NOT appear in string bag from string s

function stripCharsNotInBag (s, bag)
  {
  var i;
  var returnString = "";

  // Search through string's characters one by one;
  // if character is in bag, append to returnString
  for (i = 0; i < s.length; i++)
    {
    // Check that current character isn't blank
    var c = s.charAt(i);
    if (bag.indexOf(c) != -1)
      returnString += c;
    }
  return returnString;
  }


// Removes all blank chars (as defined by blanks) from s

function stripBlanks(s)
  {
  return stripCharsInBag(s, blanks)
  }


// Removes leading blank chars (as defined by blanks) from s

function stripLeadingBlanks(s)
  {
  var i = 0;
  while ((i < s.length) && (blanks.indexOf(s.charAt(i)) != -1))
     i++;
  return s.substring(i, s.length);
  }


// Removes trailing blank chars (as defined by blanks) from s

function stripTrailingBlanks(s)
  {
  var i = s.length - 1;
  while ((i >= 0) && (blanks.indexOf(s.charAt(i)) != -1))
     i--;
  return s.substring(0, i+1);
  }


// Removes leading+trailing blank chars (as defined by blanks) from s

function stripLeadingTrailingBlanks(s)
  {
  s = stripLeadingBlanks(s);
  s = stripTrailingBlanks(s);
  return s;
  }
  
function trim(s) {
  s = stripLeadingBlanks(s);
  s = stripTrailingBlanks(s);
  return s;
}


// Returns true if character c is an English letter (A .. Z, a..z)

function isLetter(c)
  {
  return (((c >= "a") && (c <= "z")) || ((c >= "A") && (c <= "Z")));
  }


// Returns true if character c is a digit (0 .. 9)

function isDigit(s)
  {
    var isDig = true;
  for (i = 0; i < s.length; i++)
    {
    // Check that current character isn't blank
    var c = s.charAt(i);
    if (!((c >= "0") && (c <= "9")))
      isDig = false;
    }
  return isDig;
  }


// Returns true if all chars in string s are numbers;
// first character is allowed to be + or -; does not
// accept floating point, exponential notation, etc.

function isInteger(s)
  {
  if (isBlank(s))
    return false;

  // skip leading + or -
  if ((s.charAt(0) == "-") || (s.charAt(0) == "+"))
    var i = 1;
  else
    var i = 0;

  // Search through string's chars one by one until we find a
  // non-numeric char, then return false; if we don't, return true
  for (i; i<s.length; i++)
    {
    // Check that current character is number
    var c = s.charAt(i);
    if (!isDigit(c))
      return false;
    }
  // All characters are numbers
  return true;
  }


// True if string s is an unsigned floating point (real) number;
// first character is allowed to be + or -; no exponential notation.

function isFloat(s)
  {
  var seenDecimalPoint = false;

  if (isBlank(s))
    return false;
  if (s == decimalPointDelimiter)
    return false;

  // skip leading + or -
  if ((s.charAt(0) == "-") || (s.charAt(0) == "+"))
    var i = 1;
  else
    var i = 0;

  // Search through string's chars one by one until we find a
  // non-numeric char, then return false; if we don't, return true

  for (i; i<s.length; i++)
    {
    // Check that current character is number
    var c = s.charAt(i);

    if ((c == decimalPointDelimiter) && !seenDecimalPoint)
      seenDecimalPoint = true;
    else if (!isDigit(c))
      return false;
    }
  // All characters are numbers
  return seenDecimalPoint;
  }


// Returns true if string s is English letters (A .. Z, a..z) only

function isAlphabetic(s)
  {
  var i;

  if (isBlank(s))
     return false;

  // Search through string's chars one by one until we find a
  // non-alphabetic char, then return false; if we don't, return true

  for (i = 0; i < s.length; i++)
  {
  // Check that current character is letter
  var c = s.charAt(i);

  if (!isLetter(c))
    return false;
  }

  // All characters are letters
  return true;
  }


// Returns true if string s is English letters (A .. Z, a..z) and numbers only

function isAlphanumeric(s)
  {
  var i;

  if (isBlank(s))
     return false;

  // Search through string's chars one by one until we find a
  // non-alphanumeric char, then return false; if we don't, return true

  for (i = 0; i < s.length; i++)
    {
    // Check that current character is number or letter
    var c = s.charAt(i);

    if (! (isLetter(c) || isDigit(c) ) )
    return false;
    }

  // All characters are numbers or letters
  return true;
  }


// reformatString(targetStr [, str1, int1, str2, int2, ... strN, intN])
//
// Handy function for arbitrarily inserting formatting characters
// or delimiters of various kinds within targetString.
//
// reformatString() takes one required string argument, targetStr,
// and 0-N optional string/integer-pair arguments. These optional
// arguments specify how targetStr is to be reformatted and how/where
// other strings are to be inserted in it.
//
// reformatString() processes the optional args in order one by one.
// * If the argument is an integer, reformatString() appends that number
//   of sequential characters from targetStr to the resultString.
// * If the argument is a string, reformatString() appends the string
//   to the resultString.
//
// NOTE: The first argument after targetString must be a string.
// (It can be empty.)  The second argument must be an integer.
// Thereafter, integers and strings must alternate.  This is to
// provide backward compatibility to Navigator 2.0.2 JavaScript
// by avoiding use of the typeof operator.
//
// It is the caller's responsibility to make sure that we do not
// try to copy more characters from s than s.length.
//
// EXAMPLES:
//
// * To reformat a 10-digit U.S. phone number from "1234567890"
//   to "(123)456-7890" make this function call:
//   reformatString("1234567890", "(", 3, ")", 3, "-", 4)
//
// HINT:
//
// If you have a string which is already delimited in one way
// (example: a phone number delimited with spaces as "123 456 7890")
// and you want to delimit it in another way using function reformat,
// call stripCharsNotInBag() or stripBlanks() to remove unwanted
// characters, THEN call function reformatString to delimit as desired.
//
// EXAMPLE:
//
// reformatString(stripCharsNotInBag ("123 456 7890", digits),
//           "(", 3, ") ", 3, "-", 4)
function reformatString(targetString)
  {
  var arg;
  var sPos = 0;
  var resultString = "";

  for (var i=1; i<reformatString.arguments.length; i++)
    {
    arg = reformatString.arguments[i];
    if (i%2 == 1)
      {
      resultString += arg;
      }
    else
      {
      resultString += targetString.substring(sPos, sPos + arg);
      sPos += arg;
      }
    }
  return resultString;
  }


// Returns true if s is valid U.S. phone number (with area code): 10 digits

function isUSPhoneNumber(s)
  {
  if (isBlank(s))
    return false;
  s = stripCharsNotInBag(s, digits);
  return (isInteger(s) && (s.length == digitsInUSPhoneNumber));
  }


// Returns true if string s is a valid U.S. ZIP code: ##### or #####-####

function isZIPCode(s)
  {
  if (isBlank(s))
    return false;

  s = stripLeadingTrailingBlanks(s);

  if ((isInteger(s)) && (s.indexOf("-") == -1) &&  // #####
      (s.length == digitsInZIPCode1))
    return true;

  if (s.indexOf("-") != 5)  // - in wrong place
    return false;

  s = stripCharsNotInBag(s, digits);

  if (s.length == digitsInZIPCode2)
    return true;   // #####-####
  else
    return false;  // not #####-####
  }


// Returns true if s is valid 2-letter U.S. state abbreviation

function isStateCode(s)
  {
  if (isBlank(s))
    return false;
  return ((USStateCodes.indexOf(s) != -1) &&
          (s.indexOf(USStateCodeDelimiter) == -1))
  }


// Returns true if string is a valid email address: @ and . required,
// at least one char before @, at least one char before and after .

function isEmail(s)
  {
  if (isBlank(s))
    return false;

  // there must be >= 1 character before @, so we start
  // start looking at character position 1 (i.e. second character)
  var i = 1;
  var sLength = s.length;

  // look for @
  while ((i < sLength) && (s.charAt(i) != "@"))
    i++

  if ((i >= sLength) || (s.charAt(i) != "@"))
    return false;
  else
    i += 2;

  // look for .
  while ((i < sLength) && (s.charAt(i) != "."))
    i++

  // there must be at least one character after the .
  if ((i >= sLength - 1) || (s.charAt(i) != "."))
    return false;
  else
    return true;
  }


// Returns true if string s is an integer such that a <= s <= b

function isIntegerInRange (s, a, b)
  {
  if (isBlank(s))
    return false;
  if (!isInteger(s))
    return false;
  var num = parseInt(s);
  return ((num >= a) && (num <= b));
  }


// Returns index of checked radio button in radio set,
// or -1 if no radio buttons are checked

function getCheckedRadioButton(radioSet)
  {
  for (var i=0; i<radioSet.length; i++)
    if (radioSet[i].checked)
      return i;
  return -1;
  }


// Returns array containing index(es) of checked checkbox(es)
// in checkbox set, or -1 if no checkboxes are checked

function getCheckedCheckboxes(checkboxSet)
  {
  var arr = new Array();
  for (var i=0,j=0; i<checkboxSet.length; i++)
    if (checkboxSet[i].checked)
      arr[j++] = i;
  if (arr.length > 0)
    return arr;
  else
    return -1;
  }


// Returns array containing index(es) of checked option(s)
// in select box, or -1 if no options are selected

function getCheckedSelectOptions(select)
  {
  var arr = new Array();
  for (var i=0,j=0; i<select.length; i++)
    if (select.options[i].selected)
      arr[j++] = i;
  if (arr.length > 0)
    return arr;
  else
    return -1;
  }

 //menghapus space pada sebelah kiri string
function LTrim(sInput)
{
	if (sInput.charAt(0) != " ")
		return sInput;

	var I, sTemp = "";
	for (I=0; I < sInput.length; I++)
	{
	if (sInput.charAt(I) != " ")
		{
		for (; I < sInput.length; I++)
			sTemp = sTemp + sInput.charAt(I);
		}
	}
	return sTemp;
}

//menghapus space pada sebelah kanan string
function RTrim(sInput)
{
	if (sInput.charAt(sInput.length-1) != " ")
		return sInput;

	var I, sTemp = "";
	for (I=sInput.length-1; I > -1; I--)
	{	if (sInput.charAt(I) != " ")
		{
			for (; I > -1; I--)
			sTemp = sInput.charAt(I) + sTemp;
		}
	}
	return sTemp;
}

//menghapus space sebelah kanan-kiri string
function Trim(sInput)
{
	var sString = sInput;
	sString = LTrim(sString);
	sString = RTrim(sString);
	return sString;
}
 function isNull(sItem)
{
	if (Trim(sItem) == "")
		return  true;
	return false;
}

function isEmail(s)
  {
  if (isBlank(s))
    return false;

  // there must be >= 1 character before @, so we start
  // start looking at character position 1 (i.e. second character)
  var i = 1;
  var sLength = s.length;

  // look for @
  while ((i < sLength) && (s.charAt(i) != "@"))
    i++

  if ((i >= sLength) || (s.charAt(i) != "@"))
    return false;
  else
    i += 2;

  // look for .
  while ((i < sLength) && (s.charAt(i) != "."))
    i++

  // there must be at least one character after the .
  if ((i >= sLength - 1) || (s.charAt(i) != "."))
    return false;
  else
    return true;
  }

 /* function ini untuk mengcheck apakah string sItem bukan numeric.
	return an empty string if numeric, otherwise return an error Message.	*/
function isNotNumeric(sItem)
{
	if (!check(sItem,"1234567890."))
		return true;
	return false;
}
/* 	function ini untuk mengcheck apakah string sItem adalah nomor telephone
	return an empty string if valid telephone number, otherwise return an error Message.	*/
function isNotTelephone(sItem)
{
	if (!check(sItem,"1234567890-()+"))
		return true;
	return false;
}
function isNotDate(sItem)
{
	if (!check(sItem,"1234567890/"))
		return true;
	return false;
}

function check(sInput, sCheck)
{	var chr, j;
	var bfound = false;
	var ok = true;
	for (var i = 0; i < sInput.length; i++)
	{
		chr = sInput.charAt(i);
		bfound = false;
		for (j=0; j < sCheck.length; j++)
		{
			if (chr == sCheck.charAt(j)) bfound = true;
		}
		if (!bfound) ok = false;
	}
	return ok;
}
function na_preload_img()
{
  var img_list = na_preload_img.arguments;
  if (document.preloadlist == null)
    document.preloadlist = new Array();
  var top = document.preloadlist.length;
  for (var i=0; i < img_list.length; i++) {
    document.preloadlist[top+i]     = new Image;
    document.preloadlist[top+i].src = img_list[i+1];
  }
}

function na_change_img_src(name, nsdoc, rpath, preload)
{
  var img = eval((navigator.appName == 'Netscape') ? nsdoc+'.'+name : 'document.all.'+name);
  if (name == '')
    return;
  if (img) {
    img.altsrc = img.src;
    img.src    = rpath;
  }
}

function na_restore_img_src(name, nsdoc)
{
  var img = eval((navigator.appName == 'Netscape') ? nsdoc+'.'+name : 'document.all.'+name);
  if (name == '')
    return;
  if (img && img.altsrc) {
    img.src    = img.altsrc;
    img.altsrc = null;
  }
}

isNav = (navigator.appName.indexOf("Netscape") != -1) ? true : false;
isIE = (navigator.appName.indexOf("Microsoft") != -1) ? true : false;


//fungsi untuk mengambil key event
function getkey(e) {
	if (window.event)
		return window.event.keyCode;
	else if (e)
		return e.which;
	else
		return null;
}

//fungsi untuk memfilter karakter
//parameter:
// e	 --> event
// goods --> set karakter yang diinginkan
function goodchars(e, goods) {
	var key, keychar;
	key = getkey(e);
	if (key == null) return true;
	
	// get character
	keychar = String.fromCharCode(key);
	keychar = keychar.toLowerCase();
	goods = goods.toLowerCase();

	// check goodkeys
	if (goods.indexOf(keychar) != -1)
		return true;

	// control keys
	if ( key==null || key==0 || key==8 || key==9 || key==13 || key==27 )
		return true;

	// else return false
	return false;
}

function goodkey(e) {
	var key;
	key = getkey(e);
	if (key == null) 
		return true;
	if ( key==null || key==0 || key==8 || key==9 || key==13 || key==27 )
		return true;
	return false;
}

function isCharPartOfString(e, str) {
	var key, keychar;
	key = getkey(e);
	if (key == null)
		return true;
	
	// get character
	keychar = String.fromCharCode(key);
	keychar = keychar.toLowerCase();
	str = str.toLowerCase();
	
	// check is part of
	return (str.indexOf(keychar) >= 0);
}
