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

/**
 * Mds の既定クラス
 *
 *   $ で始まる変数は Element を継承したオブジェクトを表現します
 *   $event は例外的に Event を継承したオブジェクトを表現します
 *
 * @author T.Mori <t.mori@moshimo.co.jp>
 * @package Mds
 * @access public
 */
var Mds = Class.create(
  {

    /**
     * 確認ダイアログを出してからフォームを送信する
     *
     * @deprecated
     * @param Form $form フォーム要素 (フォームの ID も可)
     * @param String message 確認メッセージ
     */
    confirm: function ($form, message) {
      message = message || "実行しますか？";
      if (confirm(message)) {
        this.submit($form);
      }
    },

    /**
     * フォームを送信する
     *
     * @deprecated
     * @param Form $form フォーム要素 (フォームの ID も可)
     */
    submit: function ($form) {
      var $form = $($form);
      $form.submit();
    },

    /**
     * リダイレクトする
     *
     * @deprecated
     * @param String action_name アクション名 (アンダースコア記法)
     */
    redirect: function (action_name) {
      var absolute_path = "/" + action_name.gsub(/_/, '/');
      location.href = location.protocol + '//' + location.host + _variables.path_prefix + absolute_path;
    },

    /**
     * 画面をポップアップさせる
     *
     * @deprecated
     * @param String action_name アクション名
     * @param String path_prefix パスプレフィックス
     */
    popup: function (action_name, path_prefix) {
      if (Object.isUndefined(path_prefix)) {
        path_prefix = _variables.path_prefix;
      }
      var absolute_path = "/" + action_name.gsub(/_/, '/');
      var full_path = location.protocol + '//' + location.host + path_prefix + absolute_path;
      window.open(full_path);
    },

    /**
     * Ajax なリクエストを送信する
     *
     * @deprecated
     * @param Form $form フォーム要素
     * @param Function callback コールバックメソッド
     */
    request: function ($form, callback, options) {
      options = Object.extend(
        {
          onSuccess: function (response) {
            callback(response, $form);
          }
        },
        options || {}
      );
      $form = $($form);
      // post じゃないと IE で重複送信が出来ない
      $form.request(
        options
      );
    },

    // {{{ tooltip
    /** @var Object ツールチップに関するオブジェクト */
    tooltip: {

      // {{{ variables

      /** @var Boolean 表示中かどうか */
      displaying: false,

      /** @var Boolean ロック中かどうか */
      locked: false,

      /** @var mixed 表示するコンテンツ */
      contents: undefined,

      // }}}

      /**
       * ツールチップを開く
       *
       * @deprecated
       * @param Event e イベントオブジェクト
       * @param String contents 表示する文字列 (HTML 可)
       */
      open: function(e, contents) {
        if (this.locked) {
          return;
        }
        if (this.displaying) {
          if (this.contents != contents) {
            this.close();
            this.contents = undefined;
            this.displaying = false;
          } else {
            this.update(e);
            return;
          }
        }
        // {{{ create iframe
        if (Prototype.Browser.IE) {
          var iframe = new Element(
            'iframe',
            {
              id: "_tooltip_iframe",
              src: "javascript: false;",
              frameborder: "0"
            }
          );
        } else {
          var iframe = new Element(
            'iframe',
            {
              id: "_tooltip_iframe",
              frameborder: "0"
            }
          );
        }
        // }}}
        // {{{ create base
        var base = new Element(
          'div',
          {
            id: "_tooltip_base"
          }
        );
        base.addClassName('tooltip');
        // }}}
        // {{{ 位置を計算
        var left = e.pointerX() + 5;
        if (left < 0) {
          left = 0;
        }
        var top = e.pointerY() + 5;
        if (top < 0) {
          top = 0;
        }
        // }}}
        // {{{ iframe style setting
        iframe.setStyle(
          {
            position  : 'absolute',
            left      : left + 'px',
            top       : top + 'px',
            zIndex    : '30',
            padding   : "0px",
            margin    : "0px",
            border    : "none"
          }
        );
        // }}}
        // {{{ base style setting
        base.setStyle(
          {
            position  : 'absolute',
            left      : left + 'px',
            top       : top + 'px',
            padding   : '3px',
            textAlign : 'left',
            backgroundColor: '#ffffff',
            border    : 'solid 1px #888888',
            zIndex    : '40'
          }
        );
        base.update(contents);
        // }}}
        $('container').insert({after: iframe});
        $('container').insert({after: base});
        // {{{ iframe style setting
        iframe.setStyle(
          {
            width     : base.getWidth() + "px",
            height    : base.getHeight() + "px"
          }
        );
        // }}}
        this.width = base.getWidth();
        this.height = base.getHeight();
        this.contents = contents;
        this.displaying = true;
      },

      /**
       * 位置を更新する
       *
       * @param Event e イベントオブジェクト
       */
      update: function(e) {
        // {{{ 位置を計算
        var left = e.pointerX() + 5;
        if (left < 0) {
          left = 0;
        }
        var top = e.pointerY() + 5;
        if (top < 0) {
          top = 0;
        }
        // }}}
        // {{{ iframe style setting
        if ($('_tooltip_iframe')) {
          $('_tooltip_iframe').setStyle(
            {
              left      : left + 'px',
              top       : top + 'px'
            }
          );
        }
        // }}}
        // {{{ base style setting
        if ($('_tooltip_base')) {
          $('_tooltip_base').setStyle(
            {
              left      : left + 'px',
              top       : top + 'px'
            }
          );
        }
        // }}}
      },

      /**
       * ツールチップを閉じる
       */
      close: function() {
        if ($('_tooltip_iframe')) {
          $('_tooltip_iframe').remove();
        }
        if ($('_tooltip_base')) {
          $('_tooltip_base').remove();
        }
        this.contents = undefined;
        this.displaying = false;
      },

      /**
       * ロックする
       */
      lock: function() {
        this.locked = true;
      },

      /**
       * ロックを解除する
       */
      unlock: function() {
        this.locked = false;
      }

    },
    // }}}

    // {{{ loading
    /** @var Object 読み込み中画像に関するオブジェクト */
    loading: {

      /**
       * now-loading 画像を生成する
       */
      create: function() {
        var div = new Element('div', {"id": "now-loading"});
        var p_img = new Element('p');
        var p_text = new Element('p');
        var img = new Element('img', {"src": "/images/common/now-loading.gif", "width": "48", "height": "48"});
        var span_base = new Element('span', {"id": "now-loading-text-base"});
        var span_dot = new Element('span', {"id": "now-loading-text-dot"});
        p_img.addClassName('inline-center');
        p_img.insert({bottom: img});
        div.insert({bottom: p_img});
        span_base.update('Now Loading');
        var dot_interval = setInterval(
          function() {
            var text = this.innerHTML;
            if (text.length >= 5) {
              text = ".";
            } else {
              text += ".";
            }
            this.update(text);
          }.bind(span_dot),
          300
        );
        p_text.addClassName('inline-left');
        p_text.setStyle({padding: "5px", width: "8em", margin: "0px auto"});
        p_text.insert({bottom: span_base});
        p_text.insert({bottom: span_dot});
        div.insert({bottom: p_text});
        div.dot_interval = dot_interval;
        return div;
      },

      /**
       * now-loading 画像を除去する
       */
      remove: function() {
        if ($('now-loading')) {
          if ($('now-loading').dot_interval) {
            clearInterval($('now-loading').dot_interval);
          }
          $('now-loading').remove();
        }
      }

    },
    // }}}

    // {{{ form
    /** @var Object <form ...> 関連のオブジェクト */
    form: {

      /**
       * 確認ダイアログを出してからフォームを送信する
       *
       * @param Form $form フォーム要素 (フォームの ID も可)
       * @param String message 確認メッセージ
       */
      confirm: function ($form, message) {
        message = message || "実行しますか？";
        if (confirm(message)) {
          this.submit($form);
        }
      },

      /**
       * フォームを送信する
       *
       * @param Form $form フォーム要素 (フォームの ID も可)
       */
      submit: function ($form) {
        var $form = $($form);
        $form.submit();
      },

      /**
       * Ajax なリクエストを送信する
       *
       * @param Form $form フォーム要素
       * @param Function callback コールバックメソッド
       */
      request: function ($form, callback, options) {
        options = Object.extend(
          {
            onSuccess: function (response) {
              callback(response, $form);
            }
          },
          options || {}
        );
        $form = $($form);
        // post じゃないと IE で重複送信が出来ない
        $form.request(
          options
        );
      },

      // {{{ input
      /** @var Object <input ...> 関連のオブジェクト */
      input: {

        // {{{ checkbox
        /** @var Object <input type="checkbox" ...> 関連のオブジェクト */
        checkbox: {

          /**
           * チェックボックスを全てチェックする
           *
           * @param Array $elements checkbox の要素を含む配列
           */
          checkAll: function ($elements) {
            $elements.each(
              function ($element) {
                var call = false;
                if (!$element.checked) {
                  call = true;
                }
                if ($element.tagName.toLowerCase() == 'input' && $element.readAttribute('type') == 'checkbox' && !$element.disabled) {
                  $element.checked = 1;
                }
                if (call) {
                  $element.fire('mds:change');
                }
              }
            );
          },

          /**
           * チェックボックスを全てチェック解除する
           *
           * @param Array $elements checkbox の要素を含む配列
           */
          releaseAll: function ($elements) {
            if (!Object.isArray($elements)) {
              return;
            }
            $elements.each(
              function ($element) {
                var call = false;
                if ($element.checked) {
                  call = true;
                }
                if ($element.tagName.toLowerCase() == 'input' && $element.readAttribute('type') == 'checkbox') {
                  $element.checked = 0;
                }
                if (call) {
                  $element.fire('mds:change');
                }
              }
            );
          },

          /**
           * チェックが付いているチェックボックスの個数をカウントする
           *
           * @param Array $elements checkbox の要素を含む配列
           * @return Integer チェックが付いているチェックボックスの個数
           */
          countChecked: function ($elements) {
            if (!Object.isArray($elements)) {
              return;
            }
            var counter = 0;
            $elements.each(
              function ($element) {
                if ($element.tagName.toLowerCase() == 'input' && $element.readAttribute('type') == 'checkbox' && $element.checked) {
                  counter++;
                }
              }
            );
            return counter;
          }

        }
        // }}}

      },
      // }}}

      /**
       * ダミーフォームを生成する
       *
       * @return String 生成したフォームの ID
       */
      createDummy: function(action, parameters) {
        var $form = new Element('form');
        var form_id = $form.identify();
        $form.writeAttribute('action', action);
        $form.writeAttribute('mthod', 'post');
        if (parameters) {
          $H(parameters).each(
            function(parameter) {
              var $input = new Element('input');
              $input.writeAttribute('type', 'hidden');
              $input.writeAttribute('name', parameter.key);
              $input.writeAttribute('value', parameter.value);
              $form.insert({bottom: $input});
            }
          );
        }
        $$('body')[0].insert({bottom: $form});
        return form_id;
      },
      // }}}

      // {{{ suggestText
      /**
       * サジェストするためのテキストをフォームに表示する
       *
       * @param Element $element フォームの INPUT TEXT
       * @param Object  options   オプション
       */
      suggestText: function($element) {

          var options = Object.extend({
            attribute:     'suggest',
            suggest_color: '#AAAAAA',
            normal_color:  '#000000',
            remove: true,
            remove_onsubmit: true
          }, arguments[1] || {});

          var suggest_forcus = function(onsubmit) {
            if($element.value == $element.readAttribute(options.attribute)){
              if((onsubmit && options.remove_onsubmit) || (!onsubmit && options.remove)) {
                $element.value="";
              }
              $element.setStyle({'color': options.normal_color});
            }
          }

          var suggest_blur = function() {
            if($element.value == "" || (!options.remove && $element.value == $element.readAttribute(options.attribute))) {
              $element.setStyle({'color': options.suggest_color});
              $element.value=$element.readAttribute(options.attribute);
            }
          }

          Event.observe($element, 'focus', suggest_forcus.bind(this, false));
          Event.observe($element, 'blur', suggest_blur.bind(this));
          Event.observe($element.up('form'), 'submit', suggest_forcus.bind(this, true));
          suggest_blur.bind(this)();
          
          return $element;
      }
    },
    // }}}

    // {{{ window
    /** @var Object 画面関連のオブジェクト */
    window: {

      /**
       * リダイレクトする
       *
       * @param String action_name アクション名 (アンダースコア記法)
       */
      redirect: function (action_name) {
        var absolute_path = "/" + action_name.gsub(/_/, '/');
        location.href = location.protocol + '//' + location.host + _variables.path_prefix + absolute_path;
      },

      /**
       * 画面をポップアップさせる
       *
       * @param String action_name アクション名
       * @param String path_prefix パスプレフィックス
       */
      open: function (action_name, path_prefix) {
        if (Object.isUndefined(path_prefix)) {
          path_prefix = _variables.path_prefix;
        }
        var absolute_path = "/" + action_name.gsub(/_/, '/');
        var full_path = location.protocol + '//' + location.host + path_prefix + absolute_path;
        window.open(full_path);
      },

      // {{{ popup
      /**
       * @var Object ポップアップウィンドウ制御オブジェクト
       */
      popup: {

        // {{{ variables

        /** @var Element 表示する要素 */
        $element: undefined,

        /** @var Element ポップアップさせる箱 */
        base: undefined,

        /** @var Element IE 用に覆い隠すための iframe */
        iframe: undefined,

        /** @var Element 表示要素を格納する div */
        div: undefined,

        // }}}

        /**
         * ポップアップウィンドウを開く
         *
         * @param Event $event イベントオブジェクト
         * @param Element $element 表示させる要素
         */
        open: function($event, $element) {
          var base, iframe, div;
          this.$element = $element;
          this.base = base;
          this.iframe = iframe;
          this.div = div;
          this.close();
          // {{{ 箱の構築
          this.base = new Element(
            'div',
            {
              id: "mds-popup-base"
            }
          );
          // }}}
          // {{{ iframe の構築
          this.iframe = new Element(
            'iframe',
            {
              id: "mds-popup-iframe",
              src: "/images/spacer.gif",
              frameborder: "0"
            }
          );
          // }}}
          // {{{ div の構築
          this.div = new Element(
            'div',
            {
              id: "mds-popup-div"
            }
          );
          // }}}
          this.div.insert({bottom: this.$element});
          // {{{ 箱の style を設定
          this.base.setStyle(
            {
              display   : "none",
              position  : 'absolute',
              zIndex    : '5',
              padding   : 0,
              margin    : 0,
              border    : "none"
            }
          );
          // }}}
          // {{{ iframe の style を設定
          this.iframe.setStyle(
            {
              position  : 'absolute',
              zIndex    : '10',
              padding   : "0px",
              margin    : "0px",
              border    : "none"
            }
          );
          // }}}
          // {{{ div の style を設定
          this.div.setStyle(
            {
              position  : 'absolute',
              zIndex    : '20',
              textAlign : 'center'
            }
          );
          // }}}
          this.base.insert({bottom: this.iframe});
          this.base.insert({bottom: this.div});
          $('container').insert({bottom: this.base});
          // {{{ 箱のエフェクト処理
          Effect.Appear(
            this.base,
            {
              duration: 0.5,
              delay: 0.25,
              afterFinishInternal: function() {
                this.base.show();
                this.updateSize();
                this.updatePosition();
              }.bind(this)
            }
          );
          new Draggable('mds-popup-base');
          // }}}
        },

        /**
         * ポップアップウィンドウを閉じる
         */
        close: function () {
          if (!this.base) {
            return;
          }
          Effect.Fade(
            this.base,
            {
              duration: 0.5,
              delay: 0.25,
              afterFinishInternal: function() {
                this.base.remove();
              }.bind(this)
            }
          );
        },

        /**
         * 位置を更新する
         *
         * @param Number left 横位置
         * @param Number top 縦位置
         */
        updatePosition: function(left, top) {
          if (!this.base) {
            return;
          }
          if (!left) {
            left = document.viewport.getScrollOffsets().left + (document.viewport.getDimensions().width / 2) - (this.$element.getWidth() / 2);
          }
          if (!top) {
            top = document.viewport.getScrollOffsets().top + (document.viewport.getDimensions().height / 2) - (this.$element.getHeight() / 2);
          }
          if (Prototype.Browser.IE) {
            left = left - $('container').positionedOffset().left;
            top = top - $('container').positionedOffset().top;
          }
          this.base.setStyle({left: left + 'px', top: top + 'px'});
          //this.iframe.setStyle({left: left + 'px', top: top + 'px'});
          //this.div.setStyle({left: left + 'px', top: top + 'px'});
        },

        /**
         * サイズを更新する
         *
         * @param Number width 横幅
         * @param Number height 縦幅
         */
        updateSize: function(width, height) {
          if (!this.base) {
            return;
          }
          width = width || this.$element.getWidth();
          height = height || this.$element.getHeight();
          this.base.setStyle({width: width + 'px', height: height + 'px'});
          this.iframe.setStyle({width: width + 'px', height: height + 'px'});
          this.div.setStyle({width: width + 'px', height: height + 'px'});
        }

      },
      // }}}

      // {{{ Alert
      /** @var Object 通知領域制御オブジェクト */
      Alert: Class.create(

        {

          // {{{ static variables
          /**
           * @var Object static 変数を格納するオブジェクト
           * @static
           */
          Statics: {

            /** @var Number 表示オブジェクトのインデックス */
            index: 0,

            /** @var Number 表示しているオブジェクトの数 */
            displayed_number: 0,

            /** @var Number 表示オブジェクトの高さ合計 */
            composited_height: 0

          },
          // }}}

          /**
           * 実際に表示する
           */
          show: function() {
            // {{{ 要素の構築
            this.Statics.index++;
            this.base = new Element(
              'div',
              {
                id: 'mds-alert-base-' + this.Statics.index
              }
            );
            if (Prototype.Browser.IE) {
              this.iframe = new Element(
                'iframe',
                {
                  id: 'mds-alert-iframe' + this.Statics.index,
                  src: '/images/spacer.gif',
                  frameborder: "0"
                }
              );
            }
            this.div = new Element(
              'div',
              {
                id: 'mds-alert-div-' + this.Statics.index
              }
            );
            // }}}

            // {{{ 中身をセット
            this.div.insert({bottom: this.$element});
            // }}}

            // {{{ style を設定
            var position = 'fixed';
            if (Prototype.Browser.IE) {
              position = 'absolute';
            }
            this.base.setStyle(
              {
                display: 'none',
                position: position,
                zIndex: 105,
                padding: 0,
                margin: 0,
                border: "none"
              }
            );
            if (Prototype.Browser.IE) {
              this.iframe.setStyle(
                {
                  position: position,
                  zIndex: 110,
                  padding: 0,
                  margin: 0,
                  border: "none"
                }
              );
            }
            this.div.setStyle(
              {
                position: position,
                zIndex: 120,
                border: 'solid 1px #aaaaaa',
                backgroundColor: '#ffff00'
              }
            );
            // }}}

            // {{{ 要素を追加
            if (Prototype.Browser.IE) {
              this.base.insert({bottom: this.iframe});
            }
            this.base.insert({bottom: this.div});
            $('container').insert({bottom: this.base});
            // }}}
            // {{{ エフェクトを設定
            new Effect.Parallel(
              [
                Effect.Appear(
                  this.base,
                  {
                    duration: 0.5,
                    beforeStartInternal: function() {
                      this.Statics.displayed_number++;
                      this.base.setOpacity(0.1);
                      this.base.show();
                      this.updateSize();
                      this.updatePosition();
                    }.bind(this)
                  }
                ),
                Effect.Fade(
                  this.base,
                  {
                    duration: 1,
                    delay: 3,
                    afterFinishInternal: function() {
                      this.div.hide();
                      if (Prototype.Browser.IE) {
                        this.iframe.hide();
                      }
                      this.base.hide();
                      this.Statics.displayed_number--;
                      if (this.Statics.displayed_number <= 0) {
                        this.Statics.composited_height = 0;
                      }
                    }.bind(this)
                  }
                )
              ],
              {delay: 3}
            );
            // }}}
          },

          /**
           * 位置を更新する
           *
           * @param Number left 横位置
           * @param Number top 縦位置
           */
          updatePosition: function(left, top) {
            if (!this.base) {
              return;
            }
            if (!left) {
              left = document.viewport.getScrollOffsets().left + document.viewport.getDimensions().width - this.$element.getWidth() - 2;
            }
            if (!top) {
              //top = document.viewport.getScrollOffsets().top + this.Statics.composited_height;
              top = this.Statics.composited_height;
            }
            this.Statics.composited_height += this.$element.getHeight();
            if (Prototype.Browser.IE) {
              this.base.setStyle({left: 'expression((document.viewport.getScrollOffsets().left + ' + left + ') + \'px\')', top: 'expression((document.viewport.getScrollOffsets().top + ' + top + ') + \'px\')'});
            } else {
              this.base.setStyle({left: left + 'px', top: top + 'px'});
            }
          },

          /**
           * サイズを更新する
           *
           * @param Number width 横幅
           * @param Number height 縦幅
           */
          updateSize: function(width, height) {
            if (!this.base) {
              return;
            }
            width = width || this.$element.getWidth();
            height = height || this.$element.getHeight();

            this.base.setStyle({width: width + 'px', height: height + 'px'});
            if (Prototype.Browser.IE) {
              this.iframe.setStyle({width: width + 'px', height: height + 'px'});
            }
            this.div.setStyle({width: width + 'px', height: height + 'px'});
          },

          /**
           * コンストラクタ
           */
          initialize: function($element) {
            var div = new Element('div');
            if (Object.isString($element)) {
              div.update($element);
            } else {
              div.insert({bottom: $element});
            }
            div.setStyle({padding: '5px 10px', whiteSpace: 'nowrap'});
            this.$element = div;
            this.show();
          }

        }
      ),
      // }}}

      /**
       * ツールチップを開く
       *
       * @param Event e イベントオブジェクト
       * @param String contents 表示する文字列 (HTML 可)
       */
      tooltip: function(e, contents) {
        if (this.tooltip_window) {
          Windows.close(this.tooltip_window.getId());
        }
        if (contents === false) {
          return;
        }
        this.tooltip_window = new Window(
          {
            className: 'lighting',
            left: e.pointerX() + 5,
            top: e.pointerY() + 5,
            resizable: false,
            closable: false,
            minimizable: false,
            maximizable: false,
            draggable: false,
            showEffect: Element.show,
            hideEffect: Element.hide,
            destroyOnClose: true
          }
        );
        var div = new Element('div');
        div.setStyle(
          {
            backgroundColor: '#ffffff',
            border: 'solid 1px #888888',
            padding: '3px',
            textAlign: 'left'
          }
        );
        div.addClassName('tooltip');
        div.update(contents);
        this.tooltip_window.getContent().insert({bottom: div});
        this.tooltip_window.show();
      }

    },
    // }}}

    /**
     * コンストラクタ
     */
    initialize: function() {
    }

  }
);

