//
//  Copyright © 2002, RESON Inc. All Rights Reserved.
//
//  No part of this file may be reproduced or transmitted in any form or by
//  any means, electronic or mechanical, including photocopy, recording, or
//  information storage or retrieval system, without permission in writing
//  from RESON Inc.
//
//  Filename:   CTimer.cpp
//
//  Project:    6046
//
//  Author(s):  W. Arcus
//
//  Purpose:    Implements a timer class to simplify usage of a waitable timer.
//
//  Notes:      
//

#include "StdAfx.h"
#include "Timer.h"

//////////////////////////////////////////////////////////////////////
// CTimer class implementation.

CTimer::CTimer( const bool  &rbManualReset,
                LPCTSTR      lpszName )
{
    ManageDllState_m();

    m_hTimer = ::CreateWaitableTimer( NULL, rbManualReset ? 1UL : 0UL, lpszName );
    ASSERT( m_hTimer != NULL );

    if ( m_hTimer == NULL )
    {
        TRACE( _T( "CTimer::CTimer(), m_hTimer is NULL. Error code: %lu\n" ), ::GetLastError() );
    }
}

CTimer::~CTimer( void )
{
    ManageDllState_m();

    if ( m_hTimer != NULL )
    {
        __TRY
        {
            Cancel();

            if ( m_hTimer != NULL )
            {
                CloseHandle( m_hTimer );
                m_hTimer = NULL;
            }
        }
        __FINALLY
        {
            ASSERT( m_hTimer == NULL );
            m_hTimer = NULL;
        }
        __ENDFINALLY
    }
}

bool CTimer::Set(   const long  &rlTimeFromNowInMilliseconds,
                    const long  &rlPeriodMilliseconds )
{
    ManageDllState_m();

    bool bSuccess = false;

    if ( m_hTimer != NULL )
    {
        // The following specifies the timer object to be signalled in 100 nanosecond units from current time
        // hence (-)ve values. The timer accuracy depends on the system's hardware capabilities.

        const long lMillisecondsTo100Nanoseconds = 10000L;

        LARGE_INTEGER liDueTimeInNanoseconds = { 0 };
        
        liDueTimeInNanoseconds.QuadPart = -( rlTimeFromNowInMilliseconds * lMillisecondsTo100Nanoseconds );

        bSuccess = ( ::SetWaitableTimer( m_hTimer, &liDueTimeInNanoseconds, rlPeriodMilliseconds, NULL, NULL, FALSE ) != FALSE );

        if ( ! bSuccess )
        {
            TRACE( _T( "CTimer::Set(), SetWaitableTimer() failed, error code: %lu\n" ), ::GetLastError() );
        }
    }

    return bSuccess;
}

bool CTimer::Cancel( void )
{
    ManageDllState_m();

    if ( m_hTimer != NULL )
    {
        return ( CancelWaitableTimer( m_hTimer ) != FALSE );
    }

    return false;
}

CTimer::operator HANDLE ( void ) const
{
    ManageDllState_m();

    return m_hTimer;
}



