text: /*
   * Copyright (C) 2014 SDN Hub
   *
   * Licensed under the GNU GENERAL PUBLIC LICENSE, Version 3.
   * You may not use this file except in compliance with this License.
   * You may obtain a copy of the License at
   *
   *    http://www.gnu.org/licenses/gpl-3.0.txt
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
   * implied.
   */
  
  var switchList = {};
  var hostList = {};
  var hostSwitchLinkList = [];
  
  var url = "http://" + location.hostname + ":8080";
  var graph = new joint.dia.Graph;
  var erd = joint.shapes.erd;
  
  var element = function(elm, x, y, label) {
      var cell = new elm({ position: { x: x, y: y }, size: { width: 150, height: 30 },
  	      attrs: { text: { text: label }}});
  	
  	cell.attr({
  		  rect: { fill: '#2C3E50', rx: 5, ry: 5, 'stroke-width': 2, stroke: 'black' },
  	      text: {
  	          fill: 'white',
  	          'font-size': 16, 'font-weight': 'bold', 'font-variant': 'small-caps', 'text-transform': 'capitalize'
  	      }
  	  });
  	
      graph.addCell(cell);
      return cell;
  };
  
  var link = function(elm1, elm2) {
      var cell = new erd.Line({ source: { id: elm1.id }, target: { id: elm2.id }, 
          attrs : { '.connection': { stroke: 'blue' } },
          labels: [{ text: {'font-size': 10 } },
                   { text: {'font-size': 10 } }]
      });
  
      graph.addCell(cell);
      return cell;
  };
  
  var getSwitchDesc = function(dpid) {
      var ofctl_dpid = parseInt(dpid, 16);
      $.getJSON(url.concat("/stats/desc/").concat(ofctl_dpid), function(descs){
  	    $.each(descs, function(key, value){
              var valueJson = JSON.stringify(value);
              var switchDesc = JSON.parse(valueJson);
              switchList[dpid]['desc'] = switchDesc;
          });
      }).then(setSwitchTooltip);
  };
  
  var getDom = function(modelId) {
      var elems = document.getElementsByClassName("element");
      for (i=0;i < elems.length; i++) {
          dom = document.getElementById(elems[i].id);
          if (modelId == dom.getAttribute("model-id"))
              return dom;
      }
      return undefined;
  };
  
  var setSwitchTooltip = function() {
      $.each(switchList, function(dpid, value) {
          var rectDom = getDom(value.element.id);
          if (rectDom != undefined && value.desc != undefined) {
              value['tooltip'] = new joint.ui.Tooltip({
                      target: rectDom,
                      content: '<span>Switch ' + value['name'] + '</span>' + 
                               '<hr><table>' +
                               '<tr><td>H/w type:</td><td>' + value.desc.hw_desc + '</td></tr>' +
                               '<tr><td>S/w version:</td><td>' + value.desc.sw_desc + '</td></tr>' +
                               '<tr><td>Vendor:</td><td>' + value.desc.mfr_desc + '</td></tr>' +
                               '<tr><td>Serial #:</td><td>' + value.desc.serial_num + '</td></tr>' +
                               '<tr><td>Description:</td><td>' + value.desc.dp_desc + '</td></tr>' +
                               '</table>',
                      top: rectDom,
                      direction: 'top'
              });
          }
      });
  };
  
  var hostCleanup = function(currentHosts) {
      $.each(hostList, function(key, value){
          value.tooltip.remove();
          value.link.remove();
          if (!(key in currentHosts))
              value.element.remove();
      });
  };
  
  var drawHosts = function() {
  	srcSwitch = {}; 
  	dstSwitch = {};
  
  	$.getJSON(url.concat("/v1.0/hosts"), function(hosts){
          //Remove old tooltips and host links
          hostCleanup(hosts);
  
  	    $.each(hosts, function(key, value){
              //Do all common stuff for an IP
              if (!(key in hostList)) 
                  hostList[key] = {};
  
              if (!('element' in hostList[key])) {
                  var x = 1000, y=1000;
                  var cell = new erd.Normal({ position: { x: x, y: y }, attrs: { text: { text: key }}});
                  graph.addCell(cell);
  
                  hostList[key]['element'] = cell;
                  hostList[key]['dom'] = getDom(cell.id);
              }
  
              hostList[key]['entry'] = value;
              var hostDom = hostList[key]['dom'];
              var cell = hostList[key]['element'];
  
              if (value.dpid in switchList && hostDom != undefined) {
                  var date = new Date(value.timestamp * 1000);
                  var dateStr = (date.getMonth() + 1) + "/" +
                                 date.getDate() + "/" +
                                 date.getFullYear() + " " +
                                 date.getHours() + ":" +
                                 date.getMinutes() + ":" +
                                 date.getSeconds();
  
                  hostList[key]['tooltip'] = new joint.ui.Tooltip({
                          target: hostDom,
                          content: '<table>' +
                                   '<tr><td>IP:</td><td>' + key + '</td></tr>' +
                                   '<tr><td>MAC:</td><td>' + value.mac + '</td></tr>' +
                                   '<tr><td>Assoc switch:</td><td>' + value.dpid + '</td></tr>' +
                                   '<tr><td>Assoc port:</td><td>' + value.port + '</td></tr>' +
                                   '<tr><td>Time seen:</td><td>' + dateStr + '</td></tr>' +
                                   '</table>',
                          top: hostDom,
                          direction: 'top'
                  });
      
                  hostList[key]['link'] =link(switchList[value.dpid]['element'], cell);
              }
  		});
          joint.layout.DirectedGraph.layout(graph, { setLinkVertices: false, edgeSep: 20, rankSep: 80, nodeSep: 50 });
  	});
  };
  
  var drawLinks = function() {
  	srcSwitch = {}; 
  	dstSwitch = {};
  	$.getJSON(url.concat("/v1.0/topology/links"), function(links){
  	    $.each(links, function(key, value){
              var valueJson = JSON.stringify(value);
              var obj = JSON.parse(valueJson);
  
              var portname = obj.src.name;
              link(switchList[obj.src.dpid]['element'],
                   switchList[obj.dst.dpid]['element']).cardinality(portname);
  		});
          joint.layout.DirectedGraph.layout(graph, { setLinkVertices: false, edgeSep: 20, rankSep: 80, nodeSep: 80 });
  	}).then(drawHosts);
  }
  
  $(function()  {
      var paperScroller = new joint.ui.PaperScroller;
  
      var paper = new joint.dia.Paper({
              el: paperScroller.el,
              width: 2400,
              height: 800,
              model: graph
      });
  
      paperScroller.options.paper = paper;
      $('#paper-container').append(paperScroller.render().el);
      paper.on('blank:pointerdown', paperScroller.startPanning);
  
  $.getJSON(url.concat("/v1.0/topology/switches"), function(switches){
  	var counter = 0;
      $.each(switches, function(index, value){
  		var valueJson = JSON.stringify(value);
          var obj = JSON.parse(valueJson);
  
          switchList[obj.dpid] = {}
  
          var switchName = obj.dpid; 
          switchList[obj.dpid]['name'] = switchName;
  
          var x = 200 + 150 * (index % 4);
          var y = 100 + 150 * Math.floor(index/4);
  		switchList[obj.dpid]['element'] = element(joint.shapes.basic.Rect, x, y, switchName);
  
          getSwitchDesc(obj.dpid);
  
      });	
  }).then(drawLinks);
  
  paper.on('cell:pointerdown', 
      function(cellView, evt, x, y) { 
          $.each(switchList, function(key, value) {
            if (value.id == cellView.model.id) {
              console.log("Clicked " + key);
            }
          });
  });
  
  var drawHostIntervalD = setInterval(function(){drawHosts()}, 10000);
  
  });
  /*
  graph.on('change:position', function(cell) {
      var parentId = cell.get('parent');
      if (!parentId) return;
  
      var parent = graph.getCell(parentId);
      var parentBbox = parent.getBBox();
      var cellBbox = cell.getBBox();
  
      if (parentBbox.containsPoint(cellBbox.origin()) &&
          parentBbox.containsPoint(cellBbox.topRight()) &&
          parentBbox.containsPoint(cellBbox.corner()) &&
          parentBbox.containsPoint(cellBbox.bottomLeft())) {
  
          // All the four corners of the child are inside
          // the parent area.
          return;
      }
  
      // Revert the child position.
      cell.set('position', cell.previous('position'));
  });*/
  