-- $LastChangedDate: 2011-03-17 19:59:52 -0400 (Thu, 17 Mar 2011) $
-- Macros written in Lua to expand C++ code for bindings between C++/Lua.
-- Avoid lua_/LUA_ which is reserved by Lua.

bindTable = {

class = "Aircraft",
typesig = "TYPESIG_AIRCRAFT",
luaCanInstantiate = true,

headers =
[[
#include "base/module.hh"
using namespace base;
#include "object/module.hh"
#include "object/aircraft.hh"
using namespace object;
#include "program/module.hh"
#include "program/aircraft_models.hh"
using namespace program;
]],

func_New = {
    comments = "Aircraft:New( x,y,z|Vec3, Aircraft::eType, ModelCache.LOAD_SHARED|LOAD_COPY )",
    code = [[
        const bool          loadCopy     = POP_BOOL( L );
        const eAircraftType aircraftType = static_cast<eAircraftType>( POP_INT( L ) );
        const WorldVertex   pos          = POP_VECTOR3<WorldVertex>( L );
        shptr<Aircraft> aircraft = program::MakeAircraft( aircraftType, pos, loadCopy );
        return NEW_USERDATA_SHPTR<Aircraft>( L, aircraft, BIND_METATABLE_NAME );
    ]]
},

func_Destroy = {
    comments = "Lua's garbage collector indirectly invokes this C++ destructor.",
    code = [[
        return DESTROY_USERDATA_SHPTR<Aircraft>( L, CheckTypesigAircraft );
    ]]
},

func_SetState = {
    comments = "Aircraft:SetState( eState )",
    code = [[
        const Aircraft::eState state = static_cast<Aircraft::eState>( POP_INT( L ) );
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        aircraft->SetState( state );
    ]]
},

func_GetState = {
    comments = "eState Aircraft:GetState()",
    code = [[
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        lua_pushnumber( L, aircraft->GetState() );
        return 1;  // stack items to return
    ]]
},

func_PhysicalRotate = {
    comments = "Aircraft:PhysicalRotate( axis, controlFraction, controlFreq )",
    code = [[
        const Milliseconds controlFreq( POP_INT( L ) );
        const fp controlFrac = POP_FP( L );
        const uint axis  = POP_INT( L );
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        aircraft->PhysicalRotate( axis, controlFrac, controlFreq );
    ]]
},

func_GetPhysics = {
    comments = "Aircraft:GetPhysics()",
    code = [[
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        return NEW_USERDATA_PTR( L,
                                 &aircraft->GetPhysics(),
                                 LUABIND_METATABLE_STRING("AircraftPhysics") );
    ]]
},

func_GetThrottle = {
    comments = "fp Aircraft:GetThrottle()",
    code = [[
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        lua_pushnumber( L, aircraft->GetThrottle() );
        return 1;  // stack items to return
    ]]
},

func_SetThrottle = {
    comments = "Aircraft:SetThrottle( fp )",
    code = [[
        const fp throttle = POP_FP( L );
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        aircraft->SetThrottle( throttle );
    ]]
},

func_SetLandingGear = {
    comments = "Aircraft:SetLandingGear( bool ) / down=true"
            .. "\n * SUBTLE: This is a NOP is speed is zero."
            .. "\n * Use sim.LANDING_GEAR_UP/DOWN.",
    code = [[
        const bool down = POP_BOOL( L );
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        aircraft->SetLandingGear( down );
    ]]
},

func_IfLandingGear = {
    comments = "bool Aircraft:IfLandingGear() / down=true",
    code = [[
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        lua_pushboolean( L, aircraft->IfLandingGear() );
        return 1;  // stack items to return
    ]]
},

func_ToggleLandingGear = {
    comments = "bool Aircraft:ToggleLandingGear() / returns true if landing gear changed state",
    code = [[
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        const bool state = aircraft->IfLandingGear();
        aircraft->SetLandingGear( not state );
        lua_pushboolean( L, state != aircraft->IfLandingGear() );  // true if state changed
        return 1;  // stack items to return
    ]]
},

func_EnableBrakes = {
    comments = "Aircraft:EnableBrakes(bool)",
    code = [[
        const bool enable = POP_BOOL( L );
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        aircraft->EnableBrakes( enable );
    ]]
},

func_ToggleBrakes = {
    comments = "Aircraft:ToggleBrakes()",
    code = [[
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        aircraft->EnableBrakes( not aircraft->IfBrakes() );
    ]]
},

func_IfBrakes = {
    comments = "bool Aircraft:IfBrakes()",
    code = [[
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        lua_pushboolean( L, aircraft->IfBrakes() );
        return 1;  // stack items to return
    ]]
},

func_IfWheelBrakes = {
    comments = "bool Aircraft:IfWheelBrakes()",
    code = [[
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        lua_pushboolean( L, aircraft->IfWheelBrakes() );
        return 1;  // stack items to return
    ]]
},

func_IfHasPropeller = {
    comments = "bool Aircraft:IfHasPropeller()",
    code = [[
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        lua_pushboolean( L, aircraft->IfHasPropeller() );
        return 1;  // stack items to return
    ]]
},

func_EnableCoordinatedTurn = {
    comments = "Aircraft:EnableCoordinatedTurn( bool )",
    code = [[
        const bool coturn = POP_BOOL( L );
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        aircraft->EnableCoordinatedTurn( coturn );
    ]]
},

func_IfCoordinatedTurnEnabled = {
    comments = " bool Aircraft:IfCoordinatedTurnEnabled()",
    code = [[
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        lua_pushboolean( L, aircraft->IfCoordinatedTurnEnabled() );
        return 1;  // stack items to return
    ]]
},

func_IfCoordinatedTurnExecuting = {
    comments = "bool Aircraft:IfCoordinatedTurnExecuting()",
    code = [[
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        lua_pushboolean( L, aircraft->IfCoordinatedTurnExecuting() );
        return 1;  // stack items to return
    ]]
},

func_PlayEngineSound = {
    comments = "Aircraft.PlayEngineSound( volume )",
    code = [[
        const fp volume = POP_FP( L );
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        aircraft->PlayEngineSound( volume );
    ]]
},

func_StopEngineSound = {
    comments = "Aircraft.StopEngineSound()",
    code = [[
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        aircraft->StopEngineSound();
    ]]
},

func_SwingWings = {
    comments = "Aircraft:SwingWings( fraction ) safe NOP if not swing-wing aircraft",
    code = [[
        const fp fraction = POP_FP( L );
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        aircraft->SwingWings( fraction );
    ]]
},

func_SwingBayDoors = {
    comments = "Aircraft:SwingBayDoors( fraction ) safe NOP if aircraft has no bay",
    code = [[
        const fp fraction = POP_FP( L );
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        aircraft->SwingBayDoors( fraction );
    ]]
},

func_SetShadowCaster = {
    comments = "Aircraft:SetShadowCaster( bool )",
    code = [[
        // Should be called prior to SceneGraph::AttachObject() else no effect.
        const bool enable = POP_BOOL( L );
        shptr<Aircraft> aircraft = POP_USERDATA_AS_SHPTR<Aircraft>( L );
        CHECK_TYPESIG(aircraft,TYPESIG_AIRCRAFT);
        aircraft->SetShadowCaster( enable );
    ]]
},

}

--------------------------------------------------------------------------------
-- Inherit Object methods.
function InheritMethod( code )
    code = string.gsub( code, "object", "aircraft" )
    code = string.gsub( code, "Object", "Aircraft" )
    code = string.gsub( code, "OBJECT", "AIRCRAFT" )
    return code
end
dofile( srcDir .. "bind_object_common.lua" )
