import flash.display.Sprite;
import flash.display.Stage;

import flash.geom.Vector3D;

import flash.Vector;

import flash.events.Event;
import flash.events.MouseEvent;

class WMController extends Sprite {
  private var wm( null, null ):Watermelon;

  // colors
  public var bgColor( __getBackgroundColor, __setBackgroundColor ):Int;
    public function __getBackgroundColor():Int { return( bgColor ); }
    public function __setBackgroundColor( c:Int ):Int {
      bgColor = c;
      return( bgColor );
    }

  public var bgAlpha( __getBackgroundAlpha, __setBackgroundAlpha ):Float;
    public function __getBackgroundAlpha():Float { return( bgAlpha ); }
    public function __setBackgroundAlpha( a:Float ):Float {
      bgAlpha = a;
      return( bgAlpha );
    }

  public var buttonColor( __getButtonColor, __setButtonColor ):Int;
    public function __getButtonColor():Int { return( buttonColor ); }
    public function __setButtonColor( c:Int ):Int {
      buttonColor = c;
      return( buttonColor );
    }

  public var buttonAlpha( __getButtonAlpha, __setButtonAlpha ):Float;
    public function __getButtonAlpha():Float { return( buttonAlpha ); }
    public function __setButtonAlpha( a:Float ):Float {
      buttonAlpha = a;
      return( buttonAlpha );
    }

  // line width
  public var lineWidth( __getLineWidth, __setLineWidth ):Float;
    public function __getLineWidth():Float { return( lineWidth ); }
    public function __setLineWidth( w:Float ):Float {
      lineWidth = w;
      return( lineWidth );
    }

  // sizes
  public var buttonWidth( __getButtonWidth, __setButtonWidth ):Int;
    public function __getButtonWidth():Int { return( buttonWidth ); }
    public function __setButtonWidth( w:Int ):Int {
      buttonWidth = w;
      return( buttonWidth );
    }

  public var buttonHeight( __getButtonHeight, __setButtonHeight ):Int;
    public function __getButtonHeight():Int { return( buttonHeight ); }
    public function __setButtonHeight( h:Int ):Int {
      buttonHeight = h;
      return( buttonHeight );
    }

  // button margin
  public var margin( __getMargin, __setMargin ):Int;
    public function __getMargin():Int { return( margin ); }
    public function __setMargin( m:Int ):Int {
      margin = m;
      return( margin );
    }

  // ######################################################################

  public function new( w:Watermelon ) {
    super();
    wm = w;

    // default values
    bgColor = 0xFFFFFF;
    bgAlpha = 0.0;
    buttonColor = 0x888888;
    buttonAlpha = 1.0;
    buttonWidth = 20;
    buttonHeight = 20;
    margin = 2;
    lineWidth = 3;
  }

  // misc funcs
  //// check whether the controller is created
  public function enabled():Bool {
    return( this.numChildren > 0 );
  }

  // drawings
  public function draw() {
    this.graphics.clear();
    this.removeChildren();

    fillBackground();
    createForwardButton();
    createGoToLastButton();
    createBackButton();
    createGoToInitButton();

    createPlayer();
    createScaler();

    // controller position
    this.y = wm.stage.stageHeight - buttonHeight;

    // controller event listener
    var ref = this;
    this.addEventListener( MouseEvent.ROLL_OVER,
                           function( e:Event ) {
                             ref.alpha = 1.0;
                           } );
    this.addEventListener( MouseEvent.ROLL_OUT,
                           function( e:Event ) {
                             ref.alpha = 0.0;
                           } );

    return( this );
  }

