var labelType, useGradients, nativeTextSupport, animate, counter = 1;

(function() {
  var ua = navigator.userAgent,
      iStuff = ua.match(/iPhone/i) || ua.match(/iPad/i),
      typeOfCanvas = typeof HTMLCanvasElement,
      nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'),
      textSupport = nativeCanvasSupport 
        && (typeof document.createElement('canvas').getContext('2d').fillText == 'function');
  //I'm setting this based on the fact that ExCanvas provides text support for IE
  //and that as of today iPhone/iPad current text support is lame
  labelType = (!nativeCanvasSupport || (textSupport && !iStuff))? 'Native' : 'HTML';
  nativeTextSupport = labelType == 'Native';
  useGradients = nativeCanvasSupport;
  animate = !(iStuff || !nativeCanvasSupport);
})();

$jit.ST.Plot.NodeTypes.implement({
  'line': {
    'render': function(node, canvas) {   
      var width = node.getData('width'),
          height = node.getData('height'),
          pos = this.getAlignedPos(node.pos.getc(true), width, height),
          posX = pos.x + width/2,
          posY = pos.y + height/2;
          if(node._depth == 0)
          {
              posX = 0;
              posY = 0;
              width = 0;
          }
          if(node._depth == 1)
          {
//              if(pos.x > 0)
//              {
//                   posX = pos.x + width;
//              }else{
//                   posX = pos.x;
//              }
              // here ellipse
              var delta = Math.pow(2*Math.abs(pos.y), 3/5);
              delta = Math.ceil(delta);
              if(pos.x > 0)
              {
                   posX = pos.x + width - delta;
              }else{
                   posX = pos.x + delta;
              }
              if((pos.y > -19) && (pos.y < 19) && (pos.x > 0)) // fix canvas bug
              {
                  width = width + 4;
              }
              // end ellipse
          }
          if(node._depth == 2)
          {
//              if(pos.x > 0)
//              {
//                   posX = node.pos.x + width/2;
//              }else{
//                   posX = node.pos.x - width/2;
//              }
             // here ellipse
              delta = Math.pow(2*Math.abs(pos.y), 3/5);
              delta = Math.ceil(delta);
              if(pos.x > 0)
              {
                   posX = pos.x + width - delta;
              }else{
                   posX = pos.x + delta;
              }
              if((pos.x > 0) && (pos.y <= 0)) // fix canvas bug
              {
                  width = width + 3;
              }
              if((pos.x < 0) && (pos.y <= 0)) // fix canvas bug
              {
                 width = width + 3;
              }
           // end ellipse
          }
          node.setData('color', node.data.color);
          this.nodeHelper.rectangle.render('fill', {x: posX, y: posY}, width, 2, canvas);          
    }
  }
});

$jit.ST.Plot.EdgeTypes.implement({
  'mybezier': {
    'render': function(adj, canvas) {

      var orn = this.getOrientation(adj),
             nodeFrom = adj.nodeFrom,
             nodeTo = adj.nodeTo,
             rel = nodeFrom._depth < nodeTo._depth,
             begin = this.viz.geom.getEdge(rel? nodeFrom:nodeTo, 'begin', orn),
             end =  this.viz.geom.getEdge(rel? nodeTo:nodeFrom, 'end', orn),
             dim = adj.getData('dim'),
             ctx = canvas.getCtx();
         if(nodeFrom._depth == 0)
         {
             begin.x = 0;
         }
         if(nodeTo._depth == 1)
         {
             end.x = nodeTo.endPos.x;
             // here ellipse
             var delta = Math.pow(2*Math.abs(end.y), 3/5);
             delta = Math.ceil(delta);
              if(end.x > 0)
              {
                   end.x = end.x - delta;
              }else{
                   end.x = end.x + delta;
              }
              if(end.y > 0) // fix margin canvas bug
              {
                 if(end.x > 0)
                  {
                       end.x = end.x + 2;
                  }else{
                       end.x = end.x - 2;
                  }
              }
              if((end.y > 0) && (end.y <= 19)) // fix margin canvas bug
              {
                 if(end.x > 0)
                  {
                       end.x = end.x + 5;
                  }else{
                       end.x = end.x - 5;
                  }
              }
             // end ellipse
         }
         if(nodeTo._depth == 2)
         {
             if(begin.x > 0)
             {
                begin.x = nodeFrom.endPos.x + nodeFrom.data.$width;
                end.x = end.x + nodeTo.data.$width/2;
             }else{
                begin.x = nodeFrom.endPos.x - nodeFrom.data.$width;
                end.x = end.x - nodeTo.data.$width/2;
             }
             // here ellipse
             delta = Math.pow(2*Math.abs(begin.y), 3/5);
             delta = Math.ceil(delta);
             delta2 = Math.pow(2*Math.abs(end.y), 3/5);
             delta2 = Math.ceil(delta2);
             if(begin.x > 0)
             {
                 begin.x = nodeFrom.endPos.x + nodeFrom.data.$width - delta;
                 end.x = end.x - delta2;
                 if(begin.y < 0)
                 {
                       begin.x = begin.x - 2;
                 }
             }else{
                 begin.x = nodeFrom.endPos.x - nodeFrom.data.$width + delta;
                 end.x = end.x + delta2;
             }
             if((begin.y == 0) && (begin.x > 0)) // fix margin canvas bug
             {
                  begin.x = begin.x - 5;
             }
             if((begin.y < 0) && (begin.x < 0)) // fix margin canvas bug
             {
                  begin.x = begin.x + 2;
             }
             if(end.y > 0) // fix margin canvas bug
             {
                 if(begin.x > 0)
                 {
                       end.x = end.x + 2;
                 }else{
                       end.x = end.x - 2;
                 }
             }
             if((end.y > 0) && (end.y <= 19)) // fix margin canvas bug
              {
                 if(end.x > 0)
                  {
                       end.x = end.x + 3;
                  }else{
                       end.x = end.x - 3;
                  }
              }
             // end ellipse
         }
         ctx.beginPath();
         ctx.moveTo(begin.x, begin.y);
         switch(orn) {
           case "left":
             ctx.bezierCurveTo(begin.x + dim, begin.y, end.x - dim, end.y, end.x, end.y);
             break;
           case "right":
             ctx.bezierCurveTo(begin.x - dim, begin.y, end.x + dim, end.y, end.x, end.y);
             break;
           case "top":
             ctx.bezierCurveTo(begin.x, begin.y + dim, end.x, end.y - dim, end.x, end.y);
             break;
           case "bottom":
             ctx.bezierCurveTo(begin.x, begin.y - dim, end.x, end.y + dim, end.x, end.y);
             break;
         }
         ctx.stroke();
    }
  }
});

