//
// Timer class for PTC 2.0 C++ API
// Copyright (c) 1998 Glenn Fiedler (ptc@gaffer.org)
// This source code is licensed under the GNU LGPL
//

// include files
#include <time.h>
#include "Timer.h"
#include "Error.h"



                                                    
Timer::Timer()
{
    // defaults
    m_old = 0;
    m_time = 0;
    m_start = 0;
    m_running = false;
}


Timer::~Timer()
{
    // stop
    stop();
}




void Timer::set(float time)
{
    // set time
    m_old = 0;
    m_time = time;
    m_start = time;
}




void Timer::start()
{
    // check if not running
    if (!m_running)
    {
        // set start time
        m_start = clock();

        // set old time
        m_old = clock();

        // timer is running
        m_running = true;
    }
}


void Timer::stop()
{
    // timer is not running
    m_running = false;
}




float Timer::time()
{
    // check if running
    if (m_running)
    {
        // update current time
        m_time = clock();
    }

    // calculate elapsed time
    return m_time - m_start;
}


float Timer::delta()
{
    // check if running
    if (m_running)
    {
        // get clock time
        float time = clock();

        // calculate delta
        float delta = time - m_old;

        // update old time
        m_old = time;

        // get delta
        return delta;
    }
    else
    {
        // not running
        return 0.0f;
    }
}


float Timer::resolution()
{
    //
    // Get timer resolution
    // --------------------
    //
    // This function gets the resolution of the timer in seconds.
    //
    // Currently it just returns 1/CLOCKS_PER_SEC because this timer
    // implementation depends on the <time.h> "clock" function.
    //
    // If you change the "Timer::clock" implementation make sure you
    // update the resolution function to match.
    //
    // See the "Timer::clock" function for more information
    //

    // get timer resolution
    return 1.0f / (float) CLOCKS_PER_SEC;
}




Timer& Timer::operator =(const Timer &timer)
{
    // check for self assignment
    if (this==&timer) throw Error("self assignment is not allowed");
        
    // assignment
    m_old = timer.m_old;
    m_time = timer.m_time;
    m_start = timer.m_start;
    m_running = timer.m_running;
    return *this;
}


bool Timer::operator ==(const Timer &timer) const
{
    // is equal to
    if (m_old==timer.m_old && 
        m_time==timer.m_time && 
        m_start==timer.m_start && 
        m_running==timer.m_running) return true;

    // failure
    return false;
}


bool Timer::operator !=(const Timer &timer) const
{
    // not equal to
    return !(*this==timer);
}




float Timer::clock()
{
    //
    // Get clock time
    // --------------
    //
    // This function uses the ansi c "clock" function to determine
    // the number of seconds elapsed since the process has started.
    //
    // The "clock" function is usually pretty limited in resolution
    // (ie. CLOCKS_PER_SEC) so you should probably replace the call
    // to clock with a platform dependent function with higher time
    // resolution.
    //

    // get clock time
    clock_t time = ::clock();

    // convert to seconds and return
    return (float) time / (float) CLOCKS_PER_SEC;
}





