// web.js

////////////////////////////////////////////////////////////////////////////////
Number.prototype.NaN0 = function()
{
  return isNaN(this)? 0 : this;
}

////////////////////////////////////////////////////////////////////////////////
String.prototype.trim = function()
{
  return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
};

////////////////////////////////////////////////////////////////////////////////
var web = new Object();

////////////////////////////////////////////////////////////////////////////////
web.KEY_CODE_ENTER  = 13;
web.KEY_CODE_ESCAPE = 27;
web.KEY_CODE_UP     = 38;
web.KEY_CODE_DOWN   = 40;
web.KEY_CODE_LEFT   = 37;
web.KEY_CODE_RIGHT  = 39;

////////////////////////////////////////////////////////////////////////////////
web.$ = function(id, no_throw)
{
  if(!id)
  {
    throw new Error('#{FunctionArgumentIsEmpty_[web.$(<id>)]}');
  }

  var el = document.getElementById(id);

  if(!el && !no_throw)
  {
    throw new Error('#{CouldNotGetElementById_[web.$("' + id + '")]}');
  }

  return el;
};

////////////////////////////////////////////////////////////////////////////////
web.getHttpRequest = function()
{
  if(typeof XMLHttpRequest != 'undefined')
  {
    return new XMLHttpRequest();
  }

  if(typeof ActiveXObject != 'undefined')
  {
    var vers = ['MSXML2.XMLHttp.5.0',
                'MSXML2.XMLHttp.4.0',
                'MSXML2.XMLHttp.3.0',
                'MSXML2.XMLHttp',
                'Microsoft.XMLHttp'];

    for(var i = 0; i < vers.length; i++)
    {
      try
      {
        return new ActiveXObject(vers[i]);
      }

      catch(ex) {}
    }
  }

  throw new Error('#{CouldNotCreateHttpRequest_[web.getHttpRequest()]}');
};

////////////////////////////////////////////////////////////////////////////////
web.getNodePosition = function(node)
{
  if(!node)
  {
    throw new Error('#{FunctionArgumentIsEmpty_[web.getNodePosition(<node>)]}');
  }

  var x = 0;
  var y = 0;

  while(node)
  {
    x += node.offsetLeft;
    y += node.offsetTop;

    node = node.offsetParent;
  }

  return {left : x,
          top  : y};
};

////////////////////////////////////////////////////////////////////////////////
web.getEventObject = function()
{
  if(!window.event)
  {
    throw new Error('#{CoundGetEventObject_[web.getEventObject()]}');
  }

  return window.event;
};

////////////////////////////////////////////////////////////////////////////////
web.attachEventListener = function(node, evtType, fn, capturing)
{
  if(!node)
  {
    throw new Error('#{FunctionArgumentIsEmpty_[web.attachEventListener(<node>, evtType, fn, capturing)]}');
  }

  if(!evtType)
  {
    throw new Error('#{FunctionArgumentIsEmpty_[web.attachEventListener(node, <evtType>, fn, capturing)]}');
  }

  if(!fn)
  {
    throw new Error('#{FunctionArgumentIsEmpty_[web.attachEventListener(node, evtType, <fn>, capturing)]}');
  }

  if(node.addEventListener)
  {
    node.addEventListener(evtType, fn, capturing ? true : false);

    return;
  }

  if(node.attachEvent)
  {
    node.attachEvent('on' + evtType, fn);

    return;
  }

  throw new Error('#{CouldNotAttachEventListener_[web.attachEventListener("' + node + '", "' + evtType + '", "' + fn + '", "' + capturing + '")]}');
};

