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

  \author Satofumi KAMIMURA

  $Id: StopWatch.cpp 1811 2010-04-30 16:12:05Z 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;
}