  private function createScaler():Void {
    var scaler = new Sprite();
    scaler.graphics.beginFill( bgColor, bgAlpha );
    scaler.graphics.drawRect( 0, 0, 3 * buttonWidth + margin, buttonHeight );
    scaler.graphics.endFill();

    // initializer
    var initializer = new Sprite();
    initializer.graphics.beginFill( bgColor, bgAlpha );
    initializer.graphics.drawRect( 0, 0, buttonWidth, buttonHeight );
    initializer.graphics.endFill();
    initializer.graphics.lineStyle( lineWidth, buttonColor, buttonAlpha );
    var rad:Float = 0.35 * Math.min( buttonWidth, buttonHeight );
    initializer.graphics.drawCircle( 0.65 * buttonWidth, 0.35 * buttonHeight, rad );
    var vec:Float = 1.0 / Math.sqrt( 2 );
    var vm:Float = 0.65 * Math.min( buttonWidth, buttonHeight );
    initializer.graphics.moveTo( 0.65 * buttonWidth - rad * vec,
                                 0.35 * buttonHeight + rad * vec );
    initializer.graphics.lineTo( 0.65 * buttonWidth - vm,
                                 0.35 * buttonHeight + vm );
    scaler.addChild( initializer );
    initializer.x = buttonWidth;
    var ref = wm;
    initializer.addEventListener( MouseEvent.CLICK,
                                  function( e:MouseEvent ) {
                                    var v3:Vector<Vector3D> = new Vector<Vector3D>(3);
                                    v3 = ref.states.mpos.decompose();
                                    v3[2].setTo( 1.0, 1.0, 1.0 );
                                    ref.states.mpos.recompose( v3 );
                                    ref.states.updateMPos = true;
                                  } );

    // enlarger
    var enlarger:Sprite = new Sprite();
    enlarger.graphics.beginFill( bgColor, bgAlpha );
    enlarger.graphics.drawRect( 0, 0, buttonWidth, buttonHeight );
    enlarger.graphics.endFill();
    enlarger.graphics.lineStyle( lineWidth, buttonColor, buttonAlpha );
    enlarger.graphics.moveTo( margin, buttonHeight / 2 );
    enlarger.graphics.lineTo( buttonWidth - margin, buttonHeight / 2 );
    enlarger.graphics.moveTo( buttonWidth / 2, margin );
    enlarger.graphics.lineTo( buttonWidth / 2, buttonHeight - 2 );
    scaler.addChild( enlarger );
    enlarger.x = scaler.width - buttonWidth;
    enlarger.addEventListener( MouseEvent.CLICK,
                               function( e:MouseEvent ) {
                                 ref.states.changeScale( 5 );
                               } );

    // shrinker
    var shrinker:Sprite = new Sprite();
    shrinker.graphics.beginFill( bgColor, bgAlpha );
    shrinker.graphics.drawRect( 0, 0, buttonWidth, buttonHeight );
    shrinker.graphics.endFill();
    shrinker.graphics.lineStyle( lineWidth, buttonColor, buttonAlpha );
    shrinker.graphics.moveTo( margin, buttonHeight / 2 );
    shrinker.graphics.lineTo( buttonWidth - margin, buttonHeight / 2 );
    scaler.addChild( shrinker );
    shrinker.x = 0;
    shrinker.addEventListener( MouseEvent.CLICK,
                               function( e:MouseEvent ) {
                                 ref.states.changeScale( -5 );
                               } );

    this.addChild( scaler );
    scaler.x = wm.stage.stageWidth / 2 + buttonWidth;
  }

  private function createPlayer():Void {
    var player:Sprite = new Sprite();
    player.graphics.beginFill( bgColor, bgAlpha );
    player.graphics.drawRect( 0, 0, 3 * buttonWidth, buttonHeight );
    player.graphics.endFill();
    player.x = wm.stage.stageWidth / 2 - player.width - buttonWidth;

    // stop buttton
    var stopbutton:Sprite = new Sprite();
    stopbutton.graphics.beginFill( bgColor, bgAlpha );
    stopbutton.graphics.drawRect( 0, 0, buttonWidth, buttonHeight );
    stopbutton.graphics.endFill();
    stopbutton.graphics.beginFill( buttonColor, buttonAlpha );
    stopbutton.graphics.drawRect( margin, margin, buttonWidth - 2 * margin, buttonHeight - 2 * margin);
    stopbutton.graphics.endFill();
    stopbutton.x = buttonWidth;
    player.addChild( stopbutton );
    stopbutton.addEventListener( MouseEvent.CLICK, wm.states.pausePlay );

    // play forward
    var playforward:Sprite = new Sprite();
    playforward.graphics.beginFill( bgColor, bgAlpha );
    playforward.graphics.drawRect( 0, 0, buttonWidth, buttonHeight );
    playforward.graphics.endFill();
    playforward.graphics.lineStyle( lineWidth, buttonColor, buttonAlpha );
    playforward.graphics.moveTo( margin, buttonHeight / 2 );
    playforward.graphics.lineTo( buttonWidth - margin, buttonHeight / 2 );
    playforward.graphics.lineTo( buttonWidth / 2, margin );
    playforward.graphics.moveTo( buttonWidth - margin, buttonHeight / 2 );
    playforward.graphics.lineTo( buttonWidth / 2, buttonHeight - margin );
    playforward.x = player.width - buttonWidth;
    player.addChild( playforward );
    playforward.addEventListener( MouseEvent.CLICK, wm.states.playForward );

    // play backward
    var playbackward:Sprite = new Sprite();
    playbackward.graphics.beginFill( bgColor, bgAlpha );
    playbackward.graphics.drawRect( 0, 0, buttonWidth, buttonHeight );
    playbackward.graphics.endFill();
    playbackward.graphics.lineStyle( lineWidth, buttonColor, buttonAlpha );
    playbackward.graphics.moveTo( buttonWidth - margin, buttonHeight / 2 );
    playbackward.graphics.lineTo( margin, buttonHeight / 2 );
    playbackward.graphics.lineTo( buttonWidth / 2, margin );
    playbackward.graphics.moveTo( margin, buttonHeight / 2 );
    playbackward.graphics.lineTo( buttonWidth / 2, buttonHeight - margin );
    playbackward.x = 0;
    player.addChild( playbackward );
    playbackward.addEventListener( MouseEvent.CLICK, wm.states.playBackward );

    this.addChild( player );
  }

