var labelType, useGradients, nativeTextSupport, animate;

/*
(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);
})();
*/

var allNodeIDs = new Array();
var nodeSize, nodeColor, selectedNodeColor, edgeColor;
var selectedNode, selectedNodeDomElement;

function isExistingNodeID( id )
{
    for (var existingID in allNodeIDs) 
        if( existingID == id ) return true;
    return false;
}

function traverse( input, output, relation, adjacencies ) 
{
    if (typeof input == "object") {
        for (var property in input) {
            switch( property )
            {
                case "_name":
                case "_url":
                    break;
                case "_node":
                    var nodeID;
                    if( input[ property ].constructor == Array )
                    {
                        for (var object in input[ property ])
                        { 
                            var newAdjacencies = new Array();
                            nodeID = input[ property ][ object ]._url;
                            
                            if(nodeID == undefined) continue;
                            
                            allNodeIDs.push( nodeID );
                            
                            if( !isExistingNodeID( nodeID ) )
                            output.push({
                                "id": nodeID,
                                "name": input[ property ][ object ]._name,
                                "data": { 
                                    "$dim": nodeSize, 
                                    "$type": "circle", 
                                    "$color": nodeColor, 
                                    "selectedColor": selectedNodeColor, 
                                    "url": input[ property ][ object ]._url 
                                },
                                "adjacencies": newAdjacencies
                            });
                            
                            traverse( input[ property ][ object ], output, relation, newAdjacencies );
                            
                            if(adjacencies != undefined)
                            adjacencies.push({
                                "nodeTo": input[ property ][ object ]._url,
                                "data": { "$color": edgeColor, "label": relation, "type": "line" }
                            });
                        }
                    }
                    else
                    {
                        var newAdjacencies = new Array();
                        nodeID = input[ property ]._url;
                        
                        if(nodeID == undefined) break;

                        allNodeIDs.push( nodeID );
                        
                        if( !isExistingNodeID( nodeID ) )
                        output.push({
                            "id": nodeID,
                            "name": input[ property ]._name,
                            "data": { 
                                "$dim": nodeSize, 
                                "$type": "circle", 
                                "$color": nodeColor, 
                                "selectedColor": selectedNodeColor, 
                                "url": input[ property ]._url 
                            },
                            "adjacencies": newAdjacencies
                        });
                        
                        traverse( input[ property ], output, relation, newAdjacencies );
                        
                        if(adjacencies != undefined)
                        adjacencies.push({
                            "nodeTo": input[ property ]._url,
                            "data": { "$color": edgeColor, "label": relation, "type": "line" }
                        });
                    }
                    break;
                default:
                    traverse( input[ property ], output, property, adjacencies );
            }
        }
    } else {}
}

