/*****************************************************************************
 * $LastChangedDate: 2011-04-23 21:07:07 -0400 (Sat, 23 Apr 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Test of time units classes.
 *//*
 * LEGAL:   COPYRIGHT (C) 2007 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#define TESTING 1
#include "test.hh"
#include "base/module.hh"
#include "base/time.hh"
using namespace base;

/*****************************************************************************
 * Test time units.
 * Milliseconds is the most important time class.
 *****************************************************************************/
bool
TestTimeBasic( void )
{
    // Test compiler with 64-bit operations.
    {
        const uint32 lo32 = 0x44556677U;
        const uint32 hi32 = 0x11223344U;
        const Microseconds microseconds(  (uint64(lo32) & (0xffffffffULL))
                                       | ((uint64(hi32) & (0xffffffffULL)) << 32) );
        if ( microseconds.INT() != 0x1122334444556677ULL ) return Fail();
    }

    {
    // Test that it's 64-bits.
    Milliseconds t( 0x4444333322221111LL );
    if ( t.INT() != 0x4444333322221111LL ) return Fail();
    }

    {
    // Try to test ctor defaulting to 0.
    Milliseconds t;
    if ( t.INT() != 0 ) return Fail();
    }

    // operator==()
    // operator!=()
    {
    Milliseconds t111a( 111 );
    Milliseconds t111b( 111 );
    Milliseconds t222( 222 );
    if ( t111a != t111b ) return Fail();
    if ( t111b != t111a ) return Fail();
    if ( t222 == t111a ) return Fail();
    if ( t111a == t222 ) return Fail();
    }

    // Test signedness.
    {
    Milliseconds pos64(  123412349999LL );
    Milliseconds neg64( -123412349999LL );
    if ( pos64 < Milliseconds(0) ) Fail();
    if ( neg64 > Milliseconds(0) ) Fail();
    if ( pos64 != pos64 ) Fail();
    if ( neg64 != neg64 ) Fail();
    }

    // operator+()
    {
    Milliseconds t0( 3 );
    Milliseconds t1( 4 );
    Milliseconds res = t0 + t1;
    if ( res != Milliseconds(7) ) return Fail();
    }

    // operator-()
    {
    Milliseconds t0( 10 );
    Milliseconds t1( 2 );
    Milliseconds res = t0 - t1;
    if ( res != Milliseconds(8) ) return Fail();
    }

    // operator/()
    {
    Milliseconds t0( 30 );
    Milliseconds t1( 3 );
    Milliseconds res = t0 / t1;
    if ( res != Milliseconds(10) ) return Fail();
    }

    // operator*()
    {
    Milliseconds t0( 4 );
    Milliseconds t1( 5 );
    Milliseconds res = t0 * t1;
    if ( res != Milliseconds(20) ) return Fail();
    }

    return true;
}

/*****************************************************************************
 * Test time conversions.
 * Milliseconds is the most important time class.
 *****************************************************************************/
bool
TestTimeConversions( void )
{
    {
    Milliseconds milliseconds( Microseconds2Milliseconds<TimeInt>( 5 * 1000 ) );
    if ( milliseconds != Milliseconds(5) ) return Fail();
    }

    {
    Milliseconds milliseconds( Microseconds2Milliseconds<TimeInt>( -5 * 1000 ) );
    if ( milliseconds != Milliseconds(-5) ) return Fail();
    }

    {
    Milliseconds milliseconds( Seconds2Milliseconds<TimeInt>( Seconds(9).INT() ) );
    if ( milliseconds != Milliseconds(9000) ) return Fail();
    }

    {
    Milliseconds milliseconds( Seconds2Milliseconds<TimeInt>( Seconds(-9).INT() ) );
    if ( milliseconds != Milliseconds(-9000) ) return Fail();
    }

    {
    Milliseconds milliseconds( Minutes2Milliseconds<TimeInt>( Minutes(1).INT() ) );
    if ( milliseconds != Milliseconds(1*60*1000) ) return Fail();
    }

    {
    Microseconds microseconds( Milliseconds2Microseconds<TimeInt>( 1234 ) );
    if ( microseconds.INT() != 1234*1000L ) return Fail();
    }

    {
    Seconds seconds( Microseconds2Seconds( Microseconds( 17 * MILLION ).INT() ) );
    if ( seconds.INT() != 17 ) return Fail();
    }

    {
    Seconds seconds( Milliseconds2Seconds( Milliseconds( 123 * THOUSAND ).INT() ) );
    if ( seconds.INT() != 123 ) return Fail();
    }

    {
    Seconds seconds( Milliseconds2Seconds( Milliseconds( 123456789000LL ).INT() ) );
    if ( seconds.INT() != 123456789LL ) return Fail();
    }

    return true;
}

int main( int argc, char** argv )
{
    RUN_TEST( "time units", TEST_ERROR_MODE_ABORT,
              TestTimeBasic()
          and TestTimeConversions() )
}
