/*!
  \file
  \brief 一時停止可能なタイマー

  \author Satofumi KAMIMURA

  $Id: StopWatch.cpp 1247 2009-08-25 21:13:37Z satofumi $

  \todo 状態遷移を追加する
  \todo コメントを追加する
*/

#include "StopWatch.h"
#include "ticks.h"

using namespace qrk;


struct StopWatch::pImpl
{
  enum {
    InvalidTicks = -1,
  };

  int start_ticks_;
  int pause_ticks_;


  pImpl(void)
  {
    initialize();
  }


  void initialize(void)
  {
    start_ticks_ = InvalidTicks;
    pause_ticks_ = InvalidTicks;
  }
};


StopWatch::StopWatch(void) : pimpl(new pImpl)
{
}


StopWatch::~StopWatch(void)
{
}


void StopWatch::start(void)
{
  if (pimpl->pause_ticks_ != pImpl::InvalidTicks) {
    // 一時停止の場合、再開させる
    resume();
    return;

  } else if (pimpl->start_ticks_ != pImpl::InvalidTicks) {
    // 再生中の場合は、戻る
    return;

  } else {
    // 停止中の場合は、開始する
    pimpl->start_ticks_ = qrk::ticks();
  }
}


void StopWatch::stop(void)
{
  pimpl->initialize();
}


void StopWatch::pause(void)
{
  if ((pimpl->pause_ticks_ != pImpl::InvalidTicks) ||
      (pimpl->start_ticks_ == pImpl::InvalidTicks)) {
    // 一時停止、停止の場合、戻る
    return;
  }

  pimpl->pause_ticks_ = qrk::ticks();
}


void StopWatch::resume(void)
{
  // 一時停止でなければ、戻る
  if (pimpl->pause_ticks_ == pImpl::InvalidTicks) {
    return;
  }

  int paused_msec = qrk::ticks() - pimpl->pause_ticks_;
  pimpl->start_ticks_ += paused_msec;
  pimpl->pause_ticks_ = pImpl::InvalidTicks;
}


int StopWatch::ticks(void)
{
  if (pimpl->start_ticks_ == pImpl::InvalidTicks) {
    // 停止
    return 0;

  } else if (pimpl->pause_ticks_ != pImpl::InvalidTicks) {
    // 一時停止
    return pimpl->pause_ticks_ - pimpl->start_ticks_;

  } else {
    // 再生
    return qrk::ticks() - pimpl->start_ticks_;
  }
}


bool StopWatch::isPause(void)
{
  return (pimpl->pause_ticks_ != pImpl::InvalidTicks) ? true : false;
}
