//
//  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:   FrameQueue.cpp
//
//  Project:    6046
//
//  Author(s):  W. Arcus
//
//  Purpose:    Defines a frame accumulation class for accumulating BlueFin
//              data frames in preparation of bundled frame-based 7k record formation.
//
//  Notes:      
//

#include "StdAfx.h"
#include "FrameQueue.h"

#include "..\..\..\Utils\NetUtils\7kProtocol.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// CFrameQueue class implementation.

CFrameQueue::CFrameQueue( void )
            :m_ulMaxFramePeriod( 1000UL )
{
    m_ulTimeStamp        = 0UL;
    m_ulFrameCount       = 0UL;
    m_ulFrameSizeInBytes = 0UL;
    m_ulMaxFrameCount    = 0UL;

    m_bFrameComplete     = false;

    m_eFrameType         = frameTypeUnknown;

    m_FrameQueue.Reset();
}

CFrameQueue::~CFrameQueue( void )
{
    try
    {
        m_ulTimeStamp        = 0UL;
        m_ulFrameCount       = 0UL;
        m_ulFrameSizeInBytes = 0UL;
        m_ulMaxFrameCount    = 0UL;

        m_bFrameComplete     = false;

        m_eFrameType         = frameTypeUnknown;

        m_FrameQueue.Reset();
    }
    catch ( ... )
    {
        TRACE( _T( "CFrameQueue::~FrameQueue(), Unspecified exception caught\n" ) );
    }
}

void CFrameQueue::ConfigureFrame(   const unsigned long &rulFramesPerSecond,
                                    const unsigned long &rulFrameSize,
                                    const EFRAMETYPE    &reFrameType )
{
    m_ulMaxFrameCount    = rulFramesPerSecond;
    m_ulFrameSizeInBytes = rulFrameSize;
    m_eFrameType         = reFrameType;
}

bool CFrameQueue::AddFrame(     const BYTE          *pbyData,
                                const unsigned long &rulNumBytes,
                                const unsigned long &rulTimeStamp )
{
    bool bSuccess = false;          // Assume failure for now.

    ASSERT( rulNumBytes == m_ulFrameSizeInBytes );

    if ( rulNumBytes == m_ulFrameSizeInBytes )
    {
        if ( m_ulFrameCount++ == 0 )
        {
            m_ulTimeStamp = rulTimeStamp;
        }

        m_FrameQueue.Add( const_cast<BYTE *>( pbyData ), rulNumBytes );

        if ( ( m_ulFrameCount >= m_ulMaxFrameCount ) || 
             ( ( rulTimeStamp - m_ulTimeStamp ) > m_ulMaxFramePeriod ) )
        {
            m_bFrameComplete = true;
        }

        bSuccess = true;
    }

    return bSuccess;
}

void CFrameQueue::Reset( void )
{
    m_ulTimeStamp    = 0UL;
    m_ulFrameCount   = 0UL;

    m_bFrameComplete = false;

    m_FrameQueue.Reset();
}

bool CFrameQueue::IsComplete( void ) const
{
    return m_bFrameComplete;
}

CFrameQueue::operator unsigned long ( void ) const
{
    return static_cast<unsigned long> ( sizeof( BYTE ) * m_FrameQueue.Size() );
}

CFrameQueue::operator BYTE * const ( void ) const
{
    return static_cast<BYTE *>( m_FrameQueue.GetAt( 0 ) );
}

unsigned long CFrameQueue::FrameSize( void ) const
{
    return m_ulFrameSizeInBytes;
}

unsigned long CFrameQueue::NumberOfFrames( void ) const
{
    return m_ulFrameCount;
}

CFrameQueue::EFRAMETYPE CFrameQueue::FrameType( void ) const
{
    return m_eFrameType;
}

unsigned long CFrameQueue::Timestamp( void ) const
{
    return m_ulTimeStamp;
}
