/*@cc_on _d=document;eval('var document=_d')@*/
/**
 * js/Mds/Button.js
 *
 * @author T.Mori <t.mori@moshimo.co.jp>
 * @package Mds
 * @version $Id$
 */

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

    /**
     * イベントハンドラを有効化
     */
    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('mds-button-active')) {
        this.$element.addClassName('mds-button-focus');
      }
    },

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

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

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

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

    /**
     * onmouseout イベント用ハンドラ
     *
     * @param Event event イベントオブジェクト
     */
    onMouseOut: function(event) {
      this.$element.removeClassName('mds-button-active');
      this.$element.removeClassName('mds-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) {
        MdsButtonFunctions.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('mds-button-focus');
      this.$element.removeClassName('mds-button-active');
      this.$element.removeClassName('mds-button-hover');
      this.$element.removeClassName('mds-button-disable');
      this.enableEventHandlers.bind(this)();
      this.enabled = true;
    },

    /**
     * ボタンを無効化する
     */
    disable: function() {
      this.$element.removeClassName('mds-button-focus');
      this.$element.removeClassName('mds-button-active');
      this.$element.removeClassName('mds-button-hover');
      this.$element.addClassName('mds-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 MdsButtonFunctions = {

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

  /**
   * すべてのボタンを非活性化する
   */
  disableAllButtons: function() {
    $$('.mds-button').each(
      function(e_button) {
        if (e_button.mds_button && e_button.mds_button.enabled) {
          e_button.mds_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', {'class': 'mds-button', 'tabindex': '0'}),
      'outer': new Element('div', {'class': 'mds-button-outer'}),
      'inner': new Element('div', {'class': 'mds-button-inner'}),
      'layout': new Element('div', {'class': 'mds-button-layout'}),
      'shadow': new Element('div', {'class': 'mds-button-shadow'}),
      'content': new Element('div', {'class': 'mds-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 mds_button = new MdsButton(e_list.base);
    mds_button.handler = handler;
    mds_button.enableEventHandlers();

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

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

};

Event.observe(
  window,
  'load',
  function() {
    $$('.mds-button').each(
      function(button) {
        var mds_button = new MdsButton(button);
        mds_button.enableEventHandlers();

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

        button.mds_button = Object.clone(mds_button);
      }
    );
    $$('form').each(
      function(form) {
        form.enableAllButtons = function() {
          this.select('.mds-button').each(
            function(button) {
              button.mds_button.enable();
            }
          );
        }.bind(form);
        form.disableAllButtons = function() {
          this.select('.mds-button').each(
            function(button) {
              button.mds_button.disable();
            }
          );
        }.bind(form);
        form.observe(
          'submit',
          function(event) {
            MdsButtonFunctions.disableAllButtons();
          }.bind(form)
        );
        form.observe(
          'mds:submit',
          function(event) {
            MdsButtonFunctions.disableAllButtons();
            this.submit();
          }.bind(form)
        );
      }
    );
  }
);
Event.observe(
  window,
  'focus',
  function() {
    MdsButtonFunctions.enableAllButtons();
  }
);

Mds_Globals.mds_button_behavior = {
  enable_all: false,
  disable_all: false
};

