// --------------------------------------------------------------------
// wm3d - A Flash Molecular Viewer
//
// Copyright (c) 2011-2014, tamanegi (tamanegi@users.sourceforge.jp)
// All rights reserved.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// --------------------------------------------------------------------

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

import flash.text.TextField;
import flash.text.TextFormat;

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

import haxe.macro.Context;

/**
  About message
**/

class WMAbout extends Sprite {
  // note: version name migrates to WMVersion.hx
  private var mystage:Stage;

  /**
    background color: default is green
  **/
  @:isVar public var bgColor( get, set ):Int;
    /**
      getter for `bgColor`
    **/
    public function get_bgColor():Int { return( bgColor ); }
    /**
      setter for `bgColor`
    **/
    public function set_bgColor( c:Int ):Int {
      bgColor = c;
      return( bgColor );
    }

  /**
    background color alpha: default is 0.5
  **/
  @:isVar public var bgAlpha( get, set ):Float;
    /**
      getter for `bgAlpha`
    **/
    public function get_bgAlpha():Float { return( bgAlpha ); }
    /**
      setter for `bgAlpha`
    **/
    public function set_bgAlpha( a:Float ):Float {
      bgAlpha = a;
      return( bgAlpha );
    }

  /**
    font name for drawing message: default is "Arial"
  **/
  @:isVar public var fontname( get, set ):String;
    /**
      getter for `fontname`
    **/
    public function get_fontname():String { return( fontname ); }
    /**
      setter for `fontname`
    **/
    public function set_fontname( f:String ):String {
      fontname = f;
      return( fontname );
    }

  /**
    font color for "wm3d" in about; default is black
  **/
  @:isVar public var softnameColor( get, set ):Int;
    /**
      getter for `softnameColor`
    **/
    public function get_softnameColor():Int { return( softnameColor ); }
    /**
      setter for `softnameColor`
    **/
    public function set_softnameColor( c:Int ):Int {
      softnameColor = c;
      return( softnameColor );
    }

  /**
    font color for version: default is black
  **/
  @:isVar public var versionColor( get, set ):Int;
    /**
      getter for `versionColor`
    **/
    public function get_versionColor():Int { return( versionColor ); }
    /**
      setter for `versionColor`
    **/
    public function set_versionColor( c:Int ):Int {
      versionColor = c;
      return( versionColor );
    }

  /**
    font color for description: default is red
  **/
  @:isVar public var descriptionColor( get, set ):Int;
    /**
      getter for `descriptionColor`
    **/
    public function get_descriptionColor():Int { return( descriptionColor ); }
    /**
      setter for `descriptionColor`
    **/
    public function set_descriptionColor( c:Int ):Int {
      descriptionColor = c;
      return( descriptionColor );
    }

  /**
    font color for notice message: default is black
  **/
  @:isVar public var noticeColor( get, set ):Int;
    /**
      getter for `noticeColor`
    **/
    public function get_noticeColor():Int { return( noticeColor ); }
    /**
      setter for `noticeColor`
    **/
    public function set_noticeColor( c:Int ):Int {
      noticeColor = c;
      return( noticeColor );
    }

  /**
    font size ratio for large characters: stageWidth * `this` value is used
    as font size.  Default value is 0.05. If you set this value, you must
    invoke setFontSizeLargeByRatio function to set font size.
  **/
  @:isVar public var font_large_ratio( get, set ):Float;
    /**
      getter for `font_large_ratio`
    **/
    public function get_font_large_ratio():Float { return( font_large_ratio ); }
    /**
      setter for `font_large_ratio`
    **/
    public function set_font_large_ratio( f:Float ):Float {
      font_large_ratio = f;
      return( font_large_ratio );
    }

  /**
    font size ratio for small characters: stageWidth * `this` value is used
    as font size.  Default value is 0.03. If you set this value, you must
    invoke setFontSizeSmallByRatio function to set font size.
  **/
  @:isVar public var font_small_ratio( get, set ):Float;
    /**
      getter for `font_small_ratio`
    **/
    public function get_font_small_ratio():Float { return( font_small_ratio ); }
    /**
      setter for `font_small_ratio`
    **/
    public function set_font_small_ratio( f:Float ):Float {
      font_small_ratio = f;
      return( font_small_ratio );
    }

  /**
    margin size ratio: stageWidth * `this` value is used as the margin size.
    Default value is 0.1.
  **/
  @:isVar public var margin_ratio( get, set ):Float;
    /**
      getter for `margin_ratio`
    **/
    public function get_margin_ratio():Float { return( margin_ratio ); }
    /**
      setter for `margin_ratio`
    **/
    public function set_margin_ratio( f:Float ):Float {
      margin_ratio = f;
      return( margin_ratio );
    }

  /**
    font size for characters such as "wm3d"; using `font_large_ratio` will be
    better since that value considers the window width. See it and
    setFontSizeSmallByRatio function.
  **/
  @:isVar public var font_size_large( get, set ):Float;
    /**
      getter for `font_size_large`
    **/
    public function get_font_size_large():Float { return( font_size_large ); }
    /**
      setter for `font_size_large`
    **/
    public function set_font_size_large( f:Float ):Float {
      font_size_large = f;
      return( font_size_large );
    }

  /**
    font size for characters such as version name
  **/
  @:isVar public var font_size_small( get, set ):Float;
    /**
      getter for `font_size_small`
    **/
    public function get_font_size_small():Float { return( font_size_small ); }
    /**
      setter for `font_size_small`
    **/
    public function set_font_size_small( f:Float ):Float {
      font_size_small = f;
      return( font_size_small );
    }