/**
 * Exception クラス
 *
 * @author T.Mori
 */
var Mds_Exception = Class.create(
  {

    /**
     * コンソール出力時の文字列表現
     *
     * @return String 出力文字列
     */
    toString: function() {
      return this.name + ': "' + this.message + '"';
    },

    /**
     * コンストラクタ
     *
     * @param String message 例外メッセージ
     */
    initialize: function(message) {
      this.message = message;
      this.name = 'Mds_Exception';
    }

  }
);

var Mds_Util = {

    // {{{ ClearElement
    ClearElement: function() {
      var e_div = new Element('div');
      e_div.addClassName('clear-both');
      e_div.update('&nbsp;');
      return e_div;
    },
    // }}}

    CreateWindow: function(event, e_target, e_dummy_parent, x, y, z_index) {
      var e_div, e_iframe, e_dummy, left, top, width, height;
      e_div = new Element('div');
      if (Prototype.Browser.IE) {
        e_iframe = new Element('iframe', {frameborder: 0, src: 'javascript: false;'});
      }
      e_dummy = e_target.cloneNode(true);
      z_index = z_index || 0;

      var e_parent = e_dummy_parent ? $(e_dummy_parent) : $$('body')[0];
      var parent_position = e_parent.getStyle('position');
      e_parent.setStyle({position: 'relative'});
      e_dummy.setStyle({position: 'absolute', top: 0, left: 0});
      e_dummy.setOpacity(0);
      e_parent.insert({top: e_dummy});
      width = e_dummy.getWidth();
      height = e_dummy.getHeight();
      left = event.pointerX();
      top = event.pointerY();
      if (x == 'right') {
        left = left - width - 15;
      }
      if (y == 'bottom') {
        top = top - height - 15;
      }
      e_dummy.remove();
      e_parent.setStyle({position: parent_position});

      if (Prototype.Browser.IE) {
        e_iframe.setStyle(
          {
            width     : width + "px",
            height    : height + "px",
            position  : 'absolute',
            color     : '#ffffff',
            left      : left + "px",
            top       : top + "px",
            zIndex    : parseInt(z_index) + 10,
            padding   : 0,
            margin    : 0,
            border    : "none"
          }
        );
      }
      e_div.setStyle(
        {
          position  : 'absolute',
          zIndex    : parseInt(z_index) + 20,
          left      : left + "px",
          top       : top + "px",
          padding   : 0,
          margin    : 0,
          border    : "none"
        }
      );
      e_div.insert({bottom: e_target});
      e_target.removeAttribute('id');
      return {element: e_div, iframe: e_iframe};
    },

    SwitchImage: function() {
      $$('img.mds-switch-image').each(
        function(e_img) {
          e_img.observe(
            'mouseover',
            function() {
              this.writeAttribute('src', this.readAttribute('src').gsub(/(-mouseover)?(\.[a-zA-Z0-9]+)$/, '-mouseover#{2}'));
            }.bind(e_img)
          );
          e_img.observe(
            'mouseout',
            function() {
              this.writeAttribute('src', this.readAttribute('src').gsub(/(-mouseover)?(\.[a-zA-Z0-9]+)$/, '#{2}'));
            }.bind(e_img)
          );
        }
      );
    }

};

