/*****************************************************************************
 * $LastChangedDate: 2011-04-23 21:07:07 -0400 (Sat, 23 Apr 2011) $
 * @file
 * @author  Jim E. Brooks  http://www.palomino3d.org
 * @brief   Interface of C functions for Lua scripts.
 * @remarks @remarks module.txt documents how to export new C++ classes to Lua.
 *
 * ----------------------------
 * -- THIS IS AUTO-GENERATED --
 * ----------------------------
 *
 *//*
 * 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).
 *****************************************************************************/

#include "base/module.hh"
#include "base/stream.hh"
using namespace base;
#include "object/module.hh"
#include "object/aircraft.hh"
using namespace object;
#include "control/module.hh"
#include "control/replay.hh"
using namespace control;
#include "lua_bind/module.hh"
#include "lua_bind/bind.hh"

namespace lua {


namespace bind {

#define BIND_CLASS_NAME      "Replay"
#define BIND_METATABLE_NAME  LUABIND_METATABLE_STRING(BIND_CLASS_NAME)

//==============================================================================
// C functions called by Lua that access C++ objects.
//==============================================================================
// Need a function to check typesig because of macro/template limitations.
#if ! DOXYGEN
INTERN void
CheckTypesigReplay( shptr<Replay> obj )
{
    CHECK_TYPESIG(obj,TYPESIG_REPLAY);
}
#endif // ! DOXYGEN

/*****************************************************************************
 * Lua's garbage collector indirectly invokes this C++ destructor.
 *****************************************************************************/
INTERN int 
Replay_Destroy( lua_State* L ) 
{ 
   try { 

        return DESTROY_USERDATA_SHPTR<Replay>( L, CheckTypesigReplay );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * bool Replay:IfPlaying()
 *****************************************************************************/
INTERN int 
Replay_IfPlaying( lua_State* L ) 
{ 
   try { 

        shptr<Replay> replay = POP_USERDATA_AS_SHPTR<Replay>( L );
        CHECK_TYPESIG(replay,TYPESIG_REPLAY);
        lua_pushboolean( L, replay->IfPlaying() );
        return 1;
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * bool Replay:Load( filename )
 *****************************************************************************/
INTERN int 
Replay_Load( lua_State* L ) 
{ 
   try { 

        const string filename = POP_STRING( L );
        shptr<Replay> replay = POP_USERDATA_AS_SHPTR<Replay>( L );
        CHECK_TYPESIG(replay,TYPESIG_REPLAY);
        // Load() will throw exception if file doesn't exist.
        try
        {
            const bool loaded = replay->Load( filename );
            lua_pushboolean( L, loaded );
            return 1;
        }
        catch( const Exception& e )
        {
            CERROR << e.what() << std::endl;
        }

        // Failed inside try or threw exception.
        lua_pushboolean( L, false );
        return 1;
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * Replay:New( aircraft, milliseconds, commandMode )
 *****************************************************************************/
INTERN int 
Replay_New( lua_State* L ) 
{ 
   try { 

        const Command::ExecuteMode commandExecuteMode = Command::ExecuteMode( POP_INT( L ) );
        const Milliseconds milliseconds( POP_INT( L ) );
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        shptr<Replay> replay = new Replay( aircraft, milliseconds, commandExecuteMode );
        return NEW_USERDATA_SHPTR<Replay>( L, replay, BIND_METATABLE_NAME );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * bool Replay:Play()
 *****************************************************************************/
INTERN int 
Replay_Play( lua_State* L ) 
{ 
   try { 

        shptr<Replay> replay = POP_USERDATA_AS_SHPTR<Replay>( L );
        CHECK_TYPESIG(replay,TYPESIG_REPLAY);
        lua_pushboolean( L, replay->Play() );
        return 1;  // stack items to return
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * bool Replay:Record()
 *****************************************************************************/
INTERN int 
Replay_Record( lua_State* L ) 
{ 
   try { 

        shptr<Replay> replay = POP_USERDATA_AS_SHPTR<Replay>( L );
        CHECK_TYPESIG(replay,TYPESIG_REPLAY);
        lua_pushboolean( L, replay->Record() );
        return 1;  // stack items to return
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * bool Replay:Save( filename )
 *****************************************************************************/
INTERN int 
Replay_Save( lua_State* L ) 
{ 
   try { 

        const string filename = POP_STRING( L );
        shptr<Replay> replay = POP_USERDATA_AS_SHPTR<Replay>( L );
        CHECK_TYPESIG(replay,TYPESIG_REPLAY);
        try
        {
            const bool saved = replay->Save( filename );
            lua_pushboolean( L, saved );
            return 1;
        }
        catch( const Exception& e )
        {
            CERROR << e.what() << std::endl;
        }

        // Failed inside try or threw exception.
        lua_pushboolean( L, false );
        return 1;
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * Replay:Stop()
 * Stop playing or recording (whichever is active).
 *****************************************************************************/
INTERN int 
Replay_Stop( lua_State* L ) 
{ 
   try { 

        shptr<Replay> replay = POP_USERDATA_AS_SHPTR<Replay>( L );
        CHECK_TYPESIG(replay,TYPESIG_REPLAY);
        replay->Stop();
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

//==============================================================================
// Register binding with Lua. 
//==============================================================================

#if ! DOXYGEN 

INTERN const struct luaL_reg sMethodTable[] =
{
  { "New", Replay_New },
  { "__gc", Replay_Destroy },
  { "IfPlaying", Replay_IfPlaying },
  { "Load", Replay_Load },
  { "Play", Replay_Play },
  { "Record", Replay_Record },
  { "Save", Replay_Save },
  { "Stop", Replay_Stop },
  { NULL, NULL }
};

void
RegisterReplay( lua_State* L )
{
    REGISTER_BINDING( L,
                      BIND_METATABLE_NAME,
                      BIND_CLASS_NAME,
                      sMethodTable );
}

#endif // ! DOXYGEN 

} // namespace bind 

} // namespace lua 