  /**
    window margin size; see also `margin_ratio` and setMarginByRatio function.
  **/
  @:isVar public var margin( get, set ):Int;
    /**
      getter of `margin`
    **/
    public function get_margin():Int { return( margin ); }
    /**
      setter of `margin`
    **/
    public function set_margin( f:Int ):Int {
      margin = f;
      return( margin );
    }

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

  /**
    Constructor. You can specify a Stage where about message will be displayed
    by `win`.
  **/
  public function new( ?win:Stage = null ) {
    super();
    if ( win == null ) {
      win = flash.Lib.current.stage;
    }
    // mystage shall not be null
    mystage = win;
    this.name = "about";
    // default values
    setFontSizeLargeByRatio( 0.05 );
    setFontSizeSmallByRatio( 0.03 );
    setMarginByRatio( 0.1 );
    bgColor = 0x00FF00; // green
    bgAlpha = 0.5;
    fontname = "Arial";
    softnameColor = 0x000000; // wm3d
    versionColor = 0x000000; // version: (ver)
    descriptionColor = 0xFF0000;
    noticeColor = 0x000000; // click this window to ...
  }

  /**
    draw about message
  **/
  public function drawAbout() {
    // reset drawing
    this.graphics.clear();
    this.removeChildren();
    // reset font sizes and margin size
    resetFontSizes();
    setMarginByRatio();
    // do it
    fillBackground();
    this.addChild( __tfSoftwareName() );
    this.addChild( __tfVersion() );
    this.addChild( __tfDescription() );
    this.addChild( __tfNotice() );
    // event listener
    var refstage = this.mystage;
    if ( !this.hasEventListener( MouseEvent.CLICK ) ) {
      // commit suicide when clicked
      this.addEventListener( MouseEvent.CLICK,
                             function( e:Event ) {
                               refstage.removeChild( refstage.getChildByName( "about" ) );
                             } );
    }
    return( this );
  }

  //// software name
  private function __tfSoftwareName():TextField {
    var ret:TextField = new TextField();
    ret.y = margin * 2;
    ret.width = mystage.stageWidth;
    ret.text = "wm3d";
    ret.selectable = false;
    ret.autoSize = flash.text.TextFieldAutoSize.CENTER;
    ret.setTextFormat( new TextFormat( fontname, font_size_large, softnameColor, true, null, null, null, flash.text.TextFormatAlign.CENTER ) );
    return( ret );
  }

  //// version name
  private function __tfVersion():TextField {
    var ret:TextField = new TextField();
    ret.y = margin * 3.0;
    ret.width = mystage.stageWidth;
    ret.text = "version: " + WMVersion.version();
    ret.selectable = false;
    ret.autoSize = flash.text.TextFieldAutoSize.RIGHT;
    ret.setTextFormat( new TextFormat( fontname, font_size_small, versionColor, true, null, null, null, flash.text.TextFormatAlign.RIGHT ) );
    return( ret );
  }

  //// description about this software
  private function __tfDescription():TextField {
    var ret:TextField = new TextField();
    ret.y = margin * 4;
    ret.width = mystage.stageWidth;
    ret.text = "simple flash molecular viewer\n" +
               "written in Haxe\n" +
               "©2011-2014 tamanegi. All rights reserved.\n\n" +
               "wm3d is licensed under MPL2.0.";
    ret.selectable = false;
    ret.autoSize = flash.text.TextFieldAutoSize.CENTER;
    ret.setTextFormat( new TextFormat( fontname, font_size_small, descriptionColor, true, null, null, null, flash.text.TextFormatAlign.CENTER ) );
    return( ret );
  }

  //// notice message for users
  private function __tfNotice():TextField {
    var ret:TextField = new TextField();
    ret.y = mystage.stageHeight - 2 * margin;
    ret.width = mystage.stageWidth;
    ret.text = "click this window to remove message.";
    ret.selectable = false;
    ret.autoSize = flash.text.TextFieldAutoSize.RIGHT;
    ret.setTextFormat( new TextFormat( fontname, font_size_small, noticeColor, true, null, null, null, flash.text.TextFormatAlign.RIGHT ) );
    return( ret );
  }

  //// fill background
  private function fillBackground():Void {
    this.graphics.beginFill( bgColor, bgAlpha );
    this.graphics.drawRect( 0, margin, mystage.stageWidth, mystage.stageHeight - 2 * margin );
    this.graphics.endFill();
  }

  /**
    reset font size according to the `font_large_ratio` and `font_small_ratio`
  **/
  public function resetFontSizes():Void {
    setFontSizeLargeByRatio();
    setFontSizeSmallByRatio();
  }

  /**
    set `font_size_large` from `font_large_ratio` and stage width.
    If argument `f` is given, `f` is used as font_large_ratio.
  **/
  public function setFontSizeLargeByRatio( ?f:Float ):Void {
    if ( f != null ) {
      font_large_ratio = f;
    }
    font_size_large = mystage.stageWidth * font_large_ratio;
  }

  /**
    set `font_size_small` from `font_small_ratio` and stage width.
    If argument `f` is given, `f` is used as font_small_ratio.
  **/
  public function setFontSizeSmallByRatio( ?f:Float ):Void {
    if ( f != null ) {
      font_small_ratio = f;
    }
    font_size_small = mystage.stageWidth * font_small_ratio;
  }

  /**
    set `margin` from `margin_ratio` and stage width.
    If argument `f` is given, `f` is used as margin_ratio.
  **/
  public function setMarginByRatio( ?f:Float ):Void {
    if ( f != null ) {
      margin_ratio = f;
    }
    margin = Std.int( mystage.stageHeight * margin_ratio );
  }
}