function init( containerElement, nodeSize, nodeColor, selectedNodeColor, edgeColor ) 
{
	if (document.getElementById(containerElement)) {
    this.nodeSize = nodeSize;
    this.nodeColor = nodeColor;
    this.selectedNodeColor = selectedNodeColor;
    this.edgeColor = edgeColor;

    var graph = new Array();
    
    graph.push({
        "id": "rootNode",
        "name": "",
        "data": { "$type": "none", "$color": "#000", "selectedColor": "#000" }
    });
    
    traverse( data, graph );
    
    //console.log("data for graph", graph);
    
    $jit.RGraph.Plot.EdgeTypes.implement({  
        'myarrow': {
        	'render': 
         function(adj, canvas) {
            var from = adj.nodeFrom.pos.getc(true);
            var to = adj.nodeTo.pos.getc(true);
            var dim = nodeSize * 1.5;
            var ctx = canvas.getCtx();

            var vect = new $jit.Complex(to.x - from.x, to.y - from.y);
            vect.$scale(dim / vect.norm());
            to = new $jit.Complex(to.x - vect.x, to.y - vect.y);
            vect.$scale( 0.5 );
            var intermediatePoint = new $jit.Complex(to.x - vect.x, to.y - vect.y),
            to2 = intermediatePoint.clone();
            normal = new $jit.Complex(-vect.y / 2, vect.x / 2),
            v1 = intermediatePoint.add(normal), 
            v2 = intermediatePoint.$add(normal.$scale(-1));

            ctx.beginPath();
            ctx.moveTo(from.x, from.y);
            ctx.lineTo(to2.x, to2.y);
            ctx.stroke();
            ctx.beginPath();
            ctx.moveTo(v1.x, v1.y);
            ctx.lineTo(v2.x, v2.y);
            ctx.lineTo(to.x, to.y);
            ctx.closePath();
            ctx.fill();
        } 
        }
    });  
   
    
    //init RGraph
    var rgraph = new $jit.RGraph({
        'injectInto': containerElement,
        Navigation: {
        enable: true,
        panning: true
        },
        Label: {  
            type: 'HTML'  
        },  
        Node: {
            'overridable': true
        },
        Edge: {
            'overridable': true,
            'type': 'myarrow'
        },
        interpolation: 'polar',
        transition: $jit.Trans.Quart.easeOut,
        duration:1000,
        fps: 30,
        levelDistance: 125,
        onCreateLabel: function(domElement, node){
            domElement.innerHTML = node.name;
            domElement.onclick = function () {
                rgraph.onClick(node.id, { hideLabels: true });
                
                var temp = domElement.onclick2;
                domElement.onclick2 = domElement.onclick;
                domElement.onclick = temp;
                domElement.className = "node selected";
                
                temp = node.data.$color;
                node.data.$color = node.data.selectedColor;
                node.data.selectedColor = temp;
                
                if( selectedNodeDomElement != undefined )
                {
                    temp = selectedNodeDomElement.onclick2;
                    selectedNodeDomElement.onclick2 = selectedNodeDomElement.onclick;
                    selectedNodeDomElement.onclick = temp; 
                    
                    temp = node.data.$color;
                    selectedNode.data.$color = selectedNode.data.selectedColor;
                    selectedNode.data.selectedColor = temp;
                    
                    selectedNodeDomElement.className = "node";
                }

                selectedNodeDomElement = domElement;
                selectedNode = node;
            };
            domElement.onclick2 = function () {
                if( node.data.url != "" )
                    document.location.href = node.data.url;
            };

            domElement.style.cursor = 'pointer';
            
            $jit.Graph.Util.eachAdjacency(node, function(adj) { 
                var edgeID = adj.nodeFrom.id + "-" + adj.nodeTo.id;
                if( document.getElementById( adj.nodeTo.id + "-" + adj.nodeFrom.id ) == undefined )
                {
                    var domElement2 = document.createElement('div');
                    domElement2.className = "edge";
                    domElement2.style.position = "absolute";
                    domElement2.id = edgeID;
                    domElement2.innerHTML = adj.data.label;
                    var container = rgraph.labels.getLabelContainer();
                    container.appendChild(domElement2);
                }
            });
        },
        onPlaceLabel: function(domElement, node){
            var style = domElement.style;
            var top = parseInt(style.top);
            var left = parseInt(style.left);
            var w = domElement.offsetWidth;
            style.top = (top + 15) + 'px';
            style.left = (left - w / 2) + 'px';
            
            $jit.Graph.Util.eachAdjacency(node, function(adj) { 
                var domElement2 = document.getElementById( adj.nodeTo.id + "-" + adj.nodeFrom.id );
                if( domElement2 != undefined )
                {
                    var domElementTo = document.getElementById( adj.nodeTo.id );
                    var domElementFrom = document.getElementById( adj.nodeFrom.id );
                    top = parseInt(domElementTo.style.top) + parseInt(domElementFrom.style.top);              
                    left = parseInt(domElementTo.style.left) + parseInt(domElementFrom.style.left);  
                    w = domElement2.offsetWidth;   
                    var h = domElement2.offsetHeight;         
                    domElement2.style.top = (top / 2 - h / 2) + 'px';
                    domElement2.style.left = (left / 2) + 'px';
                }
            });
        },
        
    });

    rgraph.loadJSON(graph, 1);

    rgraph.refresh();
        
    document.getElementById( allNodeIDs[ 0 ] ).onclick();
    
    rgraph.refresh();

    rgraph.controller.onBeforeCompute(rgraph.graph.getNode(rgraph.root));
    rgraph.controller.onAfterCompute();
	}
}

