//
//  Copyright © 2003, 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:   7kTriggerSequence.cpp
//
//  Project:    6046
//
//  Author(s):  W. Arcus
//
//  Purpose:    Implements C7kTriggerSequence and its helper C7kSequenceStep.
//
//  Notes:      
//

#include "StdAfx.h"
#include "7kTriggerSequence.h"

#include <algorithm>

using std::find;

///////////////////////////////////////////////////////////////////////////////
// C7kSequenceStep helper class implementation.

C7kSequenceStep::C7kSequenceStep( void )
{
    ManageDllState_m();

    m_ulTriggerId   = 0UL;
    m_ulEdgeTrigger = static_cast<unsigned long>( triggerEdgeRising );
    m_ulDelay       = 0UL;
}

C7kSequenceStep::~C7kSequenceStep( void )
{
    ManageDllState_m();

    m_ulTriggerId   = 0UL;
    m_ulEdgeTrigger = static_cast<unsigned long>( triggerEdgeRising );
    m_ulDelay       = 0UL;
}

C7kSequenceStep::C7kSequenceStep( const C7kSequenceStep &rRhs )
{
    ManageDllState_m();

    if ( &rRhs != this )
    {
        m_ulTriggerId   = rRhs.m_ulTriggerId;
        m_ulEdgeTrigger = rRhs.m_ulEdgeTrigger;
        m_ulDelay       = rRhs.m_ulDelay;
    }
    else
    {
        ASSERT( false );
    }
}

C7kSequenceStep & C7kSequenceStep::operator = ( const C7kSequenceStep &rRhs )
{
    ManageDllState_m();

    if ( &rRhs != this )
    {
        m_ulTriggerId   = rRhs.m_ulTriggerId;
        m_ulEdgeTrigger = rRhs.m_ulEdgeTrigger;
        m_ulDelay       = rRhs.m_ulDelay;
    }
    else
    {
        ASSERT( false );
    }

    return *this;
}

bool C7kSequenceStep::operator == ( const unsigned long &rulTriggerId ) const
{
    ManageDllState_m();

    return ( m_ulTriggerId == rulTriggerId );
}

bool C7kSequenceStep::operator < ( const unsigned long &rulTriggerId ) const
{
    ManageDllState_m();

    return ( m_ulTriggerId < rulTriggerId );
}

void C7kSequenceStep::Configure (   const unsigned long     &rulTriggerId,
                                    const unsigned long     &rulDelay,
                                    const ETRIGGEREDGE      &reTriggerEdge )
{
    ManageDllState_m();

    m_ulTriggerId   = rulTriggerId;
    m_ulDelay       = rulDelay;
    m_ulEdgeTrigger = static_cast<unsigned long>( reTriggerEdge );
}

unsigned long C7kSequenceStep::TriggerId( void ) const
{
    ManageDllState_m();

    return m_ulTriggerId;
}

unsigned long C7kSequenceStep::TriggerEdge( void ) const
{
    ManageDllState_m();

    return m_ulEdgeTrigger;
}

unsigned long C7kSequenceStep::Delay( void ) const
{
    ManageDllState_m();

    return m_ulDelay;
}

///////////////////////////////////////////////////////////////////////////////
// C7kTriggerSequence class implementation.

C7kTriggerSequence::C7kTriggerSequence( void )
{
    ManageDllState_m();

    m_bEnabled      = false;
    m_ulSequenceId  = 0UL;
    m_eMode         = modeSingleTrigger;

    m_SequenceList.clear();
}

C7kTriggerSequence::~C7kTriggerSequence( void )
{
    ManageDllState_m();

    try
    {
        m_bEnabled      = false;
        m_ulSequenceId  = 0UL;
        m_eMode         = modeSingleTrigger;

        m_SequenceList.clear();
    }
    catch ( ... )
    {
        TRACE( _T( "C7kTriggerSequence::~C7kTriggerSequence(), Unspecified exception caught\n" ) );
    }
}

C7kTriggerSequence::C7kTriggerSequence( const C7kTriggerSequence &rRhs )
{
    ManageDllState_m();

    if ( &rRhs != this )
    {
        m_bEnabled     = rRhs.m_bEnabled;
        m_ulSequenceId = rRhs.m_ulSequenceId;
        m_SequenceList = rRhs.m_SequenceList;
        m_eMode        = rRhs.m_eMode;
    }
    else
    {
        ASSERT( false );
    }
}

C7kTriggerSequence & C7kTriggerSequence::operator = ( const C7kTriggerSequence &rRhs )
{
    ManageDllState_m();

    if ( &rRhs != this )
    {
        m_bEnabled     = rRhs.m_bEnabled;
        m_ulSequenceId = rRhs.m_ulSequenceId;
        m_SequenceList = rRhs.m_SequenceList;
        m_eMode        = rRhs.m_eMode;
    }
    else
    {
        ASSERT( false );
    }

    return *this;
}

bool C7kTriggerSequence::operator == ( const unsigned long &rulSequenceId ) const
{
    ManageDllState_m();

    return ( m_ulSequenceId == rulSequenceId );
}

bool C7kTriggerSequence::operator <  ( const C7kTriggerSequence &rRhs ) const
{
    ManageDllState_m();

    return ( m_ulSequenceId < rRhs.m_ulSequenceId );
}

const C7kSequenceStep * C7kTriggerSequence::SequenceSteps( void ) const
{
    ManageDllState_m();

    return static_cast<const C7kSequenceStep *>( ( m_SequenceList.empty() ) ? NULL : &(m_SequenceList[ 0 ]) );
}

void C7kTriggerSequence::Mode( const EMODE &reMode )
{
    ManageDllState_m();

    m_eMode = reMode;
}

void C7kTriggerSequence::SequenceId( const unsigned long &rulSequenceId )
{
    ManageDllState_m();

    m_ulSequenceId = rulSequenceId;
}

void C7kTriggerSequence::Enable( void )
{
    ManageDllState_m();

    m_bEnabled = true;
}

void C7kTriggerSequence::Disable( void )
{
    ManageDllState_m();

    m_bEnabled = false;
}

bool C7kTriggerSequence::DeleteSteps( void )
{
    ManageDllState_m();

    if ( ! m_SequenceList.empty() )
    {
        m_SequenceList.clear();
    }

    return true;
}

bool C7kTriggerSequence::AddStep( const C7kSequenceStep &rsSequenceStep )
{
    ManageDllState_m();

    bool bSuccess = false;              // Assume failure for now.

    try
    {
        if ( IsNew( rsSequenceStep.TriggerId() ) )
        {
            m_SequenceList.push_back( rsSequenceStep );
            bSuccess = true;
        }
    }
    catch ( ... )
    {
        bSuccess = false;
        TRACE( _T( "C7kTriggerSequence::AddStep(), Unspecified exception caught\n" ) );
    }

    return bSuccess;
}

bool C7kTriggerSequence::IsEnabled( void ) const
{
    ManageDllState_m();

    return m_bEnabled;
}

unsigned long C7kTriggerSequence::SequenceId( void ) const
{
    ManageDllState_m();

    return m_ulSequenceId;
}

unsigned long C7kTriggerSequence::Steps( void ) const
{
    ManageDllState_m();

    return m_SequenceList.size();
}

inline
bool C7kTriggerSequence::IsNew( const unsigned long &rulTriggerId ) const
{
    return ( ( m_SequenceList.empty() ) ? true : ( std::find( m_SequenceList.begin(), m_SequenceList.end(), rulTriggerId ) != m_SequenceList.end() ) );
}