var Mds_Induce = Class.create(
  {

    focus: function() {
      if (this.element.getValue() == this.induce_message) {
        this.element.setValue('');
      }
      this.element.removeClassName('silver');
    },

    blur: function() {
      if (this.element.getValue() === '' || this.element.getValue() == this.induce_message) {
        this.element.addClassName('silver');
        this.element.setValue(this.induce_message);
      }
    },

    submit: function() {
      if (this.element.getValue() == this.induce_message) {
        this.element.setValue('');
      }
    },

    initialize: function(element, induce_message) {
      this.element = $(element);
      this.induce_message = induce_message;
      this.element.observe('focus', this.focus.bind(this));
      this.element.observe('blur', this.blur.bind(this));
      this.element.up('form').observe('submit', this.submit.bind(this));
      this.element.up('form').observe('mds:submit', this.submit.bind(this));
      this.element.mds_induce = this;
    }

  }
);

var Mds_Tooltip = Class.create(
  {

    show: function(event) {
      this.o_tooltip = Mds_Util.CreateWindow(event, this.e_tooltip, false, 'left', 'bottom', 10000);
      if (Object.isElement(this.o_tooltip.element)) {
        this.o_tooltip.element.addClassName('mds-tooltip');
        this.o_tooltip.element.addClassName('inline-left');
        $$('body')[0].insert({bottom: this.o_tooltip.element});
      }
      if (Object.isElement(this.o_tooltip.iframe)) {
        $$('body')[0].insert({bottom: this.o_tooltip.iframe});
      }
      this.hide_timer = setTimeout(this.hide.bindAsEventListener(this), this.display_second * 1000);
    },

    hide: function(event) {
      if (Object.isUndefined(this.o_tooltip)) {
        return;
      }
      if (Object.isElement(this.o_tooltip.element)) {
        this.o_tooltip.element.remove();
        this.o_tooltip.element = undefined;
      }
      if (Object.isElement(this.o_tooltip.iframe)) {
        this.o_tooltip.iframe.remove();
        this.o_tooltip.iframe = undefined;
      }
      this.o_tooltip = undefined;
      if (!Object.isUndefined(this.hide_timer)) {
        clearTimeout(this.hide_timer);
      }
      this.hide_timer = undefined;
    },

    update: function(event) {
      if (Object.isUndefined(this.o_tooltip)) {
        return;
      }
      var left, top;
      left = event.pointerX();
      top = event.pointerY();
      if (Object.isElement(this.o_tooltip.element)) {
        this.o_tooltip.element.setStyle({left: left + 'px', top: (top - this.o_tooltip.element.getHeight() - 15) + 'px'});
      }
      if (Object.isElement(this.o_tooltip.iframe)) {
        this.o_tooltip.iframe.setStyle({left: left + 'px', top: (top - this.o_tooltip.element.getHeight() - 15) + 'px'});
      }
      if (!Object.isUndefined(this.hide_timer)) {
        clearTimeout(this.hide_timer);
      }
      this.hide_timer = setTimeout(this.hide.bindAsEventListener(this), this.display_second * 1000);
    },

    initialize: function(element, content, display_second) {
      element = $(element);
      if (Object.isString(content)) {
        this.e_tooltip = new Element('div');
        this.e_tooltip.update(content);
      } else if (Object.isElement(content)) {
        this.e_tooltip = content.cloneNode(true);
      } else {
        return;
      }
      this.e_tooltip.setStyle(
        {
          border: 'solid 1px #000000',
          backgroundColor: '#ffffe7',
          padding: '5px'
        }
      );
      if (display_second) {
        this.display_second = display_second;
      } else {
        this.display_second = 3;
      }
      $$('body')[0].setStyle({position: 'relative'});
      element.observe('mouseover', this.show.bindAsEventListener(this));
      element.observe('mousemove', this.update.bindAsEventListener(this));
      element.observe('mouseout', this.hide.bindAsEventListener(this));
      element.observe(
        'mds:dummy',
        function() {
          this.show.bindAsEventListener(this)();
          this.hide.bindAsEventListener(this)();
        }.bind(this)
      );
      element.observe('mds:tooltip:show', this.show.bindAsEventListener(this));
      element.observe('mds:tooltip:hide', this.hide.bindAsEventListener(this));
    }

  }
);

