//
// This work is licensed under the Creative Commons Attribution 2.5 License. To 
// view a copy of this license, visit
// http://creativecommons.org/licenses/by/2.5/
// or send a letter to Creative Commons, 543 Howard Street, 5th Floor, San
// Francisco, California, 94105, USA.
//
// All copies and derivatives of this source must contain the license statement 
// above and the following attribution:
//
// Author: Kyle Scholz      http://kylescholz.com/
// Copyright: 2006
//

defined = function( x ) {
    return x === undefined ? false : true;
}


function stopEvent( event ) {
    event = event || this;
    if( Event && event === Event )
        event = window.event;
    if( event.preventDefault )
        event.preventDefault();
    if( event.stopPropagation )
        event.stopPropagation();
    try {
        event.cancelBubble = true;
        event.returnValue = false;
    } catch( e ) {}
    return false;
}

function getWindowScroll( w ) {
    var s = {
            left: 0,
            top: 0
        };

        var d = w.document;

        // ie
        var de = d.documentElement;
        if( de && defined( de.scrollLeft ) ) {
            s.left = de.scrollLeft;
            s.top = de.scrollTop;
        }

        // safari
        else if( defined( w.scrollX ) ) {
            s.left = w.scrollX;
            s.top = w.scrollY;
        }

        // opera
        else if( d.body && defined( d.body.scrollLeft ) ) {
            s.left = d.body.scrollLeft;
            s.top = d.body.scrollTop;
        }

        return s;
}

// mouse move capture for IE
var IE = document.all?true:false;
if (!IE) document.captureEvents(Event.MOUSEMOVE)

    function handleQuery( r, params ) {
      if (r.readyState == 4) {
        var loading = document.getElementById('loading');
        if (loading)
           loading.style.visibility = 'hidden';
        var xmlDoc = r.responseXML;

        var error = xmlDoc.documentElement.getElementsByTagName("error");

        if (error && error.length)
            alert(getTextFromNode(error[ 0 ].getAttributeNode('error')));
        
        // obtain the array of foafsets and loop through it
        var foafsets = xmlDoc.documentElement.getElementsByTagName("foafset");
        for( var i=0; i<foafsets.length; i++ ) {
          //var id = getTextFromNode( foafsets[i].getAttributeNode('id') );
          //var foafNode = control.addNode( '', true );

          var friends = foafsets[i].getElementsByTagName("person");
          var type = getTextFromNode( foafsets[i].getAttributeNode('type') );
          var thisImg = getTextFromNode( foafsets[i].getAttributeNode('img') );
          graphui.setOriginText( getTextFromNode( foafsets[i].getAttributeNode('nick') ) );

          //  graphui.setOriginImage( thisImg );
          
          for( var j=0; j<friends.length; j++ ) {
            var nick = getTextFromNode( friends[j].getAttributeNode('nick') );
            var foafurl = getTextFromNode( friends[j].getAttributeNode('foaf') );
            var img = getTextFromNode( friends[j].getAttributeNode('img') );

            if ( foafurl != foaf ) {
              if ( foafurl )
                control.addNode( "<img src=\"" + img + "\">&nbsp;<a href=\"?"+foafurl+"\">"+nick+"</a>", true );
              else
                control.addNode( "<img src=\"" + img + "\">&nbsp;"+nick, true );
              /*
              if ( foafurl )
                control.addNode( "<img src=\"" + color[ type ] + "\">&nbsp;<a href=\"?"+foafurl+"\">"+nick+"</a>", true );
              else
                control.addNode( "<img src=\"" + color[ type ] + "\">&nbsp;"+nick, true );
              */
              //var termNode = control.addNode( "<img src=\"" + color[ type ] + "\">&nbsp;<a href=\"?"+foafurl+"\">"+nick+"</a>", false );
              //control.addEdge( foafNode, termNode );
            }

            //var domNode = graphui.getNode( foafNode.id );

            //domNode.innerHTML = "<img src=\"" + color[ type ] + "\">";
          
            //var gloss = getTextFromNode( foafsets[i].getAttributeNode('gloss') );
			/*
            var context = new Object();
            context.nick = nick;
            context.type = type;
            context.obj = domNode;
			*/
            
            // add a mouseoverent handler
            /*
            domNode.onmouseover = new EventHandler( context, 
              function( context, e ) {
              
                if ( graph['selectedNode'] == -1 ) {
                  var nick = context.nick;
                  nick = nick.replace( /\`/g, "\'" );
                  nick = nick.replace( /\"/g, "\'" );
                  nick = nick.replace( /#(.*?)#/g, "\"<i>$1\"</i>" );
  
                  var definition = '<div style="border-bottom:1px dashed #444444;margin-bottom:4px;padding-bottom:4px"><b>Nickname:</b></div> (' + context.pos + '): ' + nick;
			
                  document.getElementById('nick').innerHTML=definition; 

                  var target = context.obj;
                  if ( target ) {
             	    document.getElementById('nick').style.left=parseInt(target.style.left) - 210;
                    document.getElementById('nick').style.top=parseInt(target.style.top) - 10;
                  }                
                  document.getElementById('nick').style.visibility="visible";
                  timer.stop();
                }
              }
            );
            */

            // add a mouseoutvent handler
            /*
            domNode.onmouseout = new EventHandler( nick, 
              function( nick, e ) {
                document.getElementById('nick').style.visibility="hidden"; 
                timer.start();
              }
            );
            */
          }
        }
      }
    }


