  
/**
 * The Util class offers general utility methods that might
 * be useful in a wide variety of applications.
 *
 * There is no need to ever call this constructor.  All the Util
 * methods are class methods, not instance methods, and the only 
 * reason this constructor exists is to cause the name "Util"
 * to be a globally-scoped class name, which the class methods 
 * can then be attached to.
 *
 * @scope    public instance constructor
 * @syntax   DO NOT CALL THIS CONSTRUCTOR
 */
function Util() {
  throw new Error("Util is a static class. You can't create instances of it.");
}

/**
 * Given an HTMLElement, return the HTMLDocument it belongs to
 */
Util.getEltDoc = function(anElt) {
  if (anElt.ownerDocument) {return anElt.ownerDocument;}
  if (anElt.document) {return anElt.document;}
  return document;
};

/**
 * This method calls document.createElement() to create a new element, and 
 * then initialized the new element with the values provided by the caller.
 *
 * @scope    public class method
 * @param    tagName    The HTML tag for the element ("div", "p", "span", etc.). 
 * @param    cssClassName    Optional. The HTML/CSS class to assign to the new element. 
 * @param    attributesInJson    Optional. A JSON object with additional attributes to set on the new element. 
 * @param    text    Optional. A text string to put in a text node within the new element. 
 * @return   The newly created HTML element.
 */
Util.newElement = function(tagName, cssClassName, attributesInJson, text, style, doc) {

  //if (!doc) {doc = document;}
  var newElement = doc.createElement(tagName);
  if (cssClassName) {
    newElement.className = cssClassName;
  }
  if (attributesInJson) {
    for (var key in attributesInJson) {
      if (key == 'id') {
        newElement.id = attributesInJson[key];
      } else {
        if (key == 'jfor') {
          newElement.setAttribute('for', attributesInJson[key]);
        }
        else {
          newElement.setAttribute(key, attributesInJson[key]);
        }
      }
    }
  }
  if (style) {
      for (key in style) {
        if (key == 'cssFloat' && Util.isIE()) {
          newElement.style['styleFloat'] = style[key];
        }
        else {
          newElement.style[key] = style[key];
        }
      }
  }    
  if (text) {
    try {
      newElement.appendChild(doc.createTextNode(text));
    } catch (e) {
      newElement.text = text;
    }
  }
  return newElement;
};

/**
 * Given an HTML element, we first call document.createElement() to 
 * create a new element, and then call appendChild() to add the new 
 * element to the given element.
 *
 * Example:
 * <pre>
 * var menuUrl = "http://en.wikipedia.org/";
 * var menuText = "Wikipedia";
 * var menuItem = Util.appendNewElement(mainMenu, "li", NavbarView.CSS_CLASS_MENU_ITEM);
 * var link = Util.appendNewElement(menuItem, "a", null, {href: menuUrl}, menuText);
 * </pre>
 *
 * @scope    public class method
 * @param    parentElement    The existing element that we should append the new element to. 
 * @param    tagName    The HTML tag for the element ("div", "p", "span", etc.). 
 * @param    cssClassName    Optional. The HTML/CSS class to assign to the new element. 
 * @param    attributesInJson    Optional. A JSON object with additional attributes to set on the new element. 
 * @param    text    Optional. A text string to put in a text node within the new element. 
 * @return   The newly created HTML element.
 */
Util.appendNewElement = function(parentElement, tagName, cssClassName, attributesInJson, text,style) {
  // IE does not like it
  //Util.assert(parentElement instanceof HTMLElement);
  var doc = Util.getEltDoc(parentElement);
  var newElement = Util.newElement(tagName, cssClassName, attributesInJson, text,style,doc);
  parentElement.appendChild(newElement);
  return newElement;
};

/**
 * Given an HTML element, we first call document.createTextNode() to 
 * create a new text node, and then call appendChild() to add the new 
 * text node to the given element.
 *
 * @scope    public class method
 * @param    parentElement    The existing element that we should append the new element to. 
 * @param    textString    The text string to put in the text node.
 * @return   The newly created text node.
 */
Util.appendNewTextNode = function(parentElement, textString) {
   // doesn't work on IE
  //Util.assert(parentElement instanceof HTMLElement);

  var doc = Util.getEltDoc(parentElement);
  var newTextNode = doc.createTextNode(textString);
  parentElement.appendChild(newTextNode);
  return newTextNode;
};

Util.now = function() {
  return (new Date()).getTime();
};

Util.relativeTime = function(origTime) {
  var diff = (Util.now() - origTime.getTime())/1000;
  if (diff > (86400*8)) {
    return origTime.toDateString();
  }
  else if (diff >= (6*86400 + 86400/2)) {
    return 'a week ago';
  }
  else if (diff >= (23*3600 + 3600/2)) {
    return Util.pluralize(Math.round(diff/86400),'day') + ' ago';
  }
  else if (diff >= (59*60 + 60/2)) {
    return Util.pluralize(Math.round(diff/3600),'hour') + ' ago';
  }
  else if (diff >= 30) {
    return Util.pluralize(Math.round(diff/60),'minute') + ' ago';
  }
  return 'mere moments ago';
};

Util.pluralize = function(num, singular, plural) {
  if (!plural) {plural = singular + 's';}
  return num + ' ' + (num == 1 ? singular : plural);
};

Util.unbold = function(str) {
  return  str.gsub(/<\/?b>/,'');
};

Util.isSafari = function () {
  return (/Konqueror|Safari|KHTML/).test(navigator.userAgent);
};

function reportTrackingEvent(trackingStr) {
  if (window.urchinTracker) { urchinTracker(trackingStr); }
  return false;
}

function doOnLoadStuff() {
  if ($('search')) {$('search').getElementsByTagName('input')[0].focus();}
}

function setQuery(query) {
  google_page_url = "http://216.182.236.208/q/" + encodeURIComponent(query);
}

Event.observe(window, 'load', doOnLoadStuff, false);