var Mds_NowLoading = {

    show: function() {
      var e_loading_mask = new Element('div', {id: 'mds-now-loading-mask'});
      var e_loading = new Element('div', {id: 'mds-now-loading'});
      var e_loading_indicator = new Element('div', {id: 'mds-now-loading-indicator'});
      var e_loading_message = new Element('p');
      var e_loading_image = new Element('img', {src: '/images/common/now-loading.gif', width: 48, height: 48});
      e_loading_mask.setOpacity(0.5);
      e_loading_message.update('ただいま読み込み中です');
      e_loading_indicator.insert({bottom: e_loading_image});
      e_loading_indicator.insert({bottom: e_loading_message});
      e_loading.insert({bottom: e_loading_indicator});
      $$('body')[0].insert({top: e_loading});
      $$('body')[0].insert({top: e_loading_mask});
    },

    hide: function() {
      $('mds-now-loading').remove();
      $('mds-now-loading-mask').remove();
      if ($('mds-now-loading-iframe')) {
        $('mds-now-loading-iframe').remove();
      }
    }

};

var Mds_BlackOut = Class.create(
  {

    show: function() {
      if ($('mds-black-out-mask') || $('mds-black-out')) {
        return;
      }
      var width, height, left, top, body_position;
      if (this.element.getStyle('width')) {
        width = this.element.getStyle('width').gsub(/px$/, '');
      } else {
        width = this.element.getWidth();
      }
      if (this.element.getStyle('height')) {
        height = this.element.getStyle('height').gsub(/px$/, '');
      } else {
        height = this.element.getHeight();
      }
      left = (document.viewport.getWidth() / 2) - (width / 2);
      top = (document.viewport.getHeight() / 2) - (height / 2);
      if (this.options && this.options.center_of_scroll) {
        left += document.viewport.getScrollOffsets().left;
        top += document.viewport.getScrollOffsets().top;
      }
      body_position = $$('body')[0].getStyle('position');
      $$('body')[0].setStyle('position', 'relative');
      this.e_black_out_mask = new Element('div', {id: 'mds-black-out-mask'});
      if (Prototype.Browser.IE) {
        this.e_black_out_iframe = new Element('iframe', {id: 'mds-black-out-iframe', src: "javascript: false;", frameborder: 0});
      }
      this.e_black_out = new Element('div', {id: 'mds-black-out'});
      this.e_black_out_indicator = new Element('div', {id: 'mds-black-out-indicator'});
      if (!Object.isUndefined(this.options) && this.options.hide_at_mask) {
        this.e_black_out_mask.observe('click', this.hide.bind(this));
      }
      if (Object.isElement(this.element) && this.element.down('.mds-black-out-close')) {
        this.element.select('.mds-black-out-close').each(
          function(e_close) {
            e_close.observe('click', this.hide.bind(this));
          }.bind(this)
        );
      }
      this.e_black_out_mask.setStyle(
        {
          height: ($('container') ? $('container').getHeight() : $$('body')[0].getHeight()) + 'px'
        }
      );
      if (Prototype.Browser.IE) {
        this.e_black_out_iframe.setStyle(
          {
            height: ($('container') ? $('container').getHeight() : $$('body')[0].getHeight()) + 'px'
          }
        );
      }
      this.e_black_out.setStyle(
        {
          position: 'absolute',
          width: width + 'px',
          height: height + 'px',
          left: left + 'px',
          top: top + 'px'
        }
      );
      this.element.setStyle('position', 'relative');
      this.e_black_out_indicator.setStyle(
        {
          width: width + 'px'
        }
      );
      this.e_black_out_indicator.insert({bottom: this.element});
      this.e_black_out.insert({bottom: this.e_black_out_indicator});
      this.e_black_out.hide();
      $$('body')[0].insert({top: this.e_black_out});
      $$('body')[0].insert({top: this.e_black_out_mask});
      if (Prototype.Browser.IE) {
        $$('body')[0].insert({top: this.e_black_out_iframe});
      }

      var duration = this.options.duration | 1.0;
      Effect.BlindDown(this.e_black_out, { duration: duration, afterFinish: this.reposition.bind(this) });
      $$('body')[0].setStyle('position', body_position);
    },

    hide: function() {
      if (this.e_black_out_mask) {
        this.e_black_out_mask.remove();
      }
      if (this.e_black_out_iframe) {
        this.e_black_out_iframe.remove();
      }
      if (this.e_black_out) {
        this.e_black_out.remove();
      }
    },

    reposition: function() {
      var width, height, left, top, body_position;
      if (this.element.getStyle('width')) {
        width = this.element.getStyle('width').gsub(/px$/, '');
      } else {
        width = this.element.getWidth();
      }
      if (this.element.getStyle('height')) {
        height = this.element.getStyle('height').gsub(/px$/, '');
      } else {
        height = this.element.getHeight();
      }
      left = (document.viewport.getWidth() / 2) - (width / 2);
      top = (document.viewport.getHeight() / 2) - (height / 2);
      if (this.options && this.options.center_of_scroll) {
        left += document.viewport.getScrollOffsets().left;
        top += document.viewport.getScrollOffsets().top;
      }
      this.e_black_out.setStyle(
        {
          position: 'absolute',
          width: width + 'px',
          height: height + 'px',
          left: left + 'px',
          top: top + 'px'
        }
      );
      this.e_black_out_indicator.setStyle(
        {
          width: width + 'px'
        }
      );
    },

    initialize: function(element, options) {
      if (!Object.isElement(element)) {
        return;
      }
      this.options = options || {};
      this.element = element;
      this.show.bind(this)();
    }

  }
);