////////////////////////////////////////////////////////////////////////////////
web.detachEventListener = function(node, evtType, fn, capturing)
{
  if(!node)
  {
    throw new Error('#{FunctionArgumentIsEmpty_[web.detachEventListener(<node>, evtType, fn, capturing)]}');
  }

  if(!evtType)
  {
    throw new Error('#{FunctionArgumentIsEmpty_[web.detachEventListener(node, <evtType>, fn, capturing)]}');
  }

  if(!fn)
  {
    throw new Error('#{FunctionArgumentIsEmpty_[web.detachEventListener(node, evtType, <fn>, capturing)]}');
  }

  if(node.removeEventListener)
  {
    node.removeEventListener(evtType, fn, capturing ? true : false);

    return;
  }

  if(node.detachEvent)
  {
    node.detachEvent('on' + evtType, fn);

    return;
  }

  throw new Error('#{CouldNotAttachEventListener_[web.detachEventListener("' + node + '", "' + evtType + '", "' + fn + '", "' + capturing + '")]}');
};

////////////////////////////////////////////////////////////////////////////////
web.getSourceNode = function(evt)
{
  if(!evt)
  {
    throw new Error('#{FunctionArgumentIsEmpty_[web.getSourceNode(<evt>)]}');
  }

  var src = evt.srcElement ? evt.srcElement : (evt.currentTarget ? evt.currentTarget : null);

  if(!src)
  {
    throw new Error('#{CouldNotGetSourceNode_[web.getSourceNode("' + evt + '")]}');
  }

  return src;
};

////////////////////////////////////////////////////////////////////////////////
web.getCookieExpirationDate = function(days, hours, minutes)
{
  var expDate = new Date();

  expDate.setDate(expDate.getDate() + parseInt(days));
  expDate.setHours(expDate.getHours() + parseInt(hours));
  expDate.setMinutes(expDate.getMinutes() + parseInt(minutes));

  return expDate.toGMTString();
};

////////////////////////////////////////////////////////////////////////////////
web.getCookieValue = function(offset)
{
  var endStr = document.cookie.indexOf(';', offset);

  if(endStr == -1)
  {
    endStr = document.cookie.length;
  }

  return unescape(document.cookie.substring(offset, endStr));
};

////////////////////////////////////////////////////////////////////////////////
web.getCookie = function(name)
{
  var arg  = name + '=';
  var aLen = arg.length;
  var cLen = document.cookie.length;
  var i    = 0;

  while(i < cLen)
  {
    var j = i + aLen;

    if(document.cookie.substring(i, j) == arg)
    {
      return web.getCookieValue(j);
    }

    i = document.cookie.indexOf(' ', i) + 1;

    if (i == 0)
    {
      break;
    }
  }

  return null;
};

////////////////////////////////////////////////////////////////////////////////
web.setCookie = function(name, value, expires, path, domain, secure)
{
  document.cookie = name + '=' + escape(value) +
    ((expires) ? '; expires=' + expires : '') +
    ((path)    ? '; path='    + path    : '') +
    ((domain)  ? '; domain='  + domain  : '') +
    ((secure)  ? '; secure'             : '');
};

////////////////////////////////////////////////////////////////////////////////
web.deleteCookie = function(name, path, domain)
{
  if(web.getCookie(name))
  {
    document.cookie = name + '=' +
      ((path)   ? '; path='   + path   : '') +
      ((domain) ? '; domain=' + domain : '') +
      '; expires=Thu, 01-Jan-70 00:00:01 GMT';
  }
};

////////////////////////////////////////////////////////////////////////////////
web.createNode = function(type, attr, style)
{
  var node = document.createElement(type);

  for(var i in attr)
  {
    node.setAttribute(i, attr[i]);
  }

  for(var i in style)
  {
    node.style[i] = style[i];
  }

  return node;
};

////////////////////////////////////////////////////////////////////////////
web.truncateSelect = function(node, text, value, disable)
{
  var len = 0;

  if(node.options && node.childNodes && node.childNodes.length)
  {
    len = node.childNodes.length;
  }

  for(var i = 0; i < len; i++)
  {
    if(node.childNodes.item(0) && node.childNodes.item(0).parentNode)
    {
      node.childNodes.item(0).parentNode.removeChild(node.childNodes.item(0));
    }
  }

  node.length        = 0;
  node.options[0]    = new Option(text, value);
  node.selectedIndex = 0;

  if(disable)
  {
    node.disabled = true;
  }
}