function init(){
    var w = screen.width;
    var h = screen.height;
    var offset = h/3;
    //init Spacetree
    var st = new $jit.ST({
        //id of viz container element
        injectInto: 'infovis',
        //canvas width and height
        width: w,
        height: h-offset,
        //multitree
    	multitree: true,
        //set duration for the animation
        duration: 800,
        //set animation transition type
        transition: $jit.Trans.Quart.easeInOut,
        //set distance between node and its children
        levelDistance: 70,
        levelsToShow: 8,
        //sibling and subtrees offsets
        siblingOffset: 20,
        subtreeOffset: 0,
        Node: {
            dim: 0,
            align: 'left',
            type: 'line',
            overridable: true,
            autoWidth: true
        },
        Edge: {
            type: 'mybezier',
            lineWidth: 2,
            overridable: true,
            dim: 40
        },
        Navigation: {
          enable: true,
          //zooming: 50,
          panning:true
          
        },

        Events: {
          enable: true,
          onMouseWheel: function(delta, e) {
              if(counter <= 0.9)
              {
                  st.canvas.getElement().style.fontSize = "90%";
              }
              if((counter > 0.9) && (counter < 1.2))
              {
                  st.canvas.getElement().style.fontSize = counter*100 + "%";
              }
              if(counter >= 1.2)
              {
                  st.canvas.getElement().style.fontSize = "120%";
              }
          }
       },
       
        //This method is called on DOM label creation.
        //Use this method to add event handlers and styles to
        //your node.
        onCreateLabel: function(label, node){
              label.id = node.id;
              label.innerHTML = node.name;
              var el = document.getElementById(label.id);
              if (typeof node.data.color != "undefined")
              {
                   label.style.borderColor = node.data.color;
              }else{
                   label.style.borderColor = "black";
              }
              if((node.id == "0_0") || (node.id == "1_1")){
                label.style.borderWidth = "1px";
                label.style.borderStyle = "solid";
                label.style.padding = "3px";
                label.className = "node root";
              }
              label.style.align = 'center';
              if((node.pos.x < 0) && (node._depth == 1))
              {
                  node.data.$orn = "right";
              }
              label.style.display = '';
              label.style.marginTop = "-0.3em";
              label.style.cursor = 'pointer';
        },

        onPlaceLabel: function(domElement, node){
             var style = domElement.style;
             fsize = style.left.replace(/px/g, "");
             if(node._depth == 0)
             {
                 node.Node.align = "center";
             }
             if(node._depth == 1)
             {
//                if(node.pos.x > 0){
//                    fsize = fsize*1 + node.data.$width/2;
//                    style.left = fsize + "px";
//                }else{
//                    fsize = fsize*1 - node.data.$width/2;
//                    style.left = fsize + "px";
//                }
              // here ellipse
              var delta = Math.pow(2*Math.abs(node.pos.y), 3/5);
              delta = Math.ceil(delta);
              if(node.pos.x > 0)
              {
                   fsize = fsize*1 + node.data.$width/2;
                   x = fsize - delta;
              }else{
                   fsize = fsize*1 - node.data.$width/2;
                   x = fsize*1 + delta;
              }
              style.left = x + "px";
              // end ellipse
             }
             if(node._depth == 2)
             {
//                if(node.pos.x > 0){
//                    fsize = fsize*1 + node.data.$width/2;
//                    style.left = fsize + "px";
//                }else{
//                    fsize = fsize*1 - node.data.$width/2;
//                    style.left = fsize + "px";
//                }
              delta = Math.pow(2*Math.abs(node.pos.y), 3/5);
              delta = Math.round(delta);
              if(node.pos.x > 0)
              {
                   fsize = fsize*1 + node.data.$width/2;
                   x = fsize - delta;
              }else{
                   fsize = fsize*1 - node.data.$width/2;
                   x = fsize*1 + delta;
              }
              if((node.pos.y > -15) && (node.pos.y < 15)) // fix margin canvas bug
              {
                 if(node.pos.x > 0)
                  {
                       x = x - 5;
                  }else{
                       x = x + 5;
                  }
              }
              style.left = x + "px";
             }
        },

        onBeforePlotLine: function(adj){
           if (typeof adj.nodeTo.data.color != "undefined")
           {
               adj.Edge.color = adj.nodeTo.data.color;
           }else{
               adj.Edge.color = "#00C0C0";
           }
           // building tooltip from json data (adj.nodeTo.data.somedata)
           html  = '<a class="info" id="id' + adj.nodeTo.id + '" href="#link' + adj.nodeTo.id + '">' + adj.nodeTo.name + '</a>';
           adj.nodeTo.name = html;
        },

        onAfterCompute: function() {
              $('#vv_body').ajaxLoaderRemove();
        }
    });
    return st;
}