/**
 * 複数要素の高さを揃える
 *
 * 使用例
 *  new Mds_HeightAssort($$('div#container div.assort-line'));
 *
 * @author T.Mori
 * @package Mds
 * @access public
 */
var Mds_HeightAssort = Class.create(
  {

    /**
     * 高さを揃える
     */
    assort: function() {
      this.calculateMaxHeight();
      this.elements.collect(
        function(element) {
          element.setStyle({ 'height': this.max_height + 'px' });
        }.bind(this)
      );
    },

    /**
     * 最大の高さを計算
     */
    calculateMaxHeight: function() {
      this.max_height = this.elements.max(
        function(element) {
          return element.getHeight();
        }
      );
    },

    /**
     * 全ての要素が Element を継承しているかどうかを調べる
     *
     * @param Enumerable enumerable 調査対象のコレクションオブジェクト
     * @return Boolean 全て Element を継承していれば true
     */
    isElementAll: function(enumerable) {
      var result = enumerable.find(
        function(entry) {
          return !Object.isElement(entry);
        }
      );
      return Object.isUndefined(result);
    },

    /**
     * コンストラクタ
     *
     * @param Array elements 揃える対象の要素
     */
    initialize: function(elements) {
      if (!Object.isArray(elements) || !this.isElementAll(elements)) {
        throw new Mds_Exception('First argument is not Array of Element');
      }
      this.elements = elements;
      this.assort();
    }

  }
);