////////////////////////////////////////////////////////////////////////////
web.getMouseOffset = function(target, ev)
{
  ev = ev || window.event;

  var docPos   = web.getPosition(target);
  var mousePos = web.mouseCoords(ev);

  return {x : mousePos.x - docPos.x,
          y : mousePos.y - docPos.y};
};

////////////////////////////////////////////////////////////////////////////
web.mouseCoords = function(ev)
{
  var s = getScroll();

  if(ev && (ev.pageX || ev.pageY))
  {
    return {x : ev.pageX,
            y : ev.pageY};
  }

  ev = window.event;

  return {x : ev.clientX - document.body.clientLeft + s.x,
          y : ev.clientY - document.body.clientTop  + s.y};
};

////////////////////////////////////////////////////////////////////////////
web.getPosition = function(element)
{
  var left = 0;
  var top  = 0;

  while(element.offsetParent)
  {
    left += element.offsetLeft + (element.currentStyle ? (parseInt(element.currentStyle.borderLeftWidth)).NaN0() : 0);
    top  += element.offsetTop  + (element.currentStyle ? (parseInt(element.currentStyle.borderTopWidth)).NaN0()  : 0);

    element = element.offsetParent;
  }

  left += element.offsetLeft + (element.currentStyle ? (parseInt(element.currentStyle.borderLeftWidth)).NaN0() : 0);
  top  += element.offsetTop  + (element.currentStyle ? (parseInt(element.currentStyle.borderTopWidth)).NaN0()  : 0);

  return {x : left,
          y : top};
};

////////////////////////////////////////////////////////////////////////////
web.screenSize = function()
{
  var w = (window.innerWidth  ? window.innerWidth  : (document.documentElement.clientWidth  ? document.documentElement.clientWidth  : document.body.offsetWidth));
  var h = (window.innerHeight ? window.innerHeight : (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.offsetHeight));

  return {w : w,
          h : h};
};

////////////////////////////////////////////////////////////////////////////
web.defScroll = function()
{
  var x = (window.scrollX) ? window.scrollX : document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft;
  var y = (window.scrollY) ? window.scrollY : document.documentElement.scrollTop  ? document.documentElement.scrollTop  : document.body.scrollTop;

  return {x : x,
          y : y};
}

////////////////////////////////////////////////////////////////////////////
web.addOnloadHandler = function(func)
{
  if(!arguments.callee.handlers)
  {
    arguments.callee.handlers = [];
  }

  arguments.callee.handlers[arguments.callee.handlers.length] = func;
}

web.addOnloadHandler.onLoaded = function ()
{
  if(web.addOnloadHandler.handlers.length)
  {
    (web.addOnloadHandler.handlers.pop())();

    window.setTimeout(arguments.callee, 1);
  }
}

web.addOnloadHandler.loaded = (function()
{
  var u  = navigator.userAgent.toLowerCase();
  var ie = /*@cc_on!@*/false;
  var i  = function()
  {
    if(web.addOnloadHandler.handlers)
    {
      web.addOnloadHandler.handlers.reverse();
      web.addOnloadHandler.onLoaded();
    }
  };

  if(/webkit/.test(u))
  {
    var timeout = setTimeout(function()
    {
      if(document.readyState == "loaded" || document.readyState == "complete")
      {
        window.clearTimeout(timeout);
        i();
      }

      else
      {
        timeout = window.setTimeout(arguments.callee,10);
      }
    }, 10);
  }

  else if((/mozilla/.test(u) && !/(compatible)/.test(u)) || (/opera/.test(u)))
  {
    document.addEventListener("DOMContentLoaded", i,false);
  }

  else if(ie)
  {
    document.write('<script id="__ie_onload" defer src=javascript:void(0)><\/script>');

    var script = document.getElementById('__ie_onload');

    script.onreadystatechange = function()
    {
      if(this.readyState == "complete")
      {
        i();
      }
    };
  }

  else
  {
    window.onload = i;
  }

  return true;

})();

