//*****************************************************************************
// HttpRequest
//   Defines a object for making asynchronous HTTP GET and POST requests.
//
//   It is basically a wrapper for the XmlHttpRequest object that hides
//   differences between browsers and makes it easier to set up callback
//   functions.
//-----------------------------------------------------------------------------
// Constructor:
//
//   HttpRequest()
//     Creates a new instance of the HttpRequest object.
//
//     Notes: Be sure to set the url property before calling get() or post().
//     Likewise, if you want to process the response, set the successCallback
//     property. To process errors on an unsuccessful request, set the
//     failureCallback property (see below).
//-----------------------------------------------------------------------------
// Properties:
//
//   successCallbackf
//     A function to be called when a GET or POST request completes
//     successfully (i.e., the HTTP status is "200 OK"). The function should
//     accept one argument which will be the HttpRequest object that made the
//     request
//
//   failureCallback
//     A function to be called when a GET or POST request completes
//     unsuccessfully (i.e., the HTTP status is anything other than "200 OK").
//     The function should accept one argument which will be the HttpRequest
//     object that made the request
//
//   url
//     The URL to send the request to. It should not include a query string.
//
//   queryString
//     A query string to append to the URL.
//
//   username
//     Username for authentication, if required.
//
//   password
//     Password for authentication, if required.
//
//   status
//     The status of the response returned from a request. This will be an
//     HTTP status code. For example, a sucessful call returns 200.
//
//   statusText
//     The text associated with the status code. For example, the text for HTTP
//     status code 404 is "Object Not Found".
//
//   responseText
//     A string representing the data returned from a request.
//
//   responseXML
//     A DOM document object representing the XML returned from a request.
//-----------------------------------------------------------------------------
// Methods:
//
//   abort()
//     Aborts a request that is in currently progress.
//
//   setRequestHeader(name, value)
//     Sets the specified request header.
//
//   getRequestHeader(name)
//     Returns the value of the specified request header.
//
//   removeRequestHeader(name, value)
//     Removes the the specified request header.
//
//   clearRequestHeaders()
//     Removes all request headers.
//
//   get()
//     Performs an asynchronous GET request.
//
//   post(data)
//     Performs an asynchronous POST request, passing the given data. Be sure
//     to set the "Content-Type" request header appropriately prior to calling
//     post().
//
//   getResponseHeader(name)
//     Returns the value of the named response header returned from a request.
//
//   getAllResponseHeaders()
//     Returns a string containing all the response headers returned from a
//     request.
//*****************************************************************************

// for vb to javascript
var True = 1;
var False = 0;

// Define a list of Microsoft XML HTTP ProgIDs.
HttpRequest.prototype.MS_PROGIDS = new Array(
   "Msxml2.XMLHTTP.7.0",
   "Msxml2.XMLHTTP.6.0",
   "Msxml2.XMLHTTP.5.0",
   "Msxml2.XMLHTTP.4.0",
   "MSXML2.XMLHTTP.3.0",
   "MSXML2.XMLHTTP",
   "Microsoft.XMLHTTP"
);

// Define constants.
HttpRequest.prototype.READY_STATE_UNINITIALIZED = 0;
HttpRequest.prototype.READY_STATE_LOADING       = 1;
HttpRequest.prototype.READY_STATE_LOADED        = 2;
HttpRequest.prototype.READY_STATE_INTERACTIVE   = 3;
HttpRequest.prototype.READY_STATE_COMPLETED     = 4;

// Define properties.
HttpRequest.prototype.successCallback = null;
HttpRequest.prototype.failureCallback = null;
HttpRequest.prototype.url             = null;
HttpRequest.prototype.username        = null;
HttpRequest.prototype.password        = null;
HttpRequest.prototype.requestHeaders  = new Array();
HttpRequest.prototype.status          = null;
HttpRequest.prototype.statusText      = null;
HttpRequest.prototype.responseXML     = null;
HttpRequest.prototype.responseText    = null;
HttpRequest.prototype.arrayRecs        = null;
HttpRequest.prototype.arrayCodes      = null;
HttpRequest.prototype.errorCode       = null;
HttpRequest.prototype.errorMsg        = null;
HttpRequest.prototype.isSessionExpired = false;
HttpRequest.prototype.bUseHttpHandler = false;


// Define methods.
HttpRequest.prototype.abort                 = HttpRequestAbort;
HttpRequest.prototype.setRequestHeader      = HttpRequestSetRequestHeader;
HttpRequest.prototype.clearRequestHeaders   = HttpRequestClearRequestHeaders;
HttpRequest.prototype.get                   = HttpRequestGet;
HttpRequest.prototype.post                  = HttpRequestPost;
HttpRequest.prototype.initiateRequest       = HttpRequestInitiateRequest;
HttpRequest.prototype.getResponseHeader     = HttpRequestGetResponseHeader;
HttpRequest.prototype.getAllResponseHeaders = HttpRequestGetAllResponseHeaders;
HttpRequest.prototype.parseRec              = HttpRequestParseRec;
HttpRequest.prototype.postAsync             = HttpRequestPostAsync;
HttpRequest.prototype.invokeService         = HttpRequestInvokeService;
HttpRequest.prototype.getErrorMsg           = HttpRequestGetErrorMessage;
HttpRequest.prototype.getArrayCodes         = HttpRequestGetArrayCodes;
HttpRequest.prototype.getErrorCode = HttpRequestGetErrorCode;
HttpRequest.prototype.getValue = HttpRequestGetValue;
//=============================================================================
// Contructor function.
//=============================================================================
function HttpRequest()
{
   // Create the appropriate HttpRequest object for the browser.
   this.xmlHttpRequest = null;

   if (window.XMLHttpRequest != null){
      this.xmlHttpRequest = new XMLHttpRequest();
   }
   else if (window.ActiveXObject != null)
   {
      // Must be IE, find the right ActiveXObject.
      var success = false;
      for (var i = 0; i < HttpRequest.prototype.MS_PROGIDS.length && !success; i++)
      {
         try
         {
            this.xmlHttpRequest = new ActiveXObject(HttpRequest.prototype.MS_PROGIDS[i]);
            success = true;
         }
         catch (ex)
         {}
      }
   }

   // If we couldn't create one, display an error and exit
   if (this.xmlHttpRequest == null)
   {
      alert("Error in HttpRequest():\n\nCannot create an XMLHttpRequest object.");
      return;
   }

}