var Mds_Grobals = {};
var Mds_Globals = {};

var mds = new Mds;

/**
 * 数字 3 桁ごとにカンマを入れる
 *
 * @return String カンマを入れた数値
 */
Number.prototype.commify = function() {
  var s = this.toString().split("\.");
  return s[0].replace(/((^[+-])?(\d)+?)(?=(\d{3})+$)/g, "$1,") + (s[1]? "." + s[1].replace(/(\d{3})(?=\d+)/g, "$1,") : "");
}

Number.prototype.roundByDigit = function(digit) {
  var value = this;
  value = value * Math.pow(10, digit);
  value = parseInt((Math.round(value)).toString());
  value = value / Math.pow(10, digit);
  return value;
};

/**
 * 改行コードを BR タグに置換する
 *
 * @param Boolen xhtml 対象とする文字列
 * @return String 置換後の文字列
 */
String.prototype.nl2br = function(xhtml) {
  xhtml = Object.isUndefined(xhtml) || xhtml ? true : false;
  br = xhtml ? '<br />' : '<br>';
  return this.gsub(/\r\n|\r|\n/i, br);
}

/**
 * prototypeUtils.js from http://jehiah.com/
 * Licensed under Creative Commons.
 * version 1.0 December 20 2005
 *
 * Contains:
 * + Form.Element.setValue()
 * + unpackToForm()
 */
