-- $LastChangedDate: 2010-02-20 12:54:37 -0500 (Sat, 20 Feb 2010) $
-- Macros written in Lua to expand C++ code for bindings between C++/Lua.
-- Avoid lua_/LUA_ which is reserved by Lua.
--
-- The SceneGraph C++ class is based on nodes only.
-- But SceneGraph Lua binding extends it with Object args
-- since Lua scripts manipulate Objects instead of nodes.
-- Lua itself serves as a container of 3D Objects
-- while SceneGraph holds its root node.

bindTable = {

class = "SceneGraph",
--typesig = "TYPESIG_SCENE_GRAPH",  -- won't compile
typesig = nil,
luaCanInstantiate = false,

headers =
[[
#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;
]],

func_AttachObject = {
    comments = "SceneGraph:AttachObject( Object )",
    code = [[
        // 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 );
    ]]
},

func_AttachObjectSpecial = {
    comments = "SceneGraph:AttachObjectSpecial( Object, nodeSortTable )",
    code = [[
        // 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) ) );
    ]]
},

func_DetachObject = {
    comments = "SceneGraph:DetachObject( Object )",
    code = [[
        shptr<Object> object = POP_USERDATA_AS_SHPTR<Object>( L );
        CHECK_TYPESIG(object,TYPESIG_OBJECT);
        GET_SCENE_GRAPH().DetachNode( object->GetRootNode() );
    ]]
},

func_OptimizeSceneGraph = {
    comments = "SceneGraph:Optimize()",
    code = [[
        GET_SCENE_GRAPH().Optimize();
    ]]
},

func_SaveToFile = {
    comments = "SceneGraph:SaveToFile( string )",
    code = [[
        const string filename = POP_STRING( L );
        GET_SCENE_GRAPH().SaveToFile( filename, true/*useCompression*/ );
    ]]
},

func_ToggleWireframeMode = {
    comments = "SceneGraph:ToggleWireframeMode()",
    code = [[
        GET_SCENE_GRAPH().ToggleWireframeMode();
    ]]
},

}