//=============================================================================
// Methods.
//=============================================================================

function HttpRequestAbort()
{
   this.xmlHttpRequest.abort();
}

function HttpRequestSetRequestHeader(name, value)
{
   // If the header name already exists, replace the value.
   for (var i = 0; i < this.requestHeaders.length; i++)
   {
      var pair = this.requestHeaders[i].split("\n");
      if (pair[0].toLowerCase() == name.toLowerCase())
      {
         this.requestHeaders[i] = name + "\n" + value;
         return;
      }
   }

   // Otherwise, add it as a new item.
   var n = this.requestHeaders.length;
   this.requestHeaders.push(name + "\n" + value);
}

function HttpRequestClearRequestHeaders()
{
   this.requestHeaders = new Array();
}

function HttpRequestGet(bAsync)
{
   this.initiateRequest("GET", null,bAsync);
}

function HttpRequestPost(data,bAsync)
{
   this.initiateRequest("POST", data,bAsync);
}

function HttpRequestInvokeService(queryString,fnCallBack){
    this.url = "/Service.aspx";
    if(!sessionid){
        alert("File:HttpRequest.js SessionId is null. Please correct this.");
    }
    this.queryString = "rdn=" + rdn + "&mysessionid=" + sessionid + "&" + queryString;

    this.successCallback = fnCallBack;
    this.postAsync();
}

function HttpRequestPostAsync(){

    if(false){
        var xmldoc=new ActiveXObject("Msxml2.DOMDocument");
        xmldoc.async = false;
        this.initiateRequest("POST",xmldoc,false);
    }

    this.initiateRequest("POST",undefined,false);
}

function HttpRequestGetResponseHeader(name)
{
   return this.xmlHttpRequest.getResponseHeader(name);
}

function HttpRequestGetAllResponseHeaders()
{
   return this.xmlHttpRequest.getAllResponseHeaders();
}

var STR_START_END_RECORD = "\x08";
var STR_END_FIELD = "\x07";

function nextField(strRet){
    var idx = strRet.indexOf(STR_END_FIELD)
    if(idx == -1)
        return null;
    var obj = new Object();
    obj["current"] = strRet.substr(0,idx);
    obj["next"] = strRet.substr(idx+1);
    obj["original"] = strRet;
    return obj;
}

function nextRec(strRet){
    var idx = strRet.indexOf(STR_START_END_RECORD)
    var obj = new Object();
    obj["original"] = strRet;
    if(idx == -1){
        obj["current"] = strRet;
        return obj;
    }

    var idx2 = strRet.indexOf(STR_START_END_RECORD,idx+1)
    if(idx2 != -1){
        var len = idx2 - idx - 2;  // should subtract by one, but end field char
        obj["current"] = strRet.substr(idx+1,len);
        obj["next"] = strRet.substr(idx2);
    }else{
        var len = strRet.length - (idx+1) - 1;
        obj["current"] = strRet.substr(idx+1,len);
    }
    return obj;
}

function fieldToObject(fields){
    var obj = new Object();
    for(var ii = 0;ii < fields.length;ii++){
        var strTemp = fields[ii];
        var jj = strTemp.indexOf("=");
        if(jj == -1) continue;
        var key = strTemp.substr(0,jj);
        var value = strTemp.substr(jj+1);
        obj[key] = value;
    }
    return obj;
}

function HttpRequestParseRec(refObj)
{
  var strRecs = refObj.responseText;
  var array = new Array();
  idx = 0;
  var bfirst = true;
  while(true){
     var obj = nextRec(strRecs);
     var strRec = obj["current"];
     var fields = strRec.split(STR_END_FIELD);
     var object = fieldToObject(fields);
     if(bfirst){
        this.arrayCodes = object;
        this.errorCode = this.getErrorCode();
        this.errorMsg = this.getErrorMsg();
        if(this.errorCode && (this.errorCode.toLowerCase() == "error")){
            if(this.errorMsg && (this.errorMsg.toLowerCase().substr("session expired") != -1) ){
                this.isSessionExpired = true;
                window.location = "/sessionExpired.aspx";
                return;
            }
        }
        bfirst = false;
     }else{
        array[idx++] = object;
     }
     if(obj["next"] == undefined)
        break;
     strRecs = obj["next"];
  }
  return array;
}

function HttpRequestGetArrayCodes(){
    return this.arrayCodes;
}

function HttpRequestGetErrorMessage(){
    var arrayCodes = this.getArrayCodes();
    if(arrayCodes == null){
        return "Error. Could not communciate with server";
    }
    return arrayCodes["Reason"];
}

function HttpRequestGetErrorCode(){
    var arrayCodes = this.getArrayCodes();
    if(arrayCodes == null){
        return "Error. Could not communciate with server";
    }
    return arrayCodes["Code"];
}

function HttpRequestGetValue(idx, strKey) {
    if (this.arrayRecs.length <= idx) {
        alert("arrayRecs in HttpRequest.HttpRequestGetValue() exceed limit, length only " + this.arrayRecs.length + " but assking for index:" + idx);
    }

    var ret = this.arrayRecs[idx][strKey];
    if (ret == undefined) {
        alert("HttpRequest.HttpRequestGetValue() arrayrecs has length:" + this.arrayRecs.length + ", and does not have property name:" + strKey);
        return undefined;
    }
    return ret;
}