/* Form.Element.setValue("fieldname/id","valueToSet") */
Form.Element.Methods.setValue = function(element,newValue) {
  element_id = element;
  element = $(element);
  if (!element){element = document.getElementsByName(element_id)[0];}
  if (!element){return false;}
  var method = element.tagName.toLowerCase();
  var parameter = Form.Element.SetSerializers[method](element,newValue);
}

Form.Element.SetSerializers = {
  input: function(element,newValue) {
    switch (element.type.toLowerCase()) {
      case 'submit':
      case 'hidden':
      case 'password':
      case 'text':
        return Form.Element.SetSerializers.textarea(element,newValue);
      case 'checkbox':
      case 'radio':
        return Form.Element.SetSerializers.inputSelector(element,newValue);
    }
    return false;
  },

  inputSelector: function(element,newValue) {
    fields = document.getElementsByName(element.name);
    for (var i=0;i<fields.length;i++){
      if (Object.isArray(newValue)) {
        if (newValue.include(fields[i].value)) {
          fields[i].checked = true;
        }
      } else {
        if (fields[i].value == newValue){
          fields[i].checked = true;
        }
      }
    }
  },

  textarea: function(element,newValue) {
    element.value = newValue;
  },

  select: function(element,newValue) {
    var value = '', opt, index = element.selectedIndex;
    for (var i=0;i< element.options.length;i++){
      if (Object.isArray(newValue)) {
        if (newValue.include(element.options[i].value)) {
          element.options[i].selected = true;
        }
      } else {
        if (element.options[i].value == newValue){
          element.options[i].selected = true;
          return true;
        }
      }
    }
  }
}

