//Modified by / Date:
//Description:
//----------------------------------
//B.Lim - JUN-13-2006
//Class and utils created
//uses encUtil.js
//uses hashUtil.js
//uses validate.js

var TIME_SECOND = 1000;
var TIME_MINUTE = TIME_SECOND * 60;
var TIME_HOUR = TIME_MINUTE * 60;
var TIME_DAY = TIME_HOUR * 24;

var RFLD_CREATE_DATE = 'createDate';
var RFLD_MOD_DATE = 'modDate';
var RFLD_EXP_DATE = 'expDate';
var RFLD_HASH = 'hash';

function CookieHandler(name, domain, path, encrypted, encKey) {
  this.Name = name;
  this.Domain = domain;
  this.Path = path;
  this.FieldList = new Collection();
  this.OrigEncCookieVal = '';
  this.RawCookieVal = '';
  this.SingleCookieVal = '';
  this.HashedCookieVal = '';
  this.FieldDelim = '&';
  this.FieldValDelim = '=';
  this.Encrypted = encrypted;
  this.EncKey = encKey;
  this.Hash = '';
  this.ReservedFldName = new Array();
  this.ReservedFldName[0] = RFLD_CREATE_DATE;
  this.ReservedFldName[1] = RFLD_MOD_DATE;
  this.ReservedFldName[2] = RFLD_EXP_DATE;
  this.ReservedFldName[3] = RFLD_HASH;

  for (var i=0; i<this.ReservedFldName.length; i++) {
    this.FieldList.addItem(this.ReservedFldName[i], null);
  }
}

//Loads the specified cookie
//Returns true if the cookie is found
CookieHandler.prototype.load = function(oDocument) {
  var sCookieStr = oDocument.cookie;
  var bCookieFound = false;

  if (sCookieStr != null) {  
    var iStartInd = sCookieStr.indexOf(this.Name + '=');
    if (iStartInd > -1) {
      bCookieFound = true;
      var iEndInd = sCookieStr.indexOf(';', iStartInd);
      if (iEndInd > -1) {
        this.RawCookieVal = sCookieStr.substring(iStartInd + this.Name.length + 1, iEndInd);
      } else {//there are no succeeding cookies
        this.RawCookieVal = sCookieStr.substring(iStartInd + this.Name.length + 1);
      }
    }
  }
  if (this.RawCookieVal != null) {
    if (this.Encrypted) {
      this.OrigEncCookieVal = this.RawCookieVal;
      this.RawCookieVal = decodeFromB64(this.RawCookieVal);
      this.RawCookieVal = this.doDecrypt(this.RawCookieVal);
    }
  
    //Retrieve field values
    if (this.RawCookieVal.indexOf(this.FieldValDelim) > -1) {
      var keyValList = new Array();
      keyValList = this.RawCookieVal.split(this.FieldDelim);

      for(var i=0; i < keyValList.length; i++) {
        var keyValPair = new Array();
        keyValPair = keyValList[i].split(this.FieldValDelim);

        if (this.containsField(keyValPair[0]) == true) {
          this.setFieldValue(keyValPair[0], unescape(keyValPair[1]));
        } else {
          this.addField(keyValPair[0], unescape(keyValPair[1]));
        }
        
        if (keyValPair[0] != RFLD_HASH) {
          if (this.HashedCookieVal != '') {
            this.HashedCookieVal += this.FieldDelim;
          }
          this.HashedCookieVal += keyValList[i];
        }
      }
    } else {//single encoded val, no fields
      this.SingleCookieVal = unescape(this.RawCookieVal);
    }
  }
  this.Hash = this.getFieldValue(RFLD_HASH);
  if ((this.Hash != null) && (this.Hash != '')) {
    bCookieFound = bCookieFound && this.checkHash(this.HashedCookieVal, this.Hash);
  } else {
    this.Hash = '';
  }

  return bCookieFound;
}