//=============================================================================
// Internal method to make the actual request.
//=============================================================================
function HttpRequestInitiateRequest(method, data,bAsync)
{
   // For IE, abort any current request.
   if (window.ActiveXObject != null)
      this.abort();

   // Clear all response fields.
   this.status       = null;
   this.statusText   = null;
   this.responseText = null;
   this.responseXML  = null;
   this.arrayRecs     = null;
   this.arrayCodes    = null;

   // Set up the callback functions.
   var refObj = this;

   if(!gblIsMozilla){
       this.xmlHttpRequest.onreadystatechange =
          function()
          {
             refObj.readyState = refObj.xmlHttpRequest.readyState;
             if (refObj.readyState == HttpRequest.prototype.READY_STATE_COMPLETED)
             {
                refObj.status       = refObj.xmlHttpRequest.status;
                refObj.statusText   = refObj.xmlHttpRequest.statusText;
                refObj.responseText = refObj.xmlHttpRequest.responseText;
                refObj.responseXML  = refObj.xmlHttpRequest.responseXML;
                if (refObj.status == 200)
                {
                   refObj.arrayRecs     = refObj.parseRec(refObj)
                   if (refObj.successCallback != null){
                      refObj.successCallback(refObj);
                   }
                }
                else
                {
                   refObj.arrayRecs = new Array();
                   refObj.arrayRecs[0] = "Communication error";
                   if (refObj.failureCallback != null){
                      refObj.failureCallback(refObj);
                   }
                }
                return;
             }
          }
   }

   // Initialize the request.
   var url = this.url;
   if (this.queryString != null)
      url = url + "?" + this.queryString;
   if(bAsync == undefined)
      bAsync = true;

   if(gblIsMozilla && !data && (method == "POST"))
      method = "GET";

   this.xmlHttpRequest.open(method, url, bAsync, this.username, this.password);

   // Set request headers (this must be done after the request is opened).
   for (var i = 0; i < this.requestHeaders.length; i++)
   {
      var pair = this.requestHeaders[i].split("\n");
      this.xmlHttpRequest.setRequestHeader(pair[0], pair[1]);
   }

   this.xmlHttpRequest.send(data);

   if(gblIsMozilla){
        refObj.status       = refObj.xmlHttpRequest.status;
        refObj.statusText   = refObj.xmlHttpRequest.statusText;
        refObj.responseText = refObj.xmlHttpRequest.responseText;
        refObj.responseXML  = refObj.xmlHttpRequest.responseXML;
        if (refObj.status == 200)
        {
           refObj.arrayRecs     = refObj.parseRec(refObj)
           if (refObj.successCallback != null){
              refObj.successCallback(refObj);
           }
        }
        else
        {
           refObj.arrayRecs = new Array();
           refObj.arrayRecs[0] = "Communication error";
           if (refObj.failureCallback != null){
              refObj.failureCallback(refObj);
           }
        }
   }
}

function invokeService(service){
    var URL = "service=" + service;
    for (var i = 1; i < arguments.length; i += 2){
        if(URL != "")
            URL += "&"
        URL += arguments[i] + "=" + escape(arguments[i+1]);
    }

    var httpObj = new HttpRequest();
    httpObj.invokeService(URL,undefined)
    return httpObj;
}

function invokeSyncServiceHttpHandler(service,data){
    var URL = "service=" + service;

    for (var i = 2; i < arguments.length; i += 2){
        if(URL != "")
            URL += "&"
        URL += arguments[i] + "=" + escape(arguments[i+1]);
    }

    var httpObj = new HttpRequest();

    httpObj.bUseHttpHandler = true;

    httpObj.url = "/CorpHttpHandler.ashx";
    if(!sessionid){
        alert("File:HttpRequest.js SessionId is null. Please correct this.");
    }
    httpObj.queryString = "rdn=" + rdn+ "&mysessionid=" + sessionid + "&" + URL;

    httpObj.initiateRequest("POST",data,false);
    return httpObj;
}

function invokeSyncServiceHttpHandlerObject(service,data,obj){
    var URL = "service=" + service;

    for(var key in obj){
        if(URL != "")
            URL += "&"
        URL += key + "=" + escape(obj[key]);
    }

    for (var i = 3; i < arguments.length; i += 2){
        if(URL != "")
            URL += "&"
        URL += arguments[i] + "=" + escape(arguments[i+1]);
    }

    var httpObj = new HttpRequest();

    httpObj.bUseHttpHandler = true;

    httpObj.url = "/CorpHttpHandler.ashx";
    if(!sessionid){
        alert("File:HttpRequest.js SessionId is null. Please correct this.");
    }
    httpObj.queryString = "rdn=" + rdn + "&mysessionid=" + sessionid + "&" + URL;
    if (httpObj.queryString.length > 1024) {
        alert("You send too much information on query string.\nPlease use httpPostObject instead of invokeSyncServiceHttpHandlerObject.\nQuery String length is:" + httpObj.queryString.length + " limit only 1024 characters.");
        return null;
    }

    httpObj.initiateRequest("POST",data,false);
    return httpObj;
}


// ex: var http = httpPostObject("sv_getvar",obj,"param1",1,"param2",2);
function httpPostObject_new(service, obj) {
    var URL = "service=" + service;

    var data = "postdata=";
    var paramcount = 0;
    if (obj == undefined || obj == null) {
        data = null;
    } else {
        var bfirst = true;
        for (var key in obj) {
            if (!bfirst)
                data += STR_END_FIELD;
            data += key + "=" + obj[key];
            bfirst = false;
            paramcount++;
        }
    }

    for (var i = 2; i < arguments.length; i += 2) {
        if (URL != "")
            URL += "&"
        URL += arguments[i] + "=" + escape(arguments[i + 1]);
    }
    URL += "&postparamcount=" + paramcount;

    var queryString = "/CorpHttpHandler.ashx?" + "rdn=" + rdn + "&mysessionid=" + sessionid + "&" + URL;
    $.ajaxSetup({ async: false });

    var httpObj = new HttpRequest();
    $.post(queryString, data, function (data) {
        var objdata = new Object();
        objdata.responseText = data;
        httpObj.arrayRecs = httpObj.parseRec(objdata);
        return httpObj;
    });

    if (true)
        return httpObj;

    var httpObj = new HttpRequest();

    httpObj.bUseHttpHandler = true;

    httpObj.url = "/CorpHttpHandler.ashx";
    if (!sessionid) {
        alert("File:HttpRequest.js SessionId is null. Please correct this.");
    }
    httpObj.queryString = "rdn=" + rdn + "&mysessionid=" + sessionid + "&" + URL;

    httpObj.initiateRequest("POST", data, false);
    return httpObj;
}

function httpPostObject(service, obj) {
    var URL = "service=" + service;

    var data = "postdata=";
    var paramcount = 0;
    if (obj == undefined || obj == null) {
        data = null;
    } else {
        var bfirst = true;
        for (var key in obj) {
            if (!bfirst)
                data += STR_END_FIELD;
            data += key + "=" + obj[key];
            bfirst = false;
            paramcount++;
        }
    }

    for (var i = 2; i < arguments.length; i += 2) {
        if (URL != "")
            URL += "&"
        URL += arguments[i] + "=" + escape(arguments[i + 1]);
    }
    URL += "&postparamcount=" + paramcount;

    var httpObj = new HttpRequest();

    httpObj.bUseHttpHandler = true;

    httpObj.url = "/CorpHttpHandler.ashx";
    if (!sessionid) {
        alert("File:HttpRequest.js SessionId is null. Please correct this.");
    }
    httpObj.queryString = "rdn=" + rdn + "&mysessionid=" + sessionid + "&" + URL;

    httpObj.initiateRequest("POST", data, false);
    return httpObj;
}