  private function fillBackground():Void {
    this.graphics.beginFill( bgColor, bgAlpha );
    this.graphics.drawRect( 0, 0, wm.stage.stageWidth, buttonHeight );
    this.graphics.endFill();
    this.alpha = 0.0;
  }

  private function createForwardButton():Void {
    var forward_button = new Sprite();
    forward_button.graphics.beginFill( bgColor, bgAlpha );
    forward_button.graphics.drawRect( 0, 0, buttonWidth, buttonHeight );
    forward_button.graphics.endFill();

    forward_button.graphics.lineStyle( 0, buttonColor, buttonAlpha );
    forward_button.graphics.beginFill( buttonColor, buttonAlpha );
    forward_button.graphics.moveTo( margin, margin );
    forward_button.graphics.lineTo( margin, buttonHeight - margin );
    forward_button.graphics.lineTo( buttonWidth - margin, buttonHeight / 2 );
    forward_button.graphics.lineTo( margin, margin );
    forward_button.graphics.endFill();
    this.addChild( forward_button );
    forward_button.x = wm.stage.stageWidth - 2 * buttonWidth;
    forward_button.addEventListener( MouseEvent.CLICK, wm.states.forwardScene );
  }

  private function createGoToLastButton():Void {
    var last_button = new Sprite();
    last_button.graphics.beginFill( bgColor, bgAlpha );
    last_button.graphics.drawRect( 0, 0, buttonWidth, buttonHeight );
    last_button.graphics.endFill();

    last_button.graphics.lineStyle( 0, buttonColor, buttonAlpha );
    last_button.graphics.beginFill( buttonColor, buttonAlpha );
    last_button.graphics.moveTo( margin, margin );
    last_button.graphics.lineTo( margin, buttonHeight - margin );
    last_button.graphics.lineTo( buttonWidth / 2, buttonHeight / 2 );
    last_button.graphics.lineTo( margin, margin );
    last_button.graphics.moveTo( buttonWidth / 2, margin );
    last_button.graphics.lineTo( buttonWidth / 2, buttonHeight - margin );
    last_button.graphics.lineTo( buttonWidth - margin, buttonHeight / 2 );
    last_button.graphics.lineTo( buttonWidth / 2, margin );
    last_button.graphics.endFill();
    this.addChild( last_button );
    last_button.x = wm.stage.stageWidth - buttonWidth;
    last_button.addEventListener( MouseEvent.CLICK, wm.states.gotoLastScene );
  }

  private function createBackButton():Void {
    var back_button = new Sprite();
    back_button.graphics.beginFill( bgColor, bgAlpha );
    back_button.graphics.drawRect( 0, 0, buttonWidth, buttonHeight );
    back_button.graphics.endFill();

    back_button.graphics.lineStyle( 0, buttonColor, buttonAlpha );
    back_button.graphics.beginFill( buttonColor, buttonAlpha );
    back_button.graphics.moveTo( buttonWidth - margin, margin );
    back_button.graphics.lineTo( buttonWidth - margin, buttonHeight - margin );
    back_button.graphics.lineTo( margin, buttonHeight / 2 );
    back_button.graphics.lineTo( buttonWidth - margin, 2 );
    back_button.graphics.endFill();
    this.addChild( back_button );
    back_button.x = buttonWidth;
    back_button.addEventListener( MouseEvent.CLICK, wm.states.backScene );
  }

  private function createGoToInitButton():Void {
    var init_button = new Sprite();
    init_button.graphics.beginFill( bgColor, bgAlpha );
    init_button.graphics.drawRect( 0, 0, buttonWidth, buttonHeight );
    init_button.graphics.endFill();

    init_button.graphics.lineStyle( 0, buttonColor, buttonAlpha );
    init_button.graphics.beginFill( buttonColor, buttonAlpha );
    init_button.graphics.moveTo( buttonWidth - margin, margin );
    init_button.graphics.lineTo( buttonWidth - margin, buttonHeight - margin );
    init_button.graphics.lineTo( buttonWidth / 2, buttonHeight / 2 );
    init_button.graphics.lineTo( buttonWidth - margin, margin );
    init_button.graphics.moveTo( buttonWidth / 2, margin );
    init_button.graphics.lineTo( buttonWidth / 2, buttonHeight - margin );
    init_button.graphics.lineTo( margin, buttonHeight / 2 );
    init_button.graphics.lineTo( buttonWidth / 2, margin );
    init_button.graphics.endFill();
    this.addChild( init_button );
    init_button.x = 0;
    init_button.addEventListener( MouseEvent.CLICK, wm.states.gotoInitScene );
  }
}
