//
//  Copyright © 2001 - 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:   SensorScheduler.h
//
//  Project:    6046.
//
//  Author(s):  W. Arcus
//
//  Purpose:    
//
//  Notes:      
//

#include "StdAfx.h"
#include "SensorScheduler.h"

namespace           // begin unnamed namespace.
{

    const unsigned long ulSecondsToMilliseconds_c = 1000UL;

};                  // end unnamed namespace.

//////////////////////////////////////////////////////////////////////
// CSensorScheduler class implementation -- public members first.

CSensorScheduler::CSensorScheduler( void )
{
    m_SchedulableSensorList.clear();
}

CSensorScheduler::~CSensorScheduler( void )
{
    m_SchedulableSensorList.clear();
}

bool CSensorScheduler::Queue(   const int           &riDelayInSeconds,
                                const int           &riModule,
                                const SENSORINFO    &rsSensorInfo )
{
    SCHEDULEDSENSOR sSensorItem( riDelayInSeconds, riModule, rsSensorInfo );

    m_SchedulableSensorList.push_back( sSensorItem );

    if ( ! m_SchedulableSensorList.empty() )
    {
        m_SchedulableSensorList.sort();
    }

    return true;
}

bool CSensorScheduler::Reset( void )
{
    // Terminate any oustanding timer operations and clear the queue of previously schedulable sensors.

    m_Timer.Cancel();
    m_SchedulableSensorList.clear();

    return true;
}

bool CSensorScheduler::Start( void )
{
    return ScheduleNext();
}

CSensorScheduler::operator HANDLE ( void ) const
{
    return static_cast<HANDLE>( m_Timer );
}

bool CSensorScheduler::ScheduledSensorInfo( SENSORINFO &rsSensorInfo,
                                            int        &riModule,
                                            const bool &rbRemoveFromQueue )
{
    bool bSuccess = false;          // Assume false for now.

    // Retrieve the queued entry for this sensor.

    if ( ! m_SchedulableSensorList.empty() )
    {
        const SCHEDULEDSENSOR &rFront = m_SchedulableSensorList.front();

        rsSensorInfo = rFront.m_sSensorInfo;
        riModule     = rFront.m_iModule;

        // Remove it from the queue, if requested (the normal operation).

        if ( rbRemoveFromQueue )
        {
            m_SchedulableSensorList.pop_front();
        }

        bSuccess = true;
    }

    return bSuccess;
}
                                       
bool CSensorScheduler::ScheduleNext( void )
{
    bool bScheduled = false;                  // Assume false for now.

    if ( m_SchedulableSensorList.empty() )
    {
        bScheduled = true;                    // Nothing to do.
    }
    else
    {
        // Locate the first sensor in the queue (since the list is maintained in sorted ascending order)
        // and schedule it for startup.

        const SCHEDULEDSENSOR &rFront = m_SchedulableSensorList.front();

        if ( rFront.m_iDelayInSeconds >= 0 )
        {
            m_Timer.Set( ulSecondsToMilliseconds_c * rFront.m_iDelayInSeconds, 0UL );
            bScheduled = true;
        }
    }

    return bScheduled;
}