function invokeSyncService(service, data) {
    var URL = "service=" + service;

    var usehttphandler = false;
    for (var i = 2; i < arguments.length; i += 2){
        if(URL != "")
            URL += "&"
        if(arguments[i] == "httphandler"){
           usehttphandler = true;
           continue;
        }
        URL += arguments[i] + "=" + escape(arguments[i+1]);
    }

    var httpObj = new HttpRequest();

    httpObj.bUseHttpHandler = usehttphandler;
    httpObj.url = usehttphandler ? "/CorpHttpHandler.ashx":"/Service.aspx";
    if(!sessionid){
        alert("File:HttpRequest.js SessionId is null. Please correct this.");
    }
    httpObj.queryString = "rdn=" + rdn+ "&mysessionid=" + sessionid + "&" + URL;

    httpObj.initiateRequest("POST",data,false);
    return httpObj;
}

String.format = function(){
    if( arguments.length == 0 )
        return null;
    var str = arguments[0];
    for(var i=1;i<arguments.length;i++)
    {
        var re = new RegExp('\\{' + (i-1) + '\\}','gm');
        str = str.replace(re, arguments[i]);
    }
    return str;
}

function IsNumeric(sText){
     var ValidChars = "0123456789";
     var IsNumber=true;
     var Char;

    for (i = 0; i < sText.length && IsNumber == true; i++)
    {
        Char = sText.charAt(i);
        if (ValidChars.indexOf(Char) == -1)
        {
        IsNumber = false;
        }
    }
    return IsNumber;
}

function BuildRecordStr2(){
    var strURL = STR_START_END_RECORD;
    for(var i = 0;i<arguments.length;i += 2){
        strURL += arguments[i] + "=" + arguments[i+1] + STR_END_FIELD;
    }
    return strURL;
}

function URLencode(sStr) {
    var str = String.fromCharCode(47,34,47) + "g";
    var str2 = String.fromCharCode(47,44,47) + "g";
    return escape(sStr)
       .replace(/\+/g, '%2B')
          .replace(str,'%22')
             .replace(str2, '%27');
}

function Object2RecordString(objData){
    var strPostData = STR_START_END_RECORD;
    for(var key in objData){
        var value = objData[key];
        if(value != undefined)
           strPostData += key + "=" + value + STR_END_FIELD;
            // value = "__undefined__";
    }
    return strPostData;
}

function RecordStringAppend(strData){
    for(var i = 1;i<arguments.length;i += 2){
        strData += arguments[i] + "=" + arguments[i+1] + STR_END_FIELD;
    }
    return strData;
}

function BuildRecordStr(){
    var strPostData = STR_START_END_RECORD;

    for(var i = 0;i<arguments.length;){
        var type = typeof(arguments[i]);
        if("object" == type){
            var objData = arguments[i];
            for(var key in objData){
                var value = objData[key];
                if(value != undefined)
                    strPostData += key + "=" + value + STR_END_FIELD;
                    // value = "__undefined__";
            }
            i++;
        }else{
            strPostData += arguments[i] + "=" + arguments[i+1] + STR_END_FIELD;
            i += 2;
        }
    }
    return strPostData;
}


function SSRec_Object(key){

    this.stKey = null;
    this.stModel = null;
    this.stSavedName = null;
    this.stYear = null;
    this.stSchedule = null;
    this.stLongForm = null;
    this.stFormat = null;
    this.stMaxServiceIntervals = null;
    this.stMaxAdditonalService = null;
    this.isSessionExpired = false;

    if(key != undefined){
        var obj = null;
        if("number" == typeof(key)){
            this.fetchByKey(key);
        }else if("string" == typeof(key)){
            this.fetchByName(key);
        }else{
            alert("SSRec_Object: does not know to handle the type you passed in" + typeof(key));
        }
    }
}

SSRec_Object.prototype.fetchByKey = function(stKey){
    var obj = invokeSyncService("service_fetchSSRec",null,"stKey",stKey);
    this.isSessionExpired = obj.isSessionExpired;
    if(this.isSessionExpired)
       return;
    if(obj.errorCode != "OK"){
        alert(obj.errorMsg);
        return -1;
    }
    var rec = obj.arrayRecs[0];
    if(!rec)
        return 0;
    this.stKey = rec.stKey;
    this.stModel = rec.stModel;
    this.stSavedName = rec.stSavedName;
    this.stYear = rec.stYear;
    this.stSchedule = rec.stSchedule;
    this.stLongForm = rec.stLongForm;
    this.stFormat = rec.stFormat;
    this.stMaxServiceIntervals = rec.stMaxServiceIntervals;
    this.stMaxAdditonalService = rec.stMaxAdditonalService;;
    this.isSessionExpired = rec.isSessionExpired;
    return this.stKey;
}

SSRec_Object.prototype.fetchByName = function(name){
    var obj = invokeSyncService("service_fetchSSRec",null,"stSavedName",name);
    this.isSessionExpired = obj.isSessionExpired;
    if(this.isSessionExpired)
       return;
    if(obj.errorCode != "OK"){
        alert(obj.errorMsg);
        return -1;
    }
    var rec = obj.arrayRecs[0];
    if(!rec)
        return 0;
    this.stKey = rec["stKey"];
    this.stModel = rec["stModel"];
    this.stSavedName = rec["stSavedName"];
    this.stYear = rec["stYear"];
    this.stSchedule = rec["stSchedule"];
    this.stLongForm = rec["stLongForm"];
    this.stFormat = rec.stFormat;
    this.stMaxServiceIntervals = rec.stMaxServiceIntervals;
    this.stMaxAdditonalService = rec.stMaxAdditonalService;;
    this.isSessionExpired = rec.isSessionExpired;
    return this.stKey;
}

