/*@cc_on
if (@_jscript_version < 9) {
    var _d = document;
    eval("var document = _d");
}
@*/
/**
 * js/Mdk/Button.js
 *
 * @author T.Mori <t.mori@moshimo.co.jp>
 * @package Mdk
 * @version $Id$
 */

/**
 * Mdk のボタンクラス
 *
 * @author T.Mori <t.mori@moshimo.co.jp>
 * @package Mdk
 * @access public
 */
var Mdk_Button = Class.create(
  Mdk,
  {

    /**
     * イベントハンドラを有効化
     */
    enableEventHandlers: function() {
      this.$element.observe('focus', this.handlers.focus);
      this.$element.observe('blur', this.handlers.blur);
      this.$element.observe('keydown', this.handlers.keydown);
      this.$element.observe('click', this.handlers.click);
      this.$element.observe('mousedown', this.handlers.mousedown);
      this.$element.observe('mouseup', this.handlers.mouseup);
      this.$element.observe('mouseover', this.handlers.mouseover);
      this.$element.observe('mouseout', this.handlers.mouseout);
    },

    /**
     * イベントハンドラを無効化
     */
    disableEventHandlers: function() {
      this.$element.stopObserving('focus');
      this.$element.stopObserving('blur');
      this.$element.stopObserving('keydown');
      this.$element.stopObserving('click');
      this.$element.stopObserving('mousedown');
      this.$element.stopObserving('mouseup');
      this.$element.stopObserving('mouseover');
      this.$element.stopObserving('mouseout');
    },

    /**
     * onfocus イベント用ハンドラ
     *
     * @param Event event イベントオブジェクト
     */
    onFocus: function(event) {
      if (!this.$element.hasClassName('mdk-button-active')) {
        this.$element.addClassName('mdk-button-focus');
      }
    },

    /**
     * onblur イベント用ハンドラ
     *
     * @param Event event イベントオブジェクト
     */
    onBlur: function(event) {
      this.$element.removeClassName('mdk-button-focus');
    },

    /**
     * onmousedown イベント用ハンドラ
     *
     * @param Event event イベントオブジェクト
     */
    onMouseDown: function(event) {
      this.$element.removeClassName('mdk-button-focus');
      this.$element.addClassName('mdk-button-active');
    },

    /**
     * onmouseup イベント用ハンドラ
     *
     * @param Event event イベントオブジェクト
     */
    onMouseUp: function(event) {
      this.$element.removeClassName('mdk-button-active');
    },

    /**
     * onmouseover イベント用ハンドラ
     *
     * @param Event event イベントオブジェクト
     */
    onMouseOver: function(event) {
      this.$element.removeClassName('mdk-button-active');
      this.$element.addClassName('mdk-button-hover');
    },

    /**
     * onmouseout イベント用ハンドラ
     *
     * @param Event event イベントオブジェクト
     */
    onMouseOut: function(event) {
      this.$element.removeClassName('mdk-button-active');
      this.$element.removeClassName('mdk-button-hover');
    },

    /**
     * onkeydown イベント用ハンドラ
     *
     * @param Event event イベントオブジェクト
     */
    onKeyDown: function(event) {
      if (event.keyCode != 13 && event.keyCode != 32) {
        return;
      }
      setTimeout(this.onMouseDown.curry(event).bind(this), 10);
      setTimeout(this.onMouseUp.curry(event).bind(this), 100);
      setTimeout(this.onClick.curry(event).bind(this), 50);
    },

    /**
     * onkeydown イベント用ハンドラ
     *
     * @param Event event イベントオブジェクト
     */
    onClick: function(event) {
      var rev = this.$element.readAttribute('rev') || '';
      if (!rev) {
        Mdk_ButtonFunctions.disableAllButtons();
      }
      if (rev.match(/lock/)) {
        this.disable();
      }
      if (rev.match(/reset/)) {
        // Do Nothing.
      }
      if (Object.isUndefined(this.handler)) {
        var handler = this.$element.readAttribute('rel');
        eval(handler);
      } else {
        this.handler();
      }
    },

    /**
     * ボタンを有効化する
     */
    enable: function() {
      this.$element.removeClassName('mdk-button-focus');
      this.$element.removeClassName('mdk-button-active');
      this.$element.removeClassName('mdk-button-hover');
      this.$element.removeClassName('mdk-button-disable');
      this.enableEventHandlers.bind(this)();
      this.enabled = true;
    },

    /**
     * ボタンを無効化する
     */
    disable: function() {
      this.$element.removeClassName('mdk-button-focus');
      this.$element.removeClassName('mdk-button-active');
      this.$element.removeClassName('mdk-button-hover');
      this.$element.addClassName('mdk-button-disable');
      this.disableEventHandlers.bind(this)();
      this.enabled = false;
    },

    /**
     * コンストラクタ
     *   要素をメンバ変数に保持
     *   イベントハンドラの準備を行う
     *
     * @param Function $super 親クラスのコンストラクタ
     * @param Element $element 対象要素
     */
    initialize: function($super, $element) {
      $super();
      this.$element = $element;
      this.handlers = {
        focus: this.onFocus.bind(this),
        blur: this.onBlur.bind(this),
        keydown: this.onKeyDown.bind(this),
        click: this.onClick.bind(this),
        mousedown: this.onMouseDown.bind(this),
        mouseup: this.onMouseUp.bind(this),
        mouseover: this.onMouseOver.bind(this),
        mouseout: this.onMouseOut.bind(this)
      };
      this.enabled = true;
      this.lock = false;
      var rev = this.$element.readAttribute('rev') || '';
      if (rev.match(/lock/)) {
        this.lock = true;
      }
    }

  }
);

