// -- wffcook.js

// -------------------------------------------------------------
// -- URL encode/decode a string
// -------------------------------------------------------------

//----URL Encode a value ----------------------

function ck_urlencd(val)
{
  if (val == null) return '';

  var encd = '';
  var spac = val.split(' ');
  for (var i = spac.length; i--;)
  {
    var enpl = '';
    var plus = spac[i].split('+');
    for (var j = plus.length; j--;)
    {    
      var ensl = '';
      var slsh = plus[j].split('/');
      for (var k = slsh.length; k--;)
	ensl = ((k > 0) ? '%2F' : '') + escape(slsh[k]) + ensl;

      enpl = ((j > 0) ? '%2B' : '') + ensl + enpl;
    }
    encd = ((i > 0) ? '+' : '') + enpl + encd;
  }
  return encd;
}
//----URL Decode a value ----------------------

function ck_urldecd(val)
{
  if (val == null) return '';

  var decd = '';
  var plus = val.split('+');
  for (var i = plus.length; i--;)
    decd = ((i > 0) ? ' ' : '') + unescape(plus[i]) + decd;

  return decd;
}
// -------------------------------------------------------------
// -- path and domain validation
// -------------------------------------------------------------

//----Validate/extract path for window --------

function ck__Path(path, win)
{
  if (!path) return '';
  if ( path == '!')
  {
    path = win.location.pathname;
    return path.substring(0, path.lastIndexOf('/'));
  }
  return ((path.indexOf('/') == 0) ? '' : '/') + path;
}
//----Validate/retrieve domain for document ---

function ck__Domain(domain, win)
{
  if (domain == null) return '';
  if (domain == '!' ) domain = win.document.domain;
  if (domain == ''  ) return '';

  var dots = 0;
  for (var i = domain.length; i-- > 0;)
  {
    i = domain.lastIndexOf('.', i);
    if (i >= 0) dots++;
  }
  return ((dots < 2 ) ? '.' : '') + domain;
}
// -------------------------------------------------------------
// -- object Cookie
// -------------------------------------------------------------

//----Add an item ----------------------------- addItem()

function ck__AddPiece(name, val)
{
  var ndx = this.pieces.length;
  this.pieces[ndx] = ck_urlencd(name); 
  if (val == null) return;
  this.pieces[ndx] += '=' + ck_urlencd(val);
}
//----Remove an item -------------------------- removeItem()

function ck__RemovePiece(name)
{
  var ndx = this.indexOf(name);
  if (ndx >= 0) this.pieces[ndx] = null;
}
//----Replace an item ------------------------- replaceItem()

function ck__UpdatePiece(name, val)
{
  this.removeItem(name);
  this.addItem(name, val);
}
//----Get the value of an item ---------------- valueOf()

function ck__GetValue(name)
{
  return this.valueAt(this.indexOf(name));
}
//----Get value of item at position ndx ------- valueAt()

function ck__GetIndexedValue(ndx)
{
  if (ndx < 0)			return '';
  if (this.pieces[ndx] == null)	return '';

  var pair = this.pieces[ndx].split('=');
  if (pair.length == 0)		return '';
  return ck_urldecd(pair[pair.length-1]);
}
//----Get name of item at position ndx -------- nameAt()

function ck__GetIndexedName(ndx)
{
  if (ndx < 0)			return '';
  if (this.pieces[ndx] == null)	return '';

  var pair = this.pieces[ndx].split('=');
  if (pair.length < 2)		return '';
  return ck_urldecd(pair[0]);
}
//----Get index of item ----------------------- indexOf()

function ck__PieceIndex(name)
{
  if (!name) return -1;
  var ename = ck_urlencd(name);

  for (var i = this.pieces.length; i--;)
  {
    if (this.pieces[i] == null)	continue;
    var pair = this.pieces[i].split('=');
    if (pair[0] == ename)	return i;
  }
  return -1;
}
//----Add domain-path items to cookie --------- qualify()

function ck__QualifyCookie(path, domain)
{
  if (path) 
    this.replaceItem("!path!", ck__Path(path, this.win));

  if (domain)
    this.replaceItem("!domain!", ck__Domain(domain, this.win));
}
//----get the "cookie value" ------------------ toString()

function ck__CookieVal()
{
  var nil = true;
  var str = '';
  for (var i = this.pieces.length; i--;)
  {
    if (this.pieces[i] == null)	continue;
    if (this.pieces[i] == ''  )	continue;

    str = this.pieces[i] + (!nil ? '&' : '') + str;
    nil = false;
  }
  return str;
}
//----Write the cookie back into cookies.txt--- write()