SSRec_Object.prototype.fetchFactory = function(stModel,stYear,stSchedule,ndealer){
    var nDealer = (ndealer != undefined) ? ndealer:0;
    var obj = invokeSyncService("service_fetchSSRec",null,"stModel",stModel,"stYear",stYear,"stSchedule",stSchedule,"dealer",nDealer);

    this.isSessionExpired = obj.isSessionExpired;
    if(this.isSessionExpired)
       return;
    if(obj.errorCode != "OK"){
        alert(obj.errorMsg);
        return -1;
    }
    var rec = obj.arrayRecs[0];
    if(!rec)
        return 0;
    this.stKey = rec["stKey"];
    this.stModel = rec["stModel"];
    this.stSavedName = rec["stSavedName"];
    this.stYear = rec["stYear"];
    this.stSchedule = rec["stSchedule"];
    this.stLongForm = rec["stLongForm"];
    this.stFormat = rec.stFormat;
    this.stMaxServiceIntervals = rec.stMaxServiceIntervals;
    this.stMaxAdditonalService = rec.stMaxAdditonalService;;
    this.isSessionExpired = rec.isSessionExpired;
    return this.stKey;
}

SSRec_Object.prototype.DeleteDealerRec = function(stKey){
    var obj = invokeSyncService("service_DeleteSSRec",null,"stKey",stKey);
    this.isSessionExpired = obj.isSessionExpired;
    if(this.isSessionExpired)
       return false;
    if(obj.errorCode != "OK"){
        alert(obj.errorMsg);
        return false;
    }
    return true;
}

function findControl(controlID,bNoPrompt){
    try{
        var control = document.getElementById(controlID);
        if(bNoPrompt)
            return control;
        if(!control){
            alert("Could not find control:" + controlID);
        }
        return control;
    }
    catch(err){
        if(bNoPrompt)
            return null;

        alert("Could not find control:" + controlID);
        return null;
    }
}

function setControlValue(controlName,value){
    var control = findControl(controlName);
    control.value = value;
}

function getControlValue(controlName){
    var control = findControl(controlName);
    return control.value;
}

function XMLHttpObj() {
  var xmlhttp;
  /*@cc_on
  @if (@_jscript_version >= 5)
    try {
      xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (E) {
        xmlhttp = false;
      }
    }
  @else
  xmlhttp = false;
  @end @*/
  if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
    try {
      xmlhttp = new XMLHttpRequest();
    } catch (e) {
      xmlhttp = false;
    }
  }
  return xmlhttp;
}


function makeString(str){
    str = "\"" + str + "\"";
    return str;
}


function setPreviewMode(nKey){
  var obj = invokeSyncService("service_setPreviewMode",null,"PreviewMode","1","stKey",nKey);
  if(obj.isSessionExpired)
       return false;
  if(obj.errorCode != "OK"){
      alert(obj.errorMsg);
      return false;
  }
  return true;
}

function isPreviewMode(nKey){
    var obj = invokeSyncService("service_IsPreviewMode",null,"stKey",nKey);
    if(obj.isSessionExpired)
       return false;
    if(obj.errorCode != "OK"){
        alert(obj.errorMsg);
        return false;
    }
    var array = obj.arrayCodes;
    return ("1" == array["PreviewMode"]);
}

function SSRequest_Object(key){
    this.stKey = null;
    this.DealerID = null;
    this.DealerName = null;
    this.Address = null;
    this.Phone = null;
    this.Hour = null;
    this.Website = null;
    this.Image = null;
    this.PrintType = null;
    this.Qty = null;
    this.stKeyServiceSchedule = null;
    this.ExpirationDate = null;
    this.isSessionExpired = false;
    this.NoDisplayLogo = 0;

    var obj = invokeSyncService("service_fetchSSRequest",null,"ssid",key);
    this.isSessionExpired = obj.isSessionExpired;
    if(this.isSessionExpired)
        return -1;
    if(obj.errorCode != "OK"){
        alert(obj.errorMsg);
        return -1;
    }
    var rec = obj.arrayRecs[0];
    if(!rec)
        return 0;
    this.stKey = rec.stkey;
    this.DealerID = rec.DealerID;
    this.DealerName = rec.DealerName;
    this.Address = rec.Address;
    this.Phone = rec.Phone;
    this.Hour = rec.Hour;
    this.Website = rec.Website;
    this.Image = rec.Image;
    this.PrintType = rec.PrintType;
    this.Qty = rec.Qty;
    this.stKeyServiceSchedule = rec.stKeyServiceSchedule;
    this.NoDisplayLogo = parseInt(rec.NoDisplayLogo,10);
}


function SessionRec_Object(){
    this.stKey = null;
    this.SSID = 0;
    this.MenuId= 0;
    this.RandomString = 0;
    this.isSessionExpired = false;

    var obj = invokeSyncService("service_fetchSessionRec",null);
    this.isSessionExpired = obj.isSessionExpired;
    if(this.isSessionExpired)
        return -1;
    if(obj.errorCode != "OK"){
        alert(obj.errorMsg);
        return -1;
    }
    var rec = obj.arrayRecs[0];
    if(!rec)
        return 0;
    this.stKey = parseInt(rec["stKey"],10);
    this.SSID = parseInt(rec["SSID"],10);
    this.MenuId = parseInt(rec["MenuId"],10);
    this.RandomString = rec["RandomString"];
}

// assume in us date format: mm/dd/yyyy
function NormalizeDate(strDate){
   var idx = strDate.indexOf("/");
   if(idx == -1) return null;
   var strMonth = strDate.substr(0,idx);
   if(strMonth.length !=1 && strMonth.length != 2)
      return null;

   var num = parseInt(strMonth,10);
   if(num == NaN) return null;
   if(num < 1 || num > 12)
      return null;
   if(num < 10 && strMonth.length == 1)
      strMonth = "0" + strMonth;

   var idx2 = strDate.indexOf("/",idx+1);
   if(idx2 == -1) return null;
   var strDay = strDate.substr(idx+1,idx2-idx-1);
   if(strDay.length != 1 && strDay.length != 2)
      return null;
   num = parseInt(strDay,10);
   if(num == NaN) return null;
   if(num < 1 || num > 31)
      return null;
   if(num < 10 && strDay.length == 1)
      strDay = "0" + strDay;

   var strYear = strDate.substr(idx2+1);
   if(strYear.length != 4) return null;
   var nYear = parseInt(strYear,10);
   if(nYear == NaN) return null;
   if(nYear < 0 || nYear > 2035)
      return null;

   var strRet = strMonth + "/" + strDay + "/" + strYear;
   return strRet;
}


/**
 * DHTML date validation script. Courtesy of SmartWebby.com (http://www.smartwebby.com/dhtml/)
 */
// Declaring valid date character, minimum year and maximum year
var dtCh= "/";
var minYear=1900;
var maxYear=2100;

