/*****************************************************************************
 * $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 "view/module.hh"
#include "view/view.hh"
#include "view/viewpoint_chase.hh"
#include "view/window.hh"
using namespace view;
#include "lua_bind/module.hh"
#include "lua_bind/bind.hh"

namespace lua {


namespace bind {

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

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

        return DESTROY_USERDATA_SHPTR<View>( L, CheckTypesigView );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * View:Enable()
 *****************************************************************************/
INTERN int 
View_Enable( lua_State* L ) 
{ 
   try { 

        const bool enable = POP_BOOL( L );

        shptr<View> view = POP_USERDATA_AS_SHPTR<View>( L );
        CHECK_TYPESIG(view,TYPESIG_VIEW);

        view->Enable( enable );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * View:EnableObjectInMainView()
 *****************************************************************************/
INTERN int 
View_EnableObjectInMainView( lua_State* L ) 
{ 
   try { 

        const bool enable = POP_BOOL( L );
        shptr<Object> object = POP_USERDATA_AS_SHPTR<Object>( L );

        View::EnableObjectInMainView( *object, enable );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * bool View:IfEnabled()
 *****************************************************************************/
INTERN int 
View_IfEnabled( lua_State* L ) 
{ 
   try { 

        shptr<View> view = POP_USERDATA_AS_SHPTR<View>( L );
        CHECK_TYPESIG(view,TYPESIG_VIEW);
        lua_pushboolean( L, view->IfEnabled() );
        return 1;  // stack items to return
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * View:New( {x1,y1,x2,y2} ) -- See C++ View::SetRect()
 *****************************************************************************/
INTERN int 
View_New( lua_State* L ) 
{ 
   try { 

        // Pop rectangle table {x1,y1,x2,y2}.
        const Rect<int> rect = POP_TABLE_INTO_RECT( L );

        // Default to chase-view.
        shptr<View> view = new View( ENABLE, rect, new ChaseViewpoint );

        // And add View to Window for Lua.
        GET_WINDOW().AddView( view );

        return NEW_USERDATA_SHPTR<View>( L, view, BIND_METATABLE_NAME );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * View:SetOutlineColor( RGBA )
 *****************************************************************************/
INTERN int 
View_SetOutlineColor( lua_State* L ) 
{ 
   try { 

        const RGBA outlineColor( POP_RGBA( L ) );
        shptr<View> view = POP_USERDATA_AS_SHPTR<View>( L );
        CHECK_TYPESIG(view,TYPESIG_VIEW);

        view->SetOutlineColor( outlineColor );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * View:SetRect(x1,y1,x2,y2) (set viewport: (x1,y1) = bottom-left (x2,y2) = top-right)
 *****************************************************************************/
INTERN int 
View_SetRect( lua_State* L ) 
{ 
   try { 

        // Set viewport area.
        const LuaNumber y2 = POP_NUMBER( L );
        const LuaNumber x2 = POP_NUMBER( L );
        const LuaNumber y1 = POP_NUMBER( L );
        const LuaNumber x1 = POP_NUMBER( L );
        shptr<View> view     = POP_USERDATA_AS_SHPTR<View>( L );
        CHECK_TYPESIG(view,TYPESIG_VIEW);
        view->SetRect( Rect<int>( x1, y1, x2, y2 ) );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * View:SetViewpoint()
 *****************************************************************************/
INTERN int 
View_SetViewpoint( lua_State* L ) 
{ 
   try { 

        shptr<Viewpoint> viewpoint = POP_USERDATA_AS_SHPTR<Viewpoint>( L );
        CHECK_TYPESIG(viewpoint,TYPESIG_VIEWPOINT);

        shptr<View> view = POP_USERDATA_AS_SHPTR<View>( L );
        CHECK_TYPESIG(view,TYPESIG_VIEW);

        view->SetViewpoint( viewpoint );
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

/*****************************************************************************
 * Vec3 View:TransformWorld2Eye( x,y,z|Vec3 )
 *****************************************************************************/
INTERN int 
View_TransformWorld2Eye( lua_State* L ) 
{ 
   try { 

        const WorldVertex wv = POP_VECTOR3<WorldVertex>( L );

        shptr<View> view = POP_USERDATA_AS_SHPTR<View>( L );
        CHECK_TYPESIG(view,TYPESIG_VIEW);

        const EyeVertex ev = view->TransformWorld2Eye( wv );
        PUSH_VECTOR3( L, ev );
        return 1;  // stack items to return
    
   } CATCH_LUA_EXCEPTION 
   return 0; 
} 

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

#if ! DOXYGEN 

INTERN const struct luaL_reg sMethodTable[] =
{
  { "New", View_New },
  { "__gc", View_Destroy },
  { "Enable", View_Enable },
  { "EnableObjectInMainView", View_EnableObjectInMainView },
  { "IfEnabled", View_IfEnabled },
  { "SetOutlineColor", View_SetOutlineColor },
  { "SetRect", View_SetRect },
  { "SetViewpoint", View_SetViewpoint },
  { "TransformWorld2Eye", View_TransformWorld2Eye },
  { NULL, NULL }
};

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

#endif // ! DOXYGEN 

} // namespace bind 

} // namespace lua 