var Mdk_ButtonFunctions = {

  /**
   * すべてのボタンを活性化する
   */
  enableAllButtons: function() {
    $$('.mdk-button').each(
      function(e_button) {
        if (e_button.mdk_button && !e_button.mdk_button.enabled) {
          var rev = e_button.mdk_button.$element.readAttribute('rev');
          if (!e_button.mdk_button.lock && (!rev || !rev.match(/disabled/))) {
            e_button.mdk_button.enable();
          }
        }
      }
    );
  },

  /**
   * すべてのボタンを非活性化する
   */
  disableAllButtons: function() {
    $$('.mdk-button').each(
      function(e_button) {
        if (e_button.mdk_button && e_button.mdk_button.enabled) {
          e_button.mdk_button.disable();
        }
      }
    );
  },

  /**
   * ボタンを生成する
   *
   * @param String text ボタン文字列
   * @param mixed 実行ハンドラ
   * @param Object オプション
   * @return Element 生成したボタン要素
   */
  createButton: function(text, handler, options) {
    options = options || {};
    var e_list = {
      'base': new Element('div', {'tabindex': '0'}),
      'outer': new Element('div'),
      'inner': new Element('div'),
      'layout': new Element('div'),
      'shadow': new Element('div'),
      'content': new Element('div')
    };

    e_list.base.addClassName('mdk-button');
    e_list.outer.addClassName('mdk-button-outer');
    e_list.inner.addClassName('mdk-button-inner');
    e_list.layout.addClassName('mdk-button-layout');
    e_list.shadow.addClassName('mdk-button-shadow');
    e_list.content.addClassName('mdk-button-content');

    e_list.shadow.update('&nbsp;');
    e_list.content.update(text);
    if (options.id) {
      e_list.base.writeAttribute('id', options.id);
    }
    if (options.rev) {
      e_list.base.writeAttribute('rev', options.rev);
    }
    if (options.title) {
      e_list.base.writeAttribute('title', options.title);
    }
    if (options.style) {
      e_list.base.writeAttribute('style', options.style);
    }
    if (options.content_style) {
      e_list.content.writeAttribute('style', options.content_style);
    }
    e_list.layout.insert({bottom: e_list.shadow});
    e_list.layout.insert({bottom: e_list.content});
    e_list.inner.insert({bottom: e_list.layout});
    e_list.outer.insert({bottom: e_list.inner});
    e_list.base.insert({bottom: e_list.outer});

    var mdk_button = new Mdk_Button(e_list.base);
    mdk_button.handler = handler;
    mdk_button.enableEventHandlers();

    var rev = mdk_button.$element.readAttribute('rev');
    if (rev && rev.match(/disabled/)) {
      mdk_button.disable();
    }

    e_list.base.mdk_button = Object.clone(mdk_button);
    return e_list.base;
  }

};

Event.observe(
  window,
  'load',
  function() {
    $$('.mdk-button').each(
      function(button) {
        var mdk_button = new Mdk_Button(button);
        mdk_button.enableEventHandlers();

        var rev = mdk_button.$element.readAttribute('rev');
        if (rev && rev.match(/disabled/)) {
          mdk_button.disable();
        }

        button.mdk_button = Object.clone(mdk_button);
      }
    );
    $$('form').each(
      function(form) {
        form.enableAllButtons = function() {
          this.select('.mdk-button').each(
            function(button) {
              button.mdk_button.enable();
            }
          );
        }.bind(form);
        form.disableAllButtons = function() {
          this.select('.mdk-button').each(
            function(button) {
              button.mdk_button.disable();
            }
          );
        }.bind(form);
        form.observe(
          'submit',
          function(event) {
            if (!(new String(this.readAttribute('rev'))).match(/no-disable-buttons/)) {
              Mdk_ButtonFunctions.disableAllButtons();
            }
          }.bind(form)
        );
        form.observe(
          'mdk:submit',
          function(event) {
            Mdk_ButtonFunctions.disableAllButtons();
          }.bind(form)
        );
      }
    );
  }
);
Event.observe(
  window,
  'focus',
  function() {
    Mdk_ButtonFunctions.enableAllButtons();
  }
);

Mdk_Globals.mdk_button_behavior = {
  enable_all: false,
  disable_all: false
};