function isInteger(s){
   var i;
    for (i = 0; i < s.length; i++){
        // Check that current character is number.
        var c = s.charAt(i);
        if (((c < "0") || (c > "9"))) return false;
    }
    // All characters are numbers.
    return true;
}

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++){
        var c = s.charAt(i);
        if (bag.indexOf(c) == -1) returnString += c;
    }
    return returnString;
}

function daysInFebruary (year){
   // February has 29 days in any year evenly divisible by four,
    // EXCEPT for centurial years which are not also divisible by 400.
    return (((year % 4 == 0) && ( (!(year % 100 == 0)) || (year % 400 == 0))) ? 29 : 28 );
}
function DaysArray(n) {
   for (var i = 1; i <= n; i++) {
      this[i] = 31
      if (i==4 || i==6 || i==9 || i==11) {this[i] = 30}
      if (i==2) {this[i] = 29}
   }
   return this
}

function isDate2(dtStr){
   var daysInMonth = DaysArray(12)
   var pos1=dtStr.indexOf(dtCh)
   var pos2=dtStr.indexOf(dtCh,pos1+1)
   var strMonth=dtStr.substring(0,pos1)
   var strDay=dtStr.substring(pos1+1,pos2)
   var strYear=dtStr.substring(pos2+1)
   strYr=strYear
   if (strDay.charAt(0)=="0" && strDay.length>1) strDay=strDay.substring(1)
   if (strMonth.charAt(0)=="0" && strMonth.length>1) strMonth=strMonth.substring(1)
   for (var i = 1; i <= 3; i++) {
      if (strYr.charAt(0)=="0" && strYr.length>1) strYr=strYr.substring(1)
   }
   month=parseInt(strMonth,10)
   day=parseInt(strDay,10)
   year=parseInt(strYr,10)
   if (pos1==-1 || pos2==-1){
      alert("The date format should be : mm/dd/yyyy")
      return false
   }
   if (strMonth.length<1 || month<1 || month>12){
      alert("Please enter a valid month")
      return false
   }
   if (strDay.length<1 || day<1 || day>31 || (month==2 && day>daysInFebruary(year)) || day > daysInMonth[month]){
      alert("Please enter a valid day")
      return false
   }
   if (strYear.length != 4 || year==0 || year<minYear || year>maxYear){
      alert("Please enter a valid 4 digit year between "+minYear+" and "+maxYear)
      return false
   }
   if (dtStr.indexOf(dtCh,pos2+1)!=-1 || isInteger(stripCharsInBag(dtStr, dtCh))==false){
      alert("Please enter a valid date")
      return false
   }
   return true
}

function topGotoPage(url,bClearSessionRec){
    if(bClearSessionRec){
        var http = invokeSyncService("service_ClearSessionRec",null);
        if(http.isSessionExpired){
            return;
        }
        if(http.errorCode != "OK"){
            alert(http.errorMsg);
            return false;
        }
    }
    url += "?rdn=" + rdn;
    window.location = url;
}

function getTimeStamp()
{
   var aDate = new Date();
   var stamp = aDate.getTime();

   return stamp;
}

function PdfJumpToPage(pdf,page){
    var url = pdf + "?ts=" + getTimeStamp() + "#page=" + page;
    window.open(url,"pdfviewer");
}

// check a file with extension
function TheFileWithExtension(thefile,extension){
    thefile = thefile.toLowerCase();
    extension = extension.toLowerCase();
    var idx = thefile.lastIndexOf(extension);
    if(idx == -1)
        return false;
    var isextension =  thefile.length-idx == extension.length;
    return isextension;
}

function LogoSupportExtension(theextensions,thefile){
     var theextensions = theextensions.split(",");
     var len = theextensions.length;
     for(var idx = 0;idx < len;idx++){
        if(TheFileWithExtension(thefile,theextensions[idx]))
            return true;
     }
     return false;
}

function DispLogoSupportExtensions(theextensions){
    alert("only support the files with extension: " + theextensions);
}

String.prototype.Trim = function() { return this.replace(/^\s+|\s+$/g, ''); }

function GetControl(id) {
    var control = document.getElementById(id);
    if (!control) {
        alert("control id:'" + id + "' does not exist");
    }
    return control;
}

function SetVisibleId(controlid, bvisible) {
    var control = GetControl(controlid);

    if (false && gblIsMozilla) {
       control.disabled = !bvisible;
    } else {
        control.style.display = (bvisible) ? "" : "none";
    }
}

function SetVisibleIds(bvisible) {
    for (var i = 1; i < arguments.length; i++ ) {
        var control = GetControl(arguments[i]);
        if (false && gblIsMozilla) {
            control.disabled = !bvisible;
        } else {
            control.style.display = (bvisible) ? "" : "none";
        }
    }
}

function IsVisible(id){
    var control = GetControl(id);
    if (false && gblIsMozilla)
        return !control.disabled;
    else{
        return control.style.display != "none";
    }
}

// http://javascript.crockford.com/remedial.html
function typeOf(value) {
    var s = typeof value;
    if (s === 'object') {
        if (value) {
            if (typeof value.length === 'number' &&
                    !(value.propertyIsEnumerable('length')) &&
                    typeof value.splice === 'function') {
                s = 'array';
            }
        } else {
            s = 'null';
        }
    }
    return s;
}

function SetDisableIds(bDisabled) {
    if (arguments.length == 2 && typeOf(arguments[1]) == "array") { // watch out I using typeOf not typeof
        var arry = arguments[1];
        for (var idx = 0; idx < arry.length; idx++) {
            var control = typeof (arry[idx]) == "string" ? GetControl(arry[idx]) : arry[idx];
            control.disabled = bDisabled;
        }
        return;
    }

    for (var i = 1; i < arguments.length; i++) {
        var control = typeOf(arguments[i]) == "string" ? GetControl(arguments[i]) : arguments[i];
        control.disabled = bDisabled;
    }
}

function SetControlVisible(control, bvisible) {
    if (false && gblIsMozilla) {
        control.disabled = !bvisible;
    } else {
        control.style.display = (bvisible) ? "" : "none";
    }
}

function SetControlsVisible(bvisible) {
    for (var i = 1; i < arguments.length; i++) {
        var control = arguments[i];
        if (typeOf(control) == "string")
            control = GetControl(control);
        if (false && gblIsMozilla) {
            control.disabled = !bvisible;
        } else {
            control.style.display = (bvisible) ? "" : "none";
        }
    }
}