// UserControl:
var UserControl = function(){};
UserControl.prototype = {

  initialize: function( timer, graph, ui ) {
    this['timer'] = timer;
    this['graph'] = graph;
    this['ui'] = ui;
    this['lastSelectedNode']=-1;
    this['liveNode']=-1;
    var context=this;

    // append the mousemove eventhandler
    window.onresize = function( e ) {
      return(
        context.resizeFrame( e )
      );
    };

    // append the mousemove eventhandler
    document.onmousemove = function( e ) {
        context.moveSelected( e );
        return stopEvent( e );
    };

    // append the mouseup eventhandler
    document.onmouseup = function( e ) {
        context.unselectNode( e );
        return stopEvent( e );
    };
  },

  // resize the frame when the windo size changes
  resizeFrame: function( e ) {
    var FRAME_WIDTH;
    var FRAME_HEIGHT;

    if (IE) {
      FRAME_WIDTH = document.body.offsetWidth;
      FRAME_HEIGHT = document.body.offsetHeight;
    } else {
      FRAME_WIDTH = window.innerWidth;
      FRAME_HEIGHT = window.innerHeight;
    }

    FRAME_WIDTH -= (parseInt(document.getElementById('frame').style.left)*2);
    FRAME_HEIGHT -= (parseInt(document.getElementById('frame').style.top)+20);

    this.ui['frame_width']=FRAME_WIDTH;
    this.ui['frame_height']=FRAME_HEIGHT;

    this.graph['frame_width']=FRAME_WIDTH;
    this.graph['frame_height']=FRAME_HEIGHT;

    graph.origin.position['x'] = parseInt(this.graph['frame_width']/2);
    graph.origin.position['y'] = parseInt(this.graph['frame_height']/2);

    this.ui.drawOrigin( this.graph['origin'] );
  },

  // make this node 'selected' in the graph
  selectNode: function( e, node ) {
    if ( node == this['liveNode'] ) {
        this.unattach( e, this['liveNode'] );
    } else if ( this['liveNode'] != -1 ) {
      this.graph.addEdge( graph.getNode(this['liveNode']), graph.getNode(node), 48 );
    }
    this['graph'].setSelected( node );
  },

  focusNode: function( e, node ) {
    this['liveNode'] = node;
    graphui.setLive( graph.getNode(node) );
  },

  unattach: function( e, node ) {
    if ( this['liveNode'] != -1 ) {
      var at = this['liveNode'];
      graphui.unSetLive( graph.getNode(node) );
      this['liveNode'] = -1;
    }
  },

  // unselect this node in the graph
  unselectNode: function() {
    this['lastSelectedNode'] = this['graph'].getSelected();
    this['graph'].clearSelected();
  },

  // handle mouse movement when a node is selected
  moveSelected: function( e ) {
    if ( graph.hasSelected() ) {
      var selectedNode = graph.getSelected();
      var node = this.ui.getNode( selectedNode );
      var tempX;
      var tempY;

        
/*
      if (IE) {
        tempX = event.clientX + document.body.scrollLeft;
        tempY = event.clientY + document.body.scrollTop;
      } else {
        tempX = e.pageX;
        tempY = e.pageY;
      }
*/
        var s = getWindowScroll( window );
    
        tempX = s.left + e.clientX;
        tempY = s.top + e.clientY;

//        var log = document.getElementById('log');


      tempX -= graphui.frame_left;
      tempY -= graphui.frame_top;


      // adjust for center
      tempX -= parseInt( node.style.width || 15 ) / 2;
      tempY -= parseInt( node.style.height ) / 2;

//        log.value = 'w:'+node.style.width+' x:'+tempX+' y:'+tempY;

      // set the node position
      graph.getNode( selectedNode ).position['x']=tempX;
      graph.getNode( selectedNode ).position['y']=tempY;

      // if the timer is interupted, we still want the graph to move while we move the selected node around
      if ( this.timer['interupt'] ) {
        this.graph.applyForce();
      }
    }
  },

  // 
  addEdge: function( node1, node2, weight ) {
    if ( !weight ) { weight=48; }
    this.graph.addEdge( node1, node2, weight );
  },

  // 
  addNode: function( text, originEdge, weight ) {

    var node;
    node = graph.addNode( 1, text );

    var domNode = this.ui.getNode( node.id );
    var context = this;

    if ( originEdge ) { 
      if ( !weight ) { weight=92 }
      this.graph.addOriginEdge( node, weight );
      this.ui.addEdge( node, graph.getOrigin(), weight );
    }

    // add a mousedown event handler
    domNode.onmousedown=function(e) {
        context.selectNode(e, node.id);
        return stopEvent( e );
    };

    return node;
  }
}

