/*****************************************************************************
 * $LastChangedDate: 2009-11-22 22:39:11 -0500 (Sun, 22 Nov 2009) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Replay animation of an Aircraft.
 * @remarks Replay format versions:
 *          v1 : deficient (version info wasn't even embedded)
 *          v2 : based on Matrix12 with special initial rotation (init_m[]).
 *          v3 : based on Quaternions (eliminated special initial rotation).
 *
 *          Replay reduces memory consumption by:
 *          - zlib compression
 *          - defining rotations as quaternions
 *          - storing steps which change significantly
 *//*
 * LEGAL:   COPYRIGHT (C) 2008 JIM E. BROOKS
 *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
 *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
 *****************************************************************************/

#define CONTROL_REPLAY_CC 1
#include "base/module.hh"
using namespace base;
#include "object/module.hh"
#include "object/aircraft.hh"
using namespace object;
#include "control/module.hh"
#include "control/replay.hh"
#include "control/replay_recorder.hh"
#include "control/replay_player.hh"

namespace control {

////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////  Replay  ////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

/*****************************************************************************
 * ctor/dtor.
 *****************************************************************************/
Replay::Replay( shptr<Aircraft> aircraft,
                const Milliseconds freq,
                const Command::ExecuteMode commandExecuteMode )
:   mAircraft(aircraft),
    mRecorder(new ReplayRecorder(aircraft,freq)),
    mPlayer(new ReplayPlayer(aircraft,freq,commandExecuteMode))
{
CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);

    SET_TYPESIG(this,TYPESIG_REPLAY);
}

Replay::~Replay()
{
    INVALIDATE_TYPESIG(this,TYPESIG_REPLAY);
}

/*****************************************************************************
 * Start recording replay data.
 *****************************************************************************/
bool
Replay::Record( void )
{
CHECK_TYPESIG(this,TYPESIG_REPLAY);

    mPlayer->Stop();
    mRecorder->Start();

    return true;
}

/*****************************************************************************
 * Do a replay.
 *****************************************************************************/
bool
Replay::Play( void )
{
CHECK_TYPESIG(this,TYPESIG_REPLAY);

    // If a recording was done, then play it.
    // Else play a replay that was loaded from a file (implied).
    mRecorder->Stop();
    if ( mRecorder->IfHaveRecording() )
    {
        mPlayer->UseRecording( mRecorder );
    }
    mPlayer->Start();

    return true;
}

/*****************************************************************************
 * Stop playing or recording.
 *****************************************************************************/
void
Replay::Stop( void )
{
CHECK_TYPESIG(this,TYPESIG_REPLAY);

    mPlayer->Stop();
    mRecorder->Stop();
}

/*****************************************************************************
 * @return True if replay is executing.
 *****************************************************************************/
bool
Replay::IfPlaying( void ) const
{
CHECK_TYPESIG(this,TYPESIG_REPLAY);

    return mPlayer->IfPlaying();
}

/*****************************************************************************
 * Save replay data to a file.
 * THROWS EXCEPTION.
 *****************************************************************************/
bool
Replay::Save( const string& filename )
{
CHECK_TYPESIG(this,TYPESIG_REPLAY);

    return mRecorder->Save( filename );
}

/*****************************************************************************
 * Load replay data from a file.
 * THROWS EXCEPTION.
 *****************************************************************************/
bool
Replay::Load( const string& filename )
{
CHECK_TYPESIG(this,TYPESIG_REPLAY);

    // Stop and discard recording.
    mRecorder->Stop();
    mRecorder->Clear();

    // Load.
    return mPlayer->Load( filename );
}

} // namespace control
