/*****************************************************************************
 * $LastChangedDate: 2011-03-15 14:18:37 -0400 (Tue, 15 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 "graph/module.hh"
#include "graph/scene_graph.hh"
using namespace graph;
#include "object/module.hh"
#include "object/object.hh"
using namespace object;
#include "lua_bind/module.hh"
#include "lua_bind/bind.hh"

namespace lua {


namespace bind {

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

//==============================================================================
// C functions called by Lua that access C++ objects.
//==============================================================================

/*****************************************************************************
 * SceneGraph:AttachObject( Object )
 *****************************************************************************/
INTERN int 
SceneGraph_AttachObject( lua_State* L ) 
{ 
   try { 

        // Attach Object using any graphical attributes defined by the Object.
        shptr<Object> object = POP_USERDATA_AS_SHPTR<Object>( L );
        CHECK_TYPESIG(object,TYPESIG_OBJECT);
        GET_SCENE_GRAPH().AttachObject( object );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * SceneGraph:AttachObjectSpecial( Object, nodeSortTable )
 *****************************************************************************/
INTERN int 
SceneGraph_AttachObjectSpecial( lua_State* L ) 
{ 
   try { 

        // This overrides any graphical attributes defined by the Object itself.

        // Build C++ NodeSort from Lua table members.
        NodeSort::Attribs::Int attribBits = 0;
        string shaderName;

        // Check nodeSortTable.
        CHECK_TYPE_ERROR( L, -1, LUA_TTABLE );

        lua_getfield( L, -1, "shader" );
        if ( IF_STRING( L, -1 ) )
            shaderName = POP_STRING( L );  // pop field
        else
            lua_pop( L, 1 );  // pop field

        lua_getfield( L, -1, "no_shader" );
        if ( IF_BOOL( L, -1 ) )
            attribBits |= NodeSort::Attribs::NO_SHADER;  // assume bool=true
        lua_pop( L, 1 );  // pop field

        lua_getfield( L, -1, "transparent" );
        if ( IF_BOOL( L, -1 ) )
            attribBits |= NodeSort::Attribs::TRANSPARENT;  // assume bool=true
        lua_pop( L, 1 );  // pop field

        lua_getfield( L, -1, "no_depth_test" );
        if ( IF_BOOL( L, -1 ) )
            attribBits |= NodeSort::Attribs::NO_DEPTH_TEST;  // assume bool=true
        lua_pop( L, 1 );  // pop field

        // Pop NodeSort table.
        lua_pop( L, 1 );

        // Pop Object.
        shptr<Object> object = POP_USERDATA_AS_SHPTR<Object>( L );
        CHECK_TYPESIG(object,TYPESIG_OBJECT);

        // This variant of AttachObject() overrides Object::GetNodeSort().
        const NodeSort::Attribs attribs( attribBits );
        GET_SCENE_GRAPH().AttachObject( object, NodeSort( attribs, ShaderName(shaderName) ) );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * SceneGraph:DetachObject( Object )
 *****************************************************************************/
INTERN int 
SceneGraph_DetachObject( lua_State* L ) 
{ 
   try { 

        shptr<Object> object = POP_USERDATA_AS_SHPTR<Object>( L );
        CHECK_TYPESIG(object,TYPESIG_OBJECT);
        GET_SCENE_GRAPH().DetachNode( object->GetRootNode() );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * SceneGraph:Optimize()
 *****************************************************************************/
INTERN int 
SceneGraph_OptimizeSceneGraph( lua_State* L ) 
{ 
   try { 

        GET_SCENE_GRAPH().Optimize();
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * SceneGraph:SaveToFile( string )
 *****************************************************************************/
INTERN int 
SceneGraph_SaveToFile( lua_State* L ) 
{ 
   try { 

        const string filename = POP_STRING( L );
        GET_SCENE_GRAPH().SaveToFile( filename, true/*useCompression*/ );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * SceneGraph:ToggleWireframeMode()
 *****************************************************************************/
INTERN int 
SceneGraph_ToggleWireframeMode( lua_State* L ) 
{ 
   try { 

        GET_SCENE_GRAPH().ToggleWireframeMode();
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

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

#if ! DOXYGEN 

INTERN const struct luaL_reg sMethodTable[] =
{
  // New(),__gc() omitted as Lua cannot instantiate this C++ class.
  { "AttachObject", SceneGraph_AttachObject },
  { "AttachObjectSpecial", SceneGraph_AttachObjectSpecial },
  { "DetachObject", SceneGraph_DetachObject },
  { "OptimizeSceneGraph", SceneGraph_OptimizeSceneGraph },
  { "SaveToFile", SceneGraph_SaveToFile },
  { "ToggleWireframeMode", SceneGraph_ToggleWireframeMode },
  { NULL, NULL }
};

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

#endif // ! DOXYGEN 

} // namespace bind 

} // namespace lua 
