var FigureView = FrameView.extend({

  // {{{ init
  init: function( animation, canvas, width, height, lineWidthControl ) {
    
    this._super( animation, canvas, width, height );
    
    this.lineWidthControl = lineWidthControl;

    this.currentNode = null;
    this.clipboardNode = null;
    this.showStatic = true;
    
    this.mode = "select";
    this.singleSelect = false;
  },
  // }}}

  // {{{ setCurrentNode
  setCurrentNode: function( node ) {
    this._super( node );
    if (node != null) {
      if ( node.lineWidth != null ) {
        this.lineWidthControl.value = node.lineWidth;
      }
    }
  },
  // }}}
  
  // {{{ drawHandles
  drawHandles: function() {
    if ( this.mode == "select" ) {
      
      if ( (this.currentFigure != null) && (this.currentNode != null) ) {
        // Emphasize the Handle for the current node       
        Handle.CURRENT_HANDLE.drawHandle( this.currentNode, this.context, this.zoom );
                
        // Draw a skeleton
        this.context.lineWidth = 3;
        this.context.strokeStyle = "rgba( 255,0,255, 1 )";
        
        if (this.singleSelect) {
          
          if (this.currentNode.parent != null) {
            this.currentNode.drawSkeleton( this.context );
          }
          
        } else {
          
          var iter = new NodeIterator( this.currentNode );          
          while ( iter.hasNext() ) {
            var node = iter.next();
            if ( (node.parent != null) && (node.behaviour != Behaviour.BOUNDING_BEHAVIOUR) ) {
              node.drawSkeleton( this.context );
            }
          }
          
        }
        
      }
      this._super();
      
    } else {
     
      if ( this.currentFigure != null ) {
        var iter = new NodeIterator( this.currentFigure.root );
        while ( iter.hasNext() ) {
          var node = iter.next();
          if ( node.behaviour != Behaviour.BOUNDING_BEHAVIOUR ) {
            Handle.STATIC_HANDLE.drawHandle( node, this.context, this.zoom );
          }
        }
      }
    }
    
  },
  // }}}

  // {{{ setClipboardNode
  setClipboardNode: function( node, single ) {
    if ( (node.parent != null) && (! node.copyIgnore) ) { // Cant do that to the root node or to controls
      this.log.debug( "Setting clipboard to : ", node );
      this.clipboardNode = new Root( node.parent.x, node.parent.y );
      
      var copy = node.copy();
      this.clipboardNode.addNode( copy );
        
      if ( single ) {
        while ( copy.children.length > 0 ) {
          copy.children[ 0 ].remove();
        }
      }
      
    }
  },
  // }}}

  // {{{ onMouseDownInner
  onMouseDownInner: function( e, x, y ) {
    
    if ( this.mode == "select" ) {
      
      this._super( e, x, y );
      this.singleSelect = ! e.ctrlKey;
      
    } else {
      
      this.log.debug( "down, not select" )
      if ( this.currentFigure == null ) {
        this.log.debug( "exit - nothing selected" )
        return;
      }
      
      var node = this.currentFigure.findHandleAt( x, y, this.zoom, true );
      if ( node ) {

        this.log.debug( "starting new shape from", node )

        this.startNode = node;
        this.setCurrentNode( null );
        this.draggingNode = null;
                
      }
    }
  },
  // }}}
  
  // {{{ onMouseMoveInner
  onMouseMoveInner: function( e, x, y, alternate ) {
    
    if ( (this.mode == "select") || (this.draggingNode != null) ) {
      
      this.log.trace( "onMouseMove fallback" );
      this._super( e, x, y, alternate || (this.mode != "select") );
      
    } else {

      e = Helpers.resolveMouseEvent( e, this.canvas );
      this.log.trace( "FigureView.onMouseMove" , e.relX, e.relY );

      var x = this.toWorldX( e.relX );
      var y = this.toWorldY( e.relY );
      
      this.log.debug( "onMouseMove, non select", x, y );
      
      if ( this.startNode != null ) {
        var dx = x - this.startNode.x;
        var dy = y - this.startNode.y;

        this.log.debug( "distance", dx, dy, dx * dx + dy * dy > 20 );

        if ( dx * dx + dy * dy > 20 ) {
          
          this.log.debug( "created a new line" );

          if ( this.mode == "ellipse" ) {
            this.draggingNode = new Ellipse( x, y );
          } else {
            this.draggingNode = new Line( x, y );
          }
          this.setCurrentNode( this.draggingNode );
          this.startNode.addNode( this.draggingNode );
          this.dragOffsetX = 0;
          this.dragOffsetY = 0;
          
        }
      }
      
    }
  },
  // }}}

  // {{{ onStatic
  onStatic: function() {
    if (this.currentNode != null) {
      this.currentNode.isStatic = ! this.currentNode.isStatic;
      this.changedFigure();
    }
  },
  // }}}

  // {{{ onDeleteNode
  onDeleteNode:function() {
    
    if ( (this.currentNode != null) && (this.currentNode.canDelete) ) {

      this.setClipboardNode( this.currentNode, this.singleSelect );
      
      if ( this.singleSelect ) {
        var parent = this.currentNode.parent;
        this.currentNode.translateTo( this.currentNode.parent.x, this.currentNode.parent.y );
        
        while ( this.currentNode.children.length > 0 ) {
          var child = this.currentNode.children[ 0 ];
          child.remove();
          parent.addNode( child );
        }
      }
      
      this.currentNode.remove();
      this.setCurrentNode( null );

      this.changedFigure();
    }
  },
  // }}}
  
  // {{{ onCopyNode
  onCopyNode:function() {
    if ( (this.currentNode != null) && (this.currentNode.parent != null) ) {
      this.setClipboardNode( this.currentNode, this.singleSelect );
    }
  },
  // }}}
  
  // {{{ onPasteNode
  onPasteNode:function() {
    if ( (this.currentNode != null) && (this.clipboardNode != null) ) {
      this.clipboardNode.translateTo( this.currentNode.x, this.currentNode.y );
      this.currentNode.addNode( this.clipboardNode.children[ 0 ].copy() );
      
      this.changedFigure();
    }
  },
  // }}}
  
  // {{{ onMode
  onMode: function( mode ) {
    this.mode = mode;
    this.draw();
  },
  // }}}
  
  // {{{ setLineWidth
  setLineWidth: function( lineWidth ) {
    
    this.lineWidthControl.value = lineWidth;
    
    if ( this.currentNode != null) {
      
      if ( this.singleSelect ) {
        
        this.log.debug( "setting line width for current node only" );
        if (this.currentNode.lineWidth != null) {
          this.currentNode.lineWidth = lineWidth;
          this.changedFigure();
        }
        
      } else {
        
        this.log.debug( "setting line width for current node's tree" );
        var iter = new NodeIterator( this.currentNode );
        while ( iter.hasNext() ) {
          var node = iter.next();
          this.log.debug( "setting line width", node, node.lineWidth );
          if ( node.lineWidth != null ) {
            node.lineWidth = lineWidth;
          }
        }
        this.changedFigure();
        
      }
    }
  },
  // }}}
  
  // {{{ onLineWidthDelta
  onLineWidthDelta: function( d ) {
    var lineWidth = 4;
    try {
      lineWidth = parseFloat( this.lineWidthControl.value ) + d;
    } catch (e) {
    }
    this.setLineWidth( lineWidth );
  },
  // }}}
  
  // {{{ onLineWidthChange
  onLineWidthChange: function( event ) {
      
    var lineWidth = 4;
    try {        
      lineWidth = parseFloat( this.lineWidthControl.value );
    } catch(e) {
    }
    this.setLineWidth( lineWidth );
    
  },
  // }}}
  
  // {{{ onBehaviour
  onBehaviour: function( name ) {
    if (this.currentNode != null) {
      if (this.currentNode.changeBehaviour != null ) { 
        this.currentNode.changeBehaviour( name );
      }
    }
  },
  // }}}

  // {{{ onKeyPressed
  onKeyPressed: function( event ) {
    
    if ( (event.key == 'f') || (event.key == 'F') ) {
      this.onStatic();
      return true;
    } else if ( (event.key == 'x') || (event.key == 'X') ) {
      this.onDeleteNode();
      return true;
    } else if ( (event.key == 'v') || (event.key == 'V') ) {
      this.onPasteNode();
      return true;
    } else if ( (event.key == 's') || (event.key == 'S') ) {
      this.onMode( "select" );
      return true;
    } else if ( (event.key == 'l') || (event.key == 'L') ) {
      this.onMode( "line" );
      return true;
    } else if ( (event.key == 'e') || (event.key == 'E') ) {
      this.onMode( "ellipse" );
      return true;
    } else if ( (event.key == 'c') || (event.key == 'C') ) {
      this.onCopyNode();
      return true;
    } else if ( (event.key == '{') || (event.key == '[') ) {
      this.onLineWidthDelta( -1 );
      return true;
    } else if ( (event.key == '}') || (event.key == ']') ) {
      this.onLineWidthDelta( 1 );
      return true;
    } else if ( (event.key == '1') ) {
      this.onBehaviour( 'pivot' );
      return true;
    } else if ( (event.key == '2') ) {
      this.onBehaviour( 'dual' );
      return true;
    } else if ( (event.key == '3') ) {
      this.onBehaviour( 'dual-anticlockwise' );
      return true;
    } else if ( (event.key == '4') ) {
      this.onBehaviour( 'dual-clockwise' );
      return true;
    } else if ( (event.key == '5') ) {
      this.onBehaviour( 'move' );
      return true;
    } else if ( (event.key == '6') ) {
      this.onBehaviour( 'independent' );
      return true;
    }
    
    return this._super( event );
  },
  // }}}

  // {{{ onFrameChanged
  onFrameChanged: function() {
    if ( this.currentFigure != null ) {
      this.setCurrentFigure( this.getCurrentFrame().findFigure( this.currentFigure.id ) );
    }
    if (this.currentFigure == null) {
      this.setCurrentNode( null );
    } else {
      if ( this.currentNode != null ) {
        if ( this.currentNode.getRoot() != this.currentFigure.root ) {
          this.setCurrentNode( null );
        }
      }
    }
    this.draw();
  },
  // }}}
  
  // {{{ toString
  toString: function() {
    return this._super() + "(FigureView)";
  }
  // }}}

});