function BuildServiceUrl(service) {
    var URL = "/CorpHttpHandler.ashx?service=" + service + "&rdn=" + rdn + "&mysessionid=" + sessionid;
    for (var i = 1; i < arguments.length; i += 2) {
        if (URL != "")
            URL += "&"
        URL += arguments[i] + "=" + escape(arguments[i + 1]);
    }
    return URL;
}


function IsEmailValid(str,bprompt) {
    var at = "@";
    var dot = ".";
    var lat = str.indexOf(at);
    var lstr = str.length;
    var ldot = str.indexOf(dot);

    var errorMsg = "Invalid E-mail Format.";
    if (str.indexOf(at) == -1) {
        if (bprompt)
            alert(errorMsg);
        return false;
    }

    if (str.indexOf(at) == -1 || str.indexOf(at) == 0 || str.indexOf(at) == lstr) {
        if (bprompt)
            alert(errorMsg);
        return false;
    }

    if (str.indexOf(dot) == -1 || str.indexOf(dot) == 0 || str.indexOf(dot) == lstr) {
        if (bprompt)
            alert(errorMsg);
        return false;
    }

    if (str.indexOf(at, (lat + 1)) != -1) {
        if (bprompt)
            alert(errorMsg);
        return false;
    }

    if (str.substring(lat - 1, lat) == dot || str.substring(lat + 1, lat + 2) == dot) {
        if (bprompt)
            alert(errorMsg);
        return false;
    }

    if (str.indexOf(dot, (lat + 2)) == -1) {
        if (bprompt)
            alert(errorMsg);
        return false;
    }

    if (str.indexOf(" ") != -1) {
        if (bprompt)
            alert(errorMsg);
        return false;
    }

    return true;
}

function RemovePhoneChar(strPhone) {
    var ret = "";
    for (var idx = 0; idx < strPhone.length; idx++) {
        var ch = strPhone.charAt(idx);
        if (ch == '(' || ch == ')' || ch == '_' || ch == '-')
            continue;
        ret += ch;
    }
    return ret;
}

function RemoveTableRowsExceptTopRows(id, excepttoprows) {
    var table = GetControl(id);
    var rows = table.rows;

    while (rows.length > excepttoprows) {
        table.deleteRow(rows.length - 1);
    }
}

/*
 * Copyright (C) 2006 Baron Schwartz <baron at sequent dot org>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by the
 * Free Software Foundation, version 2.1.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 * details.
 *
 * $Revision: 1.3 $
 */

// Abbreviations: LODP = Left Of Decimal Point, RODP = Right Of Decimal Point
Number.formatFunctions = {count:0};

// Constants useful for controlling the format of numbers in special cases.
Number.prototype.NaN         = 'NaN';
Number.prototype.posInfinity = 'Infinity';
Number.prototype.negInfinity = '-Infinity';

Number.prototype.numberFormat = function(format, context) {
    if (isNaN(this) ) {
        return Number.prototype.NaNstring;
    }
    else if (this == +Infinity ) {
        return Number.prototype.posInfinity;
    }
    else if ( this == -Infinity) {
        return Number.prototype.negInfinity;
    }
    else if (Number.formatFunctions[format] == null) {
        Number.createNewFormat(format);
    }
    return this[Number.formatFunctions[format]](context);
}

Number.createNewFormat = function(format) {
    var funcName = "format" + Number.formatFunctions.count++;
    Number.formatFunctions[format] = funcName;
    var code = "Number.prototype." + funcName + " = function(context){\n";

    // Decide whether the function is a terminal or a pos/neg/zero function
    var formats = format.split(";");
    switch (formats.length) {
        case 1:
            code += Number.createTerminalFormat(format);
            break;
        case 2:
            code += "return (this < 0) ? this.numberFormat(\""
                + String.escape(formats[1])
                + "\", 1) : this.numberFormat(\""
                + String.escape(formats[0])
                + "\", 2);";
            break;
        case 3:
            code += "return (this < 0) ? this.numberFormat(\""
                + String.escape(formats[1])
                + "\", 1) : ((this == 0) ? this.numberFormat(\""
                + String.escape(formats[2])
                + "\", 2) : this.numberFormat(\""
                + String.escape(formats[0])
                + "\", 3));";
            break;
        default:
            code += "throw 'Too many semicolons in format string';";
            break;
    }
    eval(code + "}");
}

