/*****************************************************************************
 * $LastChangedDate: 2011-03-17 19:59:52 -0400 (Thu, 17 Mar 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"
using namespace base;
#include "object/module.hh"
#include "object/dyna.hh"
using namespace object;
#include "graph/module.hh"
#include "graph/model_cache.hh"
using namespace graph;
#include "lua_bind/module.hh"
#include "lua_bind/bind.hh"

namespace lua {


namespace bind {

#define BIND_CLASS_NAME      "Dyna"
#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
CheckTypesigDyna( shptr<Dyna> obj )
{
    CHECK_TYPESIG(obj,TYPESIG_DYNA);
}
#endif // ! DOXYGEN

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

        return DESTROY_USERDATA_SHPTR<Dyna>( L, CheckTypesigDyna );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * table Dyna:GetMatrix()
 *****************************************************************************/
INTERN int 
Dyna_GetMatrix( lua_State* L ) 
{ 
   try { 

        shptr<Dyna> dyna = POP_USERDATA_AS_SHPTR<Dyna>( L );
        CHECK_TYPESIG(dyna,TYPESIG_DYNA);
        PUSH_TABLE_FROM_MATRIX( L, dyna->GetMatrix() );
        return 1;  // stack items to return
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * string Dyna:GetName()
 *****************************************************************************/
INTERN int 
Dyna_GetName( lua_State* L ) 
{ 
   try { 

        Dyna* dyna = POP_USERDATA_AS_SHPTR<Dyna>( L ).PTR();
        CHECK_TYPESIG(dyna,TYPESIG_DYNA);
        lua_pushstring( L, dyna->GetName().c_str() );
        return 1;  // stack items to return
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * Vec3 Dyna:GetPosition()
 *****************************************************************************/
INTERN int 
Dyna_GetPosition( lua_State* L ) 
{ 
   try { 

        shptr<Dyna> dyna = POP_USERDATA_AS_SHPTR<Dyna>( L );
        CHECK_TYPESIG(dyna,TYPESIG_DYNA);
        const WorldVertex pos = dyna->GetPosition();
        PUSH_VECTOR3( L, pos );
        return 1;  // stack items to return
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * number Dyna:GetRawPtr()
 *****************************************************************************/
INTERN int 
Dyna_GetRawPtr( lua_State* L ) 
{ 
   try { 

        Dyna* dyna = POP_USERDATA_AS_SHPTR<Dyna>( L ).PTR();
        CHECK_TYPESIG(dyna,TYPESIG_DYNA);
        lua_pushnumber( L, long(static_cast<Dyna*>(dyna)) );
        return 1;  // stack items to return
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * bool Dyna:IfCollidable()
 *****************************************************************************/
INTERN int 
Dyna_IfCollidable( lua_State* L ) 
{ 
   try { 

        shptr<Dyna> dyna = POP_USERDATA_AS_SHPTR<Dyna>( L );
        CHECK_TYPESIG(dyna,TYPESIG_DYNA);
        lua_pushboolean( L, dyna->IfCollidable() );
        return 1;  // stack items to return
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * bool Dyna:IfCollision()
 *****************************************************************************/
INTERN int 
Dyna_IfCollision( lua_State* L ) 
{ 
   try { 

        shptr<Dyna> dyna = POP_USERDATA_AS_SHPTR<Dyna>( L );
        CHECK_TYPESIG(dyna,TYPESIG_DYNA);
        lua_pushboolean( L, dyna->IfCollision() );
        return 1;  // stack items to return
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * bool Dyna:IfCollisionFatal()
 *****************************************************************************/
INTERN int 
Dyna_IfCollisionFatal( lua_State* L ) 
{ 
   try { 

        shptr<Dyna> dyna = POP_USERDATA_AS_SHPTR<Dyna>( L );
        CHECK_TYPESIG(dyna,TYPESIG_DYNA);
        lua_pushboolean( L, dyna->IfCollisionFatal() );
        return 1;  // stack items to return
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * bool Dyna:IfZombie()
 *****************************************************************************/
INTERN int 
Dyna_IfZombie( lua_State* L ) 
{ 
   try { 

        shptr<Dyna> dyna = POP_USERDATA_AS_SHPTR<Dyna>( L );
        CHECK_TYPESIG(dyna,TYPESIG_DYNA);
        lua_pushboolean( L, dyna->IfZombie() );
        return 1;  // stack items to return
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * Dyna:New( x,y,z|Vec3, modelPathname, scale, ModelCache.LOAD_SHARED|LOAD_COPY )
 *****************************************************************************/
INTERN int 
Dyna_New( lua_State* L ) 
{ 
   try { 

        const bool        loadCopy  = POP_BOOL( L );
        const fp          scale     = POP_FP( L );
        const string      modelName = POP_STRING( L );
        const WorldVertex pos       = POP_VECTOR3<WorldVertex>( L );

        // Load 3D model.
        shptr<Graph> graph = GET_MODEL_CACHE().LoadModel( modelName, scale, loadCopy );
        shptr<Dyna>  dyna  = new Dyna( graph, pos );

        return NEW_USERDATA_SHPTR<Dyna>( L, dyna, BIND_METATABLE_NAME );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * Dyna:Reset()
 *****************************************************************************/
INTERN int 
Dyna_Reset( lua_State* L ) 
{ 
   try { 

        shptr<Dyna> dyna = POP_USERDATA_AS_SHPTR<Dyna>( L );
        CHECK_TYPESIG(dyna,TYPESIG_DYNA);
        dyna->Reset();
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * Dyna:Rotate( axis, radian )
 *****************************************************************************/
INTERN int 
Dyna_Rotate( lua_State* L ) 
{ 
   try { 

        const fp   radian = POP_FP( L );
        const uint axis   = POP_INT( L );
        shptr<Dyna> dyna = POP_USERDATA_AS_SHPTR<Dyna>( L );
        CHECK_TYPESIG(dyna,TYPESIG_DYNA);
        dyna->Rotate( axis, radian );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * Dyna:SetCollidable( bool )
 *****************************************************************************/
INTERN int 
Dyna_SetCollidable( lua_State* L ) 
{ 
   try { 

        const bool f = POP_BOOL( L );
        shptr<Dyna> dyna = POP_USERDATA_AS_SHPTR<Dyna>( L );
        CHECK_TYPESIG(dyna,TYPESIG_DYNA);
        dyna->SetCollidable( f );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * Dyna:SetCollision( int )
 *****************************************************************************/
INTERN int 
Dyna_SetCollision( lua_State* L ) 
{ 
   try { 

        const int collision = POP_INT( L );
        shptr<Dyna> dyna = POP_USERDATA_AS_SHPTR<Dyna>( L );
        CHECK_TYPESIG(dyna,TYPESIG_DYNA);
        dyna->SetCollision( static_cast<Dyna::eCollision>( collision ) );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * Dyna:SetMatrix( matrix )
 *****************************************************************************/
INTERN int 
Dyna_SetMatrix( lua_State* L ) 
{ 
   try { 

        Matrix m; POP_TABLE_INTO_MATRIX( L, m );
        shptr<Dyna> dyna = POP_USERDATA_AS_SHPTR<Dyna>( L );
        CHECK_TYPESIG(dyna,TYPESIG_DYNA);
        dyna->SetMatrix( m, Dyna::PLACEMENT );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * Dyna:SetPosition( x,y,z|Vec3 )
 *****************************************************************************/
INTERN int 
Dyna_SetPosition( lua_State* L ) 
{ 
   try { 

        const WorldVertex pos = POP_VECTOR3<WorldVertex>( L );
        shptr<Dyna> dyna = POP_USERDATA_AS_SHPTR<Dyna>( L );
        CHECK_TYPESIG(dyna,TYPESIG_DYNA);
        dyna->SetPosition( pos );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * Dyna:Zombify()
 *****************************************************************************/
INTERN int 
Dyna_Zombify( lua_State* L ) 
{ 
   try { 

        shptr<Dyna> dyna = POP_USERDATA_AS_SHPTR<Dyna>( L );
        CHECK_TYPESIG(dyna,TYPESIG_DYNA);
        dyna->Zombify();
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

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

#if ! DOXYGEN 

INTERN const struct luaL_reg sMethodTable[] =
{
  { "New", Dyna_New },
  { "__gc", Dyna_Destroy },
  { "GetMatrix", Dyna_GetMatrix },
  { "GetName", Dyna_GetName },
  { "GetPosition", Dyna_GetPosition },
  { "GetRawPtr", Dyna_GetRawPtr },
  { "IfCollidable", Dyna_IfCollidable },
  { "IfCollision", Dyna_IfCollision },
  { "IfCollisionFatal", Dyna_IfCollisionFatal },
  { "IfZombie", Dyna_IfZombie },
  { "Reset", Dyna_Reset },
  { "Rotate", Dyna_Rotate },
  { "SetCollidable", Dyna_SetCollidable },
  { "SetCollision", Dyna_SetCollision },
  { "SetMatrix", Dyna_SetMatrix },
  { "SetPosition", Dyna_SetPosition },
  { "Zombify", Dyna_Zombify },
  { NULL, NULL }
};

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

#endif // ! DOXYGEN 

} // namespace bind 

} // namespace lua 