/* Form.Element.clear("fieldname/id") */
Form.Element.Methods.clear = function(element) {
  element_id = element;
  element = $(element);
  if (!element){element = document.getElementsByName(element_id)[0];}
  if (!element){return false;}
  var method = element.tagName.toLowerCase();
  var parameter = Form.Element.ClearSerializers[method](element);
  return parameter;
}

Form.Element.ClearSerializers = {
  input: function(element) {
    switch (element.type.toLowerCase()) {
      case 'submit':
      case 'hidden':
      case 'password':
      case 'text':
        return Form.Element.ClearSerializers.textarea(element);
      case 'checkbox':
      case 'radio':
        return Form.Element.ClearSerializers.inputSelector(element);
    }
    return false;
  },

  inputSelector: function(element) {
    fields = document.getElementsByName(element.name);
    for (var i=0;i<fields.length;i++){
      fields[i].checked = false;
      fields[i].removeAttribute('checked');
    }
    return element;
  },

  textarea: function(element) {
    element.value = '';
    return element;
  },

  select: function(element,newValue) {
    var value = '', opt, index = element.selectedIndex;
    for (var i=0;i< element.options.length;i++){
      element.options[i].selected = false;
      element.options[i].removeAttribute('selected');
    }
  }
}

Element.addMethods();

function unpackToForm(data){
   for (i in data){
     Form.Element.setValue(i,data[i].toString());
   }
}

document.viewport.getDimensions = function() {
  var dimensions = { }, B = Prototype.Browser;
  $w('width height').each(function(d) {
    var D = d.capitalize();
    if (B.WebKit && !document.evaluate) {
      // Safari <3.0 needs self.innerWidth/Height
      dimensions[d] = self['inner' + D];
    } else if (B.Opera && parseFloat(window.opera.version()) < 9.5) {
      // Opera <9.5 needs document.body.clientWidth/Height
      dimensions[d] = document.body['client' + D];
    //} else if (B.IE) {
    //  dimensions[d] = document.body['client' + D];
    } else {
      dimensions[d] = document.documentElement['client' + D];
    }
  });
  return dimensions;
}

