var utils = {
  element: {
    // function to return element position in document content taken from
    // http://www.quirksmode.org/js/findpos.html
    position: function(obj) {
      var curleft = curtop = 0;
      
      if (obj.offsetParent) {
        do {
          curleft += obj.offsetLeft;
          curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
      }
      
      return {
        "left": curleft,
        "top":  curtop
      };
    },
    dimensions: function(obj) {
      return {
        width: obj.offsetWidth,
        height: obj.offsetHeight
      }
    },
    nextSibling: function(obj, num) {
      var sib = obj;
      while(num > 0) {
        sib = sib.nextSibling;
        if(sib === null) break;
        if(sib.nodeType === 1) num--;
      }
      return sib;
    },
    previousSibling: function(obj, num) {
      var sib = obj;
      while(num > 0) {
        sib = sib.previousSibling;
        if(sib === null) break;
        if(sib.nodeType === 1) num--;
      }
      return sib;
    },
    firstChild: function(obj) {
      var children = obj.childNodes;
      var firstElement = null;
      for(var i = 0, len = children.length; i < len; i++) {
        if(children[i].nodeType === 1) {
          firstElement = children[i];
          break;
        }
      }
      return firstElement;
    },
    lastChild: function(obj) {
      var children = obj.childNodes;
      var lastElement = null;
      for(var i = children.length-1; i > 0; i--) {
        if(children[i].nodeType === 1) {
          lastElement = children[i];
          break;
        }
      }
      return lastElement;
    }
  },
  
  window: {
    // size and scroll code
    // from http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
    size: function() {
      var myWidth = 0, myHeight = 0;
      
      if(typeof(window.innerWidth) == 'number') {
        //Non-IE
        myWidth = window.innerWidth;
        myHeight = window.innerHeight;
      }
      else if(document.documentElement &&
             (document.documentElement.clientWidth || document.documentElement.clientHeight)) {
        //IE 6+ in 'standards compliant mode'
        myWidth = document.documentElement.clientWidth;
        myHeight = document.documentElement.clientHeight;
      }
      else if(document.body && (document.body.clientWidth || document.body.clientHeight)) {
        //IE 4 compatible
        myWidth = document.body.clientWidth;
        myHeight = document.body.clientHeight;
      }
      
      return {
        "width":  myWidth,
        "height": myHeight
      };
    },
    
    scroll: function() {
      var scrOfX = 0, scrOfY = 0;
      
      if(typeof(window.pageYOffset) == 'number') {
        //Netscape compliant
        scrOfY = window.pageYOffset;
        scrOfX = window.pageXOffset;
      }
      else if(document.body && (document.body.scrollLeft || document.body.scrollTop)) {
        //DOM compliant
        scrOfY = document.body.scrollTop;
        scrOfX = document.body.scrollLeft;
      }
      else if(document.documentElement &&
             (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
        //IE6 standards compliant mode
        scrOfY = document.documentElement.scrollTop;
        scrOfX = document.documentElement.scrollLeft;
      }
      
      return {
        "left": scrOfX,
        "top":  scrOfY
      };
    }
  }
}