function ck__WriteCookie(days, path, domain, secure)
{
  var name  = ck_urlencd(this.name) + '=';
  var value = ck_urlencd(this.toString());
  var till  = "";

  if (!value) value = "!nil!";
  if (days)
  {
    var expire   = new Date();
    var epoch    = new Date(0);
    var duration = 365*24*3600*1000;

    if (days >= 0) duration *= days;
    else
    {
      expire.setTime(epoch.getTime());
      value = "";
    }
    expire.setTime(expire.getTime() - epoch.getTime() + duration);
    till = ("; EXPIRES=" + expire.toGMTString());
  }
  if (!domain)	domain = this.valueOf("!domain!");
   else		domain = ck__Domain(domain, this.win);
  if (!path)    path   = this.valueOf("!path!");
   else		path   = ck__Path(path, this.win);

  this.win.document.cookie = name + value + till +
	((domain) ? "; DOMAIN=" + domain : "") +
	((path)   ? "; PATH="   + path   : "") +
	((secure) ? "; SECURE" : "");
}
//----Release space of Cookie pieces ---------- release()

function ck__ReleasePieces()
{
  for (var i = this.pieces.length; i--;)
     this.pieces[i] = null;

  this.pieces = null;
  this.pieces = new Array;
}
//----a Cookie object -------------------------

function obj__Cookie(win, name, value)
{
  if (name.indexOf(' ') == 0)
      name = name.substring(1, name.length);

  this.win	= win;
  this.name	= ck_urldecd(name);
  this.index	= -1;

  if (!value || value == "!nil!")
    this.pieces = new Array;
  else
  {
    value	= ck_urldecd(value);
    this.pieces	= value.split('&');
  }

  this.indexOf     = ck__PieceIndex;
  this.replaceItem = ck__UpdatePiece;
  this.removeItem  = ck__RemovePiece;
  this.addItem     = ck__AddPiece;
  this.nameAt	   = ck__GetIndexedName;
  this.valueOf     = ck__GetValue;
  this.valueAt     = ck__GetIndexedValue;
  this.toString    = ck__CookieVal;
  this.qualify     = ck__QualifyCookie;
  this.write       = ck__WriteCookie;
  this.release	   = ck__ReleasePieces;
  return this;

} /* obj__Cookie */

// -------------------------------------------------------------
// -- object CookieSet
// -------------------------------------------------------------

//----Add a cookie to CookieSet object -------- add()

function ck__AddCookie(name, path, domain)
{
  var ndx = this.cookies.length;
  this.cookies[ndx] = new obj__Cookie(this.win, ck_urlencd(name));
  this.cookies[ndx].index = ndx;
  this.cookies[ndx].qualify(path, domain);
  return this.cookies[ndx];
}
//----Delete a cookie from cookies.txt -------- remove()
//------- and from the CookieSet object--------

function ck__DelCookie(ndx, path, domain)
{
  if (this.cookies[ndx] == null) return;    

  this.cookies[ndx].release();
  this.cookies[ndx].write(-1, path, domain);
  this.cookies[ndx].name = null;
  this.cookies[ndx] = null;
}
//----Find a cookie in CookieSet object ------- access()

function ck__FindCookie(name, path, domain)
{
  var ndx = this.indexOf(name, path, domain);
  return (ndx < 0) ? null : this.cookies[ndx];
}
//----Get index of cookie in CookieSet object-- indexOf()

function ck__CookieIndex(name, path, domain)
{
  if (path)   path   = ck__Path(path, this.win);
  if (domain) domain = ck__Domain(domain, this.win);

  for (var ndx = this.cookies.length; ndx--;)
  {
    var aCookie = this.cookies[ndx];
    if (aCookie == null)	continue;
    if (aCookie.name != name)	continue;

    if (path   && (aCookie.valueOf("!path!")   != path))   continue;
    if (domain && (aCookie.valueOf("!domain!") != domain)) continue;
    return ndx;
  }
  return -1;
}
//----Release space of Cookies ---------------- release()

function ck__ReleaseCookies()
{
  for (var ndx  = this.cookies.length; ndx--;)
  {
    if (this.cookies[ndx] == null) continue;

    this.cookies[ndx].release();
    this.cookies[ndx].name   = null;
    this.cookies[ndx].pieces = null;
    this.cookies[ndx] = null;
  }
  this.cookies = null;
}
//----a CookieSet object ----------------------

function obj__CookieSet(win)
{
  this.win	= win;
  this.cookies	= new Array;

  if (win != null)
  {
    var cSet	= win.document.cookie.split(';');
    for (var ndx  = 0; ndx < cSet.length; ndx++)
    {
      var sCookie = cSet[ndx].split('=');
      this.cookies[ndx] = new obj__Cookie(win, sCookie[0], sCookie[1]);
      this.cookies[ndx].index = ndx;
    }
  }

  this.indexOf	= ck__CookieIndex;
  this.add	= ck__AddCookie;
  this.remove	= ck__DelCookie;
  this.access	= ck__FindCookie;
  this.release	= ck__ReleaseCookies;
  return this;
  
} /* obj__CookieSet */

// -------------------------------------------------------------
// -- retrieve a document's cookies
// -------------------------------------------------------------

function CookiesOf(win)
{
  var Cookie = new obj__CookieSet(win);
  return Cookie;
}