Number.createTerminalFormat = function(format) {
    // If there is no work to do, just return the literal value
    if (format.length > 0 && format.search(/[0#?]/) == -1) {
        return "return '" + String.escape(format) + "';\n";
    }
    // Negative values are always displayed without a minus sign when section separators are used.
    var code = "var val = (context == null) ? new Number(this) : Math.abs(this);\n";
    var thousands = false;
    var lodp = format;
    var rodp = "";
    var ldigits = 0;
    var rdigits = 0;
    var scidigits = 0;
    var scishowsign = false;
    var sciletter = "";
    // Look for (and remove) scientific notation instructions, which can be anywhere
    m = format.match(/\..*(e)([+-]?)(0+)/i);
    if (m) {
        sciletter = m[1];
        scishowsign = (m[2] == "+");
        scidigits = m[3].length;
        format = format.replace(/(e)([+-]?)(0+)/i, "");
    }
    // Split around the decimal point
    var m = format.match(/^([^.]*)\.(.*)$/);
    if (m) {
        lodp = m[1].replace(/\./g, "");
        rodp = m[2].replace(/\./g, "");
    }
    // Look for %
    if (format.indexOf('%') >= 0) {
        code += "val *= 100;\n";
    }
    // Look for comma-scaling to the left of the decimal point
    m = lodp.match(/(,+)(?:$|[^0#?,])/);
    if (m) {
        code += "val /= " + Math.pow(1000, m[1].length) + "\n;";
    }
    // Look for comma-separators
    if (lodp.search(/[0#?],[0#?]/) >= 0) {
        thousands = true;
    }
    // Nuke any extraneous commas
    if ((m) || thousands) {
        lodp = lodp.replace(/,/g, "");
    }
    // Figure out how many digits to the l/r of the decimal place
    m = lodp.match(/0[0#?]*/);
    if (m) {
        ldigits = m[0].length;
    }
    m = rodp.match(/[0#?]*/);
    if (m) {
        rdigits = m[0].length;
    }
    // Scientific notation takes precedence over rounding etc
    if (scidigits > 0) {
        code += "var sci = Number.toScientific(val,"
            + ldigits + ", " + rdigits + ", " + scidigits + ", " + scishowsign + ");\n"
            + "var arr = [sci.l, sci.r];\n";
    }
    else {
        // If there is no decimal point, round to nearest integer, AWAY from zero
        if (format.indexOf('.') < 0) {
            code += "val = (val > 0) ? Math.ceil(val) : Math.floor(val);\n";
        }
        // Numbers are rounded to the correct number of digits to the right of the decimal
        code += "var arr = val.round(" + rdigits + ").toFixed(" + rdigits + ").split('.');\n";
        // There are at least "ldigits" digits to the left of the decimal, so add zeros if needed.
        code += "arr[0] = (val < 0 ? '-' : '') + String.leftPad((val < 0 ? arr[0].substring(1) : arr[0]), "
            + ldigits + ", '0');\n";
    }
    // Add thousands separators
    if (thousands) {
        code += "arr[0] = Number.addSeparators(arr[0]);\n";
    }
    // Insert the digits into the formatting string.  On the LHS, extra digits are copied
    // into the result.  On the RHS, rounding has chopped them off.
    code += "arr[0] = Number.injectIntoFormat(arr[0].reverse(), '"
        + String.escape(lodp.reverse()) + "', true).reverse();\n";
    if (rdigits > 0) {
        code += "arr[1] = Number.injectIntoFormat(arr[1], '" + String.escape(rodp) + "', false);\n";
    }
    if (scidigits > 0) {
        code += "arr[1] = arr[1].replace(/(\\d{" + rdigits + "})/, '$1" + sciletter + "' + sci.s);\n";
    }
    return code + "return arr.join('.');\n";
}

Number.toScientific = function(val, ldigits, rdigits, scidigits, showsign) {
    var result = {l:"", r:"", s:""};
    var ex = "";
    // Make ldigits + rdigits significant figures
    var before = Math.abs(val).toFixed(ldigits + rdigits + 1).trim('0');
    // Move the decimal point to the right of all digits we want to keep,
    // and round the resulting value off
    var after = Math.round(new Number(before.replace(".", "").replace(
        new RegExp("(\\d{" + (ldigits + rdigits) + "})(.*)"), "$1.$2"))).toFixed(0);
    // Place the decimal point in the new string
    if (after.length >= ldigits) {
        after = after.substring(0, ldigits) + "." + after.substring(ldigits);
    }
    else {
        after += '.';
    }
    // Find how much the decimal point moved.  This is #places to LODP in the original
    // number, minus the #places in the new number.  There are no left-padded zeroes in
    // the new number, so the calculation for it is simpler than for the old number.
    result.s = (before.indexOf(".") - before.search(/[1-9]/)) - after.indexOf(".");
    // The exponent is off by 1 when it gets moved to the left.
    if (result.s < 0) {
        result.s++;
    }
    // Split the value around the decimal point and pad the parts appropriately.
    result.l = (val < 0 ? '-' : '') + String.leftPad(after.substring(0, after.indexOf(".")), ldigits, "0");
    result.r = after.substring(after.indexOf(".") + 1);
    if (result.s < 0) {
        ex = "-";
    }
    else if (showsign) {
        ex = "+";
    }
    result.s = ex + String.leftPad(Math.abs(result.s).toFixed(0), scidigits, "0");
    return result;
}

Number.prototype.round = function(decimals) {
    if (decimals > 0) {
        var m = this.toFixed(decimals + 1).match(
            new RegExp("(-?\\d*)\.(\\d{" + decimals + "})(\\d)\\d*$"));
        if (m && m.length) {
            return new Number(m[1] + "." + String.leftPad(Math.round(m[2] + "." + m[3]), decimals, "0"));
        }
    }
    return this;
}

Number.injectIntoFormat = function(val, format, stuffExtras) {
    var i = 0;
    var j = 0;
    var result = "";
    var revneg = val.charAt(val.length - 1) == '-';
    if ( revneg ) {
       val = val.substring(0, val.length - 1);
    }
    while (i < format.length && j < val.length && format.substring(i).search(/[0#?]/) >= 0) {
        if (format.charAt(i).match(/[0#?]/)) {
            // It's a formatting character; copy the corresponding character
            // in the value to the result
            if (val.charAt(j) != '-') {
                result += val.charAt(j);
            }
            else {
                result += "0";
            }
            j++;
        }
        else {
            result += format.charAt(i);
        }
        ++i;
    }
    if ( revneg && j == val.length ) {
        result += '-';
    }
    if (j < val.length) {
        if (stuffExtras) {
            result += val.substring(j);
        }
        if ( revneg ) {
             result += '-';
        }
    }
    if (i < format.length) {
        result += format.substring(i);
    }
    return result.replace(/#/g, "").replace(/\?/g, " ");
}

Number.addSeparators = function(val) {
    return val.reverse().replace(/(\d{3})/g, "$1,").reverse().replace(/^(-)?,/, "$1");
}

String.prototype.reverse = function() {
    var res = "";
    for (var i = this.length; i > 0; --i) {
        res += this.charAt(i - 1);
    }
    return res;
}

String.prototype.trim = function(ch) {
    if (!ch) ch = ' ';
    return this.replace(new RegExp("^" + ch + "+|" + ch + "+$", "g"), "");
}

String.leftPad = function (val, size, ch) {
    var result = new String(val);
    if (ch == null) {
        ch = " ";
    }
    while (result.length < size) {
        result = ch + result;
    }
    return result;
}

String.escape = function(string) {
    return string.replace(/('|\\)/g, "\\$1");
}


function round_decimals(number,decimals){
    return new Number(number).numberFormat("0.00");
}

function currency_format(num) {
    return formatCurrency(num);
}

function TrimTo2Decimal(num){
    return round_decimals(num,2);
}

function formatCurrency(num) {
    num = num.toString().replace(/\$|\,/g,'');
    if(isNaN(num))
    num = "0";
    sign = (num == (num = Math.abs(num)));
    num = Math.floor(num*100+0.50000000001);
    cents = num%100;
    num = Math.floor(num/100).toString();
    if(cents<10)
    cents = "0" + cents;
    for (var i = 0; i < Math.floor((num.length-(1+i))/3); i++)
    num = num.substring(0,num.length-(4*i+3))+','+
    num.substring(num.length-(4*i+3));
    return (((sign)?'':'-') + '$' + num + '.' + cents);
}