CookieHandler.prototype.save = function() {
  var sCookieTxt = this.Name + '=';
  var dCurrDate = new Date();
  var iCurrTime = dCurrDate.getTime();

  if (this.FieldList.getItem(RFLD_CREATE_DATE) == null) {
    this.FieldList.setItem(RFLD_CREATE_DATE, iCurrTime);
  }
  this.FieldList.setItem(RFLD_MOD_DATE, iCurrTime);

  var iExpTime = this.FieldList.getItem(RFLD_EXP_DATE);
  if (iExpTime == null) {
    iExpTime = iCurrTime + (TIME_HOUR * 24);
    this.FieldList.setItem(RFLD_EXP_DATE, iExpTime);
  }
  var dExpDate = new Date();
  dExpDate.setTime(iExpTime);

  var sCookieVal = '';
  this.FieldList.removeItem(RFLD_HASH);
  
  for (var i=0; i < this.FieldList.getSize(); i++) {
    sCookieVal += this.FieldList.getKeyAtIndex(i) + this.FieldValDelim;
    sCookieVal += escape(this.FieldList.getValAtIndex(i));
    if ((i+1) < this.FieldList.getSize()) {
      sCookieVal += this.FieldDelim;
    }
  }

  if (this.Encrypted) {
    this.Hash = this.doHash(sCookieVal);
    this.FieldList.addItem(RFLD_HASH, this.Hash);
    sCookieVal += this.FieldDelim + RFLD_HASH + this.FieldValDelim;
    sCookieVal += escape(this.FieldList.getValAtIndex(i));

    sCookieVal = this.doEncrypt(sCookieVal);
    sCookieVal = this.doEncode(sCookieVal);
  }

  sCookieTxt += sCookieVal;
  sCookieTxt += '; expires=' + dExpDate.toGMTString();
  sCookieTxt += '; path=' + this.Path;
  sCookieTxt += '; domain=' + this.Domain;

  document.cookie = sCookieTxt;
}

CookieHandler.prototype.setExpired = function() {
  this.addExpDateDays(-1);
  this.save();
}

CookieHandler.prototype.addExpDateTime = function(iTime) {
  this.addExpDate(iTime);
}

CookieHandler.prototype.addExpDateMinutes = function(iMin) {
  this.addExpDate(TIME_MINUTE*iMin);
}

CookieHandler.prototype.addExpDateHours = function(iHours) {
  this.addExpDate(TIME_HOUR*iHours);
}

CookieHandler.prototype.addExpDateDays = function(iDays) {
  this.addExpDate(TIME_DAY*iDays);
}

CookieHandler.prototype.addExpDate = function(iTime) {
  var iExpTime = this.FieldList.getItem(RFLD_EXP_DATE);
  if (iExpTime == null) {
    iExpTime = (new Date()).getTime();
  }
  iExpTime = Number(iExpTime) + iTime;
  this.FieldList.setItem(RFLD_EXP_DATE, iExpTime);
}

CookieHandler.prototype.setExpDate = function(iNewTime) {
  this.FieldList.setItem(RFLD_EXP_DATE, iNewTime);
}

CookieHandler.prototype.setExpDateToNow = function() {
  this.FieldList.setItem(RFLD_EXP_DATE, (new Date()).getTime());
}

CookieHandler.prototype.setEncrypted = function(isEncrypted) {
  this.Encrypted = isEncrypted;
}

CookieHandler.prototype.setEncKey = function(key) {
  this.EncKey = key;
}

CookieHandler.prototype.checkHash = function(sValue, sHash) {
  var bRetVal= false;
  var sNewHash = this.doHash(sValue);
  if (sHash == sNewHash) {
    bRetVal = true;
  }
  return bRetVal;
}

CookieHandler.prototype.doHash = function(sValue) {
  return hashToMD5Hex(sValue);
}

CookieHandler.prototype.doEncrypt = function(sValue) {
  return encryptToBT(sValue, this.EncKey);
}

CookieHandler.prototype.doDecrypt = function(sValue) {
  return decryptFromBT(sValue, this.EncKey);
}

CookieHandler.prototype.doEncode = function(sValue) {
  return encodeToB64(sValue);
}

CookieHandler.prototype.doDecode = function(sValue) {
  return decodeFromB64(sValue);
}

CookieHandler.prototype.addField = function(sFieldName, sFieldValue) {
  if (this.FieldList.containsKey(sFieldName)) {
    this.FieldList.setItem(sFieldName, sFieldValue);
  } else {
    this.FieldList.addItem(sFieldName, sFieldValue);
  }
}

CookieHandler.prototype.setFieldValue = function(sFieldName, sFieldValue) {
  if (this.FieldList.containsKey(sFieldName)) {
    this.FieldList.setItem(sFieldName, sFieldValue);
  }
}

CookieHandler.prototype.getFieldValue = function(sFieldName) {
  return this.FieldList.getItem(sFieldName);
}

CookieHandler.prototype.getFieldList = function() {
  return this.FieldList;
}

CookieHandler.prototype.containsField = function(sFieldName) {
  return this.FieldList.containsKey(sFieldName);
}