
var currentTM = null;

// Treemap options
var tmOptions = {
  rootId: "infovis",
  addLeftClickHandler: true,
  addRightClickHandler: true,

  Color: {
    allow: true,
    minValue: 0,      // These should be adjusted
    maxValue: 100,    // ---
    minColorValue: [65, 178, 27], // min will be "fast", so use a "fast" color
    maxColorValue: [89, 2, 2] // "slow"
  },

  Tips: {
    allow: true,
    onShow: function(tip, node, isLeaf, domElement) {
      var html = "<b>" + node.name + "</b>";
      html += "<br>data: " + node.data["$area"];
      if (node.data.lineno)
        html += "<br>line #: " + node.data.lineno;
      tip.innerHTML = html;
    }
  }
};


/* TreeNode */
function TreeNode(aName, aData, aChildren) {
  // generate && assign uuid for unique id purposes
  this.id = uuidService.generateUUID().toString();
  this.name = aName;
  this.data = aData || { "$area": 0 };
  this.children = aChildren || [];
}
TreeNode.prototype = {
  id: "",
  name: "",
  children: [],
  data: {},
  addChild: function(node) {
    this.children.push(node);
  },
  normalize: function() {
    // make sure that data[0].value != 0
    // recursively call normalize if it is
    // add data[0].value to each
    // make sure we have data[1]
    this.data["$color"] = this.data["$area"];
    if (!this.children.length)
      return;
    this.data["$area"] = this.children.reduce(function(prev, cur) {
      cur.normalize();
      return prev + cur.data["$area"];
    }, 0);
    if (isNaN(this.data["$area"])) {
      throw "NaN!";
    }
  }
}




/* DOMy EVENTS */
function onLoadFileClick() {
  var file = chooseFile();
  if (file) {
    // reset
    dtraceParseHandler.data = [];
    if (currentTM) currentTM.empty();
    document.getElementById("fileMenu").style.display = "none";

    parseDTraceLog(file, dtraceParseHandler);
    dtraceParseHandler.data.forEach(function(d) { d.normalize(); } );
    
  }
}

function populateViewMenu(aData) {
  var s = document.getElementById("viewMenu");
  while (s.options.length > 1)
    s.remove(1);
  s.style.display = "block";
  dtraceParseHandler.data.forEach(function(aData) {
    s.options[s.options.length] = new Option(aData.name, aData.id);
  });
}

function onViewMenuSelect(aSelect) {
  if (currentTM) currentTM.empty();
  document.getElementById("fileMenu").style.display = "none";
  var id = aSelect.options[aSelect.selectedIndex].value;
  dtraceParseHandler.data.every(function(aData) {
    if (aData.id == id) {
      tmOptions.Color.maxValue = dtraceParseHandler.largestSizes[id];
      var tm = new TM.Squarified(tmOptions);
      tm.loadJSON(aData);
      // update the files view
      populateFileMenu(aData);
      currentTM = tm;
      return false;
    }
    return true;
  });
}

function populateFileMenu(aData) {
  var s = document.getElementById("fileMenu");
  while (s.options.length > 1)
    s.remove(1);
  s.style.display = "block";
  var nodes = aData.children.sort(function(a, b) { return compareStrings(a.name, b.name); });
  nodes.forEach(function(aNode) {
    s.options[s.options.length] = new Option(aNode.name, aNode.id);
  });
}

function onFileMenuSelect(aSelect) {
  var id = aSelect.options[aSelect.selectedIndex].value;
  id == "reset" ? currentTM.out() : currentTM.loadTree(id);
}


function compareStrings(a, b) {
  a = a.toLowerCase();
  b = b.toLowerCase();
  if (a < b) return -1;
  else if (a > b) return 1;
  return 0;
}
