/*
 *   output object
 */

function outputLine(id, name, value, highlight, view, clickAction, clickData1, clickData2, clickObject, clickObjectData) {
  this.id = id;
  this.name = name;
  this.value = value;
  this.highlight = highlight;
  this.view = view;
  this.clickAction = clickAction;
  this.clickData1 = clickData1;
  this.clickData2 = clickData2;
  this.clickObject = clickObject;
  this.clickObjectData = clickObjectData;
}

function outputObject() {
  this.lines = new Array();
  this.linesByID = new Array();
  this.linesByName = new Array();
  this.outputNames = new Array();
  this.viewFilters = new Array();
  this.lenghth = 0;
  this.order = 'native';
  this._init = oo_init;
  this.buildOutput = oo_buildOutput;
  this.printOutput = oo_printOutput;
  this.sortOutput = oo_sortOutput;
  this.clear = oo_clear;
}

function oo_init() {
  this.viewFilters['CSS'] = '';
  this.viewFilters['DOM'] = '';
  this.viewFilters['view'] = '';
}

function oo_buildOutput(forWhat, forObject) {
  this.clear();
  getProcessingFilters(this);
  var forNode = eval(forWhat+".nodeType");
  forNode = String(forNode);
  forNode = (forNode != 'undefined') ? parseInt(forNode) : 0;
  try {
    eval("for (var i in " + forWhat + ") { buildOutputLine(this, forWhat, i, forObject, forNode); };");
  }
  catch (ex) {
    alert('Exception in oo_buildOutput():   '+ex+'   (in '+forWhat+'.'+i+')');
  }
  this.lines = this.linesByID;
  sortLinesByName(this);
}
function buildOutputLine(inObject, forWhat, i, forObject, forNode) {
  try {
    var tmp = eval(forWhat+"."+i);
  }
  catch (ex) {
    // if tested file is from another domain this should not be even call
    alert('Exception in buildOutputLine():   '+ex+'   (in '+forWhat+'.'+i+')');
  }
  finally {
    // default values
    var isObject = false;
    var isFunction = false;
    var isEmpty = false;
    var isNonEmpty = false;
    var isUndefined = false;
    // view & highlight
    var highlightDOM = inObject.viewFilters['DOM'];
    var highlightCSS = inObject.viewFilters['CSS'];
    var highlightThis = 'highlightDefault';
    var viewCase = inObject.viewFilters['view'];
    var viewThis = 'viewNo';
    var clickAction = '';
    var clickData1 = '';
    var clickData2 = '';
    var clickObject = false;
    var clickObjectData = '';
    // flags
    var str = String(tmp);
    isEmpty = (str == '');
    isUndefined = (str == 'undefined');
    isObject = (str.indexOf('[') == 0);
    isFunction = (str.indexOf('function') == 1);
    isNonEmpty = !isEmpty && !isUndefined && !isObject && !isFunction;
    // make decision about view
    switch (viewCase) {
      case 'all':
        viewThis = 'viewYes';
        if (isObject) {
          clickObject = true;
          clickObjectData = i;
        }
        break;
      case 'nonempty':
        if (isNonEmpty) { viewThis = 'viewYes'; }
        break;
      case 'empty':
        if (isEmpty) { viewThis = 'viewYes'; }
        break;
      case 'undefined':
        if (isUndefined) { viewThis = 'viewYes'; }
        break;
      case 'null':
        if (isNull) { viewThis = 'viewYes'; }
        break;
      case 'objects':
        if (isObject) {
          viewThis = 'viewYes';
          clickObject = true;
          clickObjectData = i;
        }
        break;
      case 'functions':
        if (isFunction) { viewThis = 'viewYes'; }
        break;
    }
    // make decision about CSS highlighting
    if (forObject == 'style') {
      var isIn = false;
      switch (highlightCSS) {
        case '1':	// CSS1
          var k = -1;
          for (var j=0; j<CSS1.length; j++) { if (CSS1[j] == i) { isIn = true; k = j; break; } }
          //for (var j=0; j<CSS1.length; j++) { if (CSS1[j] == i) { isIn = true; break; } }
          if (isIn) {
            highlightThis = 'highlightCSS';
            clickAction = 'openCSS1';
            clickData1 = k;
          }
          break;
        case '2':	// CSS2
          var k = -1;
          for (var j=0; j<CSS2.length; j++) { if (CSS2[j] == i) { isIn = true; k = j; break; } }
          //for (var j=0; j<CSS2.length; j++) { if (CSS2[j] == i) { isIn = true; break; } }
          if (isIn) {
            highlightThis = 'highlightCSS';
            clickAction = 'openCSS2';
            clickData1 = k;
          }
          break;
        case '3':	// CSS3
          break;
      }
    }
    // make decision about DOM highlighting
    if  (forNode != 0) {
      var isIn = false;
      switch (highlightDOM) {
        case '1':	// DOM1_core
          for (var j=0; j<DOM1_core[forNode].length; j++) { if (DOM1_core[forNode][j] == i) { isIn = true; break; } }
          if (isIn) {
            highlightThis = 'highlightDOM';
            clickAction = 'openDOM1';
            clickData1 = i;
            clickData2 = forNode;
          }
          break;
        case '1+':	// DOM1_html
          break;
        case '2':	// DOM2
          break;
        case '3':	// DOM3
          break;
      }
    }
    // finish
    inObject.linesByID[inObject.length] = new outputLine(inObject.length, i, tmp, highlightThis, viewThis, clickAction, clickData1, clickData2, clickObject, clickObjectData);
    inObject.outputNames[inObject.length] = i;
    ++inObject.length;
  }
}
function sortLinesByName(inObject) {
  inObject.outputNames.sort();
  var tmpArray = new Array();
  for (var i=0; i<inObject.length; i++) {
    for (var j=0; j<inObject.length; j++) {
      if (inObject.linesByID[j].name == inObject.outputNames[i]) {
        var tmp = inObject.outputNames[i]+'_';		// Mozilla's hack (can't named piece of Array by string 'length')
        tmpArray[tmp] = inObject.linesByID[j];
        break;
      }
    }
  }
  inObject.linesByName = tmpArray;
}
function getProcessingFilters(inObject) {
  var filterDOM = document.OL_controls.DOM;
  var filterCSS = document.OL_controls.CSS;
  var filterView = document.OL_controls.filter;
  for (var i=0; i<filterDOM.length; i++) {
    if (filterDOM[i].checked == true) { inObject.viewFilters['DOM'] = filterDOM[i].value; break; }
  }
  for (var i=0; i<filterCSS.length; i++) {
    if (filterCSS[i].checked == true) { inObject.viewFilters['CSS'] = filterCSS[i].value; break; }
  }
  for (var i=0; i<filterView.length; i++) {
    if (filterView[i].checked == true) { inObject.viewFilters['view'] = filterView[i].value; break; }
  }
}

