/**
 * js/lib/countdown.js
 *
 * @author T.Mori <t.mori@moshimo.co.jp>
 * @package Mds
 * @version $Id$
 */

/**
 * カウントダウンタイマー
 *
 * @author T.Mori <t.mori@moshimo.co.jp>
 * @package Mds
 * @access public
 */
var Xenon_CountDown = Class.create(
  {

    // {{{ setting
    /**
     * 準備する
     *
     * @param Integer _y 年
     * @param Integer _m 月
     * @param Integer _d 日
     * @param Integer _h 時
     * @param Integer _i 分
     * @param Integer _s 秒
     */
    setting: function(_y, _m, _d, _h, _i, _s) {
      _y = _y || this.src.getFullYear();
      _m = _m || this.src.getMonth() + 1;
      _d = _d || this.src.getDate();
      _h = _h || 0;
      _i = _i || 0;
      _s = _s || 0;
      this.dest = new Date(_y, _m - 1, _d, _h, _i, _s);
      return this;
    },
    // }}}

    // {{{ run
    /**
     * 実行する
     *
     * @param String|HTMLElement _element 書き換え対象要素
     * @param Object _options パラメータ
     *   Integer interval 実行間隔
     *   Boolean milliseconds ミリ秒まで表示
     *   String alternative 終了時の代替文字列
     *   String prefix 時刻表示の前に付与する文字列
     *   String suffix 時刻表示の後に付与する文字列
     */
    run: function(_element, _options) {
      _options = _options || {};
      _options.interval = _options.interval || 23;
      _options.lang = _options.lang || "ja";
      this.interval_timer = setInterval(
        function() {
          var _date = new Date;
          $(this._element).update(this._dump.bind(this)(_date, this._options));
        }.bind(
          {
            _element: _element,
            _options: _options,
            _dump: this._dump,
            dest: this.dest,
            stop: this.stop
          }
        ),
        _options.interval
      );
    },
    // }}}

    // {{{ stop
    /**
     * 停止させる
     */
    stop: function() {
      clearInterval(this.interval_timer);
    },
    // }}}

    // {{{ _dump
    /**
     * 残り時間を顕す文字列を取得する
     *
     * @param Date _date 現在の日時を顕す Date オブジェクト
     * @param Object _options パラメータ
     */
    _dump: function(_date, _options) {
      var _diff = this.dest - _date;
      if (_diff < 0) {
        this.stop();
        return _options.alternative || "";
      }
      var _d  = Math.floor(_diff / (1000 * 60 * 60 * 24));
      var _h  = Math.floor(_diff % (1000 * 60 * 60 * 24) / (1000 * 60 * 60));
      var _i  = Math.floor(_diff % (1000 * 60 * 60 * 24) % (1000 * 60 * 60) / (1000 * 60));
      var _s  = Math.floor(_diff % (1000 * 60 * 60 * 24) % (1000 * 60 * 60) % (1000 * 60) / 1000);
      var _ms = Math.floor(_diff % (1000 * 60 * 60 * 24) % (1000 * 60 * 60) % (1000 * 60) % 1000);
      var _unit = {};
      if (_options.lang == "en") {
        _unit.d = " day(s) ";
        _unit.h = ":";
        _unit.i = ":";
        _unit.s = ".";
        _unit.ms = "";
      } else if (_options.lang == "ja") {
        _unit.d = " 日 ";
        _unit.h = " 時間 ";
        _unit.i = " 分 ";
        _unit.s = " 秒 ";
        _unit.ms = "";
      } else {
        _unit.d = " ";
        _unit.h = " ";
        _unit.i = " ";
        _unit.s = " ";
        _unit.ms = "";
      }
      var _string = "";
      _string += _options.prefix || "";
      _string += _d.toPaddedString(1) + _unit.d;
      _string += _h.toPaddedString(2) + _unit.h;
      _string += _i.toPaddedString(2) + _unit.i;
      _string += _s.toPaddedString(2) + _unit.s;
      if (Object.isUndefined(_options.milliseconds) || _options.milliseconds) {
        _string += _ms.toPaddedString(3) + _unit.ms;
      }
      _string += _options.suffix || "";
      return _string;
    },
    // }}}

    // {{{ initialize
    /**
     * コンストラクタ
     */
    initialize: function() {
      this.src = new Date;
    }
    // }}}

  }
);
var x_countdown = new Xenon_CountDown;


