
// Based on Core DOM 
function examDOM(obj,depth) {
  if (!obj.nodeType) throw "ERROR: Non-DOM node";
  if (obj.nodeType == 3) //Text Node
    return "Text["+escape(obj.data).replace("%20"," ")+"]";
  if (obj.nodeType == 9) { // Document element
    var res="Document:\n";
    if (document.documentElement) 
      res +=examDOM(document.documentElement,depth);  
    else 
      res += examDOM(document.body,depth);
    return res;
  }
  if (obj.nodeType == 1) { // Normal node;
    var tag=obj.tagName;
    if (depth<=0) return "<"+tag+" ... />";
    
    var res="<"+tag+">\n";
    for(var i=obj.firstChild;i;i=i.nextSibling) {
      res += "  "+examDOM(i,depth-1).split("\n").join("\n  ")+"\n";
    }
    res +="</"+tag+">";
    return res;
  }
  return "Unknown node type";
}

function examDOMUpdate(form) {
  var depth=1;
  form.output.value="examining...";
  if (form.depth) {
      depth=parseInt(form.depth.options[form.depth.selectedIndex].value);
  }
  try {
    form.output.value=examDOM(eval(form.input.value),depth);
  } catch (e) {
    form.output.value=e.toString();
  }
}


function examObj(obj,depth) {
  var res="{\n";
  var attrs=[];
  for (var i in obj) {
    if (i != "_exam_mark")
      attrs.push(i);
  }
  if (attrs.length==0) return "";
  attrs.sort()
  for (var j in attrs) {
    var i=attrs[j];
    res += "  " + i + " : ";
    obj._exam_mark=true; 
    try {
      res += exam(obj[i],depth-1).split("\n").join("\n  ");
    } catch (e) {
      res += "  (object) [no string representation]";
    }
    obj._exam_mark=undefined;
    res += "\n"; 
  }
  res += "};"
  return res;
}

function exam(obj,depth) {
  if (!depth) depth=0;
  var res = "(" + typeof obj + ") ";
  if (typeof obj == "object" && depth>0 && !obj._exam_mark) {
      res += examObj(obj,depth);
  } else if (typeof obj == "string") {
      res += "\"" + obj + "\"";
      if (depth>1) res+=" "+examObj(obj,depth-1);
  } else if (typeof obj == "function" && !depth>0) {
    res += "function () { [code] }";
  } else {
    var objString = ""+obj;
    res += objString.replace(/^\n/,""); // Some function representations
    if (depth>1) {
      res += examObj(obj,depth).split("\n").join("\n  ");
    }
  }
  return res;
}

function examUpdate(form) {
  var depth=1;
  form.output.value="examining...";
  if (form.depth) {
      depth=parseInt(form.depth.options[form.depth.selectedIndex].value);
  }
  try {
    form.output.value=exam(eval(form.input.value),depth);
  } catch (e) {
    form.output.value=e.toString();
  }
}

function evalUpdate(form) {
   form.output.value="evaluating...";
  try {
    form.output.value=eval(form.input.value);
  } catch (e) {
    form.output.value=e.toString();
  }
}