function oo_printOutput() {
  var str = '';
  //for (var i=0; i<output.length; i++) {
  for (var i in output.lines) {
    var tmp = output.lines[i];
    var str1 = '';
    var str2 = '';
    if (tmp.clickObject == true) {
      str2 = '<a class="output" href="javascript: outputClick(\'addObject\', \''+tmp.clickObjectData+'\');">'+tmp.value+'</a>';
    } else {
      str2 = tmp.value;
    }
    if (tmp.clickAction != '') {
      str1 = '<a class="output" href="javascript: outputClick(\''+tmp.clickAction+'\', \''+tmp.clickData1+'\', \''+tmp.clickData2+'\');">'+tmp.name+'</a>';
    } else {
      str1 = tmp.name;
    }
    str += '<div class="'+tmp.view+'"><span class="property '+tmp.highlight+'">'+str1+'</span> = '+str2+'</div>\n';
    /* Hover is better! :( */
  }
  //alert(str);
  document.getElementById('order').innerHTML = this.order;
  document.getElementById('output').innerHTML = str;
}

function oo_sortOutput() {
  if (this.order == 'native') {
    this.lines = this.linesByName;
    this.order = 'alphabet';
  } else {
    this.lines = this.linesByID;
    this.order = 'native';
  }
  this.printOutput();
}

function oo_clear() {
  this.lines = new Array();
  this.linesByID = new Array();
  this.linesByName = new Array();
  this.outputNames = new Array();
  this.length = 0;
  this.order = 'native';
  this._init();			// clear processing filters
}



/*
 *   main part
 */

var output = new outputObject();
output._init();


