if (!window.console) {
  var consoleFuncs =
    [ "debug", "info", "warn", "error", "assert",
      "assertEquals", "assertNotEquals", "assertGreater",
      "assertNotGreater", "assertLess", "assertNotLess",
      "assertContains", "assertNotContains", "assertTrue",
      "assertFalse", "assertNull", "assertNotNull",
      "assertUndefined", "assertNotUndefined", "assertInstanceOf",
      "assertNotInstanceOf", "assertTypeOf", "assertNotTypeOf",
      "trace", "time", "timeEnd", "count" ];
  window.console = {};
  consoleFuncs.each(
    function (name) { window.console[name] = Prototype.emptyFunction; });
}
  
function trace(funcExpr, funcs)
{
  var oldfunc = eval(funcExpr);
  if (oldfunc.__isTraced)
  {
    console.debug("already traced: " + funcExpr);
    return;
  }
  console.debug("tracing: " + funcExpr);
//  var oldfunc = object[name];
  var newfunc = function() {
    var args = $A(arguments);
    var callString = funcExpr + "(" + args.map(Object.inspect).join(', ') + ")";
    console.debug("enter: " + callString);
    try {
      var result = oldfunc.apply(this, args);
    } catch (e) {
      console.debug("failed: " + callString);
      throw e;
    }
    console.debug("leave: " + callString);
    return result;
  };
  newfunc.__isTraced = true;
  eval(funcExpr + " = newfunc;");
}

function traceObject(objExpr, funcs)
{
  var object = eval(objExpr);
  var toTrace = new Array();
  if (funcs)
    toTrace = funcs;
  else {
    for (name in object)
    {
      if (object[name] instanceof Function)
        toTrace.push(name);
    }
  }
  
  if (toTrace.length > 0)
  {
    toTrace.each(function (name) {
      trace(objExpr + "." + name); // FIXME: escaping?
    });
  }
  else
    console.debug("nothing to trace!");
}

var Utils = {};

Utils.assert = function(val, text)
{
   if (!val) {
      console.error("*** ASSERTION FAILED: " + text);
      throw new Error("ASSERTION FAILED", text);
   }
}

Utils.createElement = function(tagName)
{
//   var parent = arguments[1];
   var className = arguments[1];
   var text = arguments[2];
   var element = document.createElement(tagName);
   if (className)
      element.className = className;
   if (text) {
      var textNode = document.createTextNode(text);
      element.appendChild(textNode);
   }
//   if (parent)
//      parent.appendChild(element);
   return element;
}

Utils.getChildren = function(element)
{
   var result = [];
   element = $(element);
   for (var child = element.firstChild; child; child = child.nextSibling)
   {
      if (child.nodeType == 1)
	 result.push(child);
   }
   return result;
}

Utils.cloneObject = function(element)
{
  element = $(element);
  var cloned = element.cloneNode(true);
  cloned.id = "";
  return cloned;
}

Utils.wrapHandler = function(func)
{
  return function (e) {
    func();
    Event.stop(e);
  };
}

Utils.fixCheckBox = function(checkbox)
{
  if (document.all)
    checkbox.checked = !checkbox.checked;
}

Utils.getModelName = function (OID)
{
  return OID.split(/:/)[0];
}

Utils.getId = function (OID)
{
  return parseInt(OID.split(/:/)[1]);
}

Utils.deepCopy = function (obj)
{
  if (obj instanceof Array)
    return obj.collect(Utils.deepCopy);
  else if (obj instanceof Object) {
    var result = {};
    for (k in obj)
      result[k] = Utils.deepCopy(obj[k]);
    return result;
  } else
    return obj;
}

Utils.toSource = function (obj)
{
  return (obj && obj.toSource) ? obj.toSource() : Object.inspect(obj);
}

Array.prototype.append = function (otherArray)
{
  var result = new Array(this.length + otherArray.length);
  for (var i = 0; i < this.length; ++i)
    result[i] = this[i];
  for (var i = 0; i < otherArray.length; ++i)
    result[i + this.length] = otherArray[i];

  return result;
}

String.prototype.formatArray = function (args) {
  var n = 0;
  return this.replace(/%[dso]/g, function() { return String(args[n++]); });
};

String.prototype.format = function () {
  return this.formatArray($A(arguments));
}
