//------------------------------------------------------------------------------
// QContactListener
//------------------------------------------------------------------------------
void QContactListener::BeginContact(b2Contact* pContact)
{
    QNode* pNodeA = (QNode*)pContact->GetFixtureA()->GetBody()->GetUserData();
    QNode* pNodeB = (QNode*)pContact->GetFixtureB()->GetBody()->GetUserData();

    lua_gettop(g_L);

    LUA_EVENT_PREPARE("collision"); // On stack: event
    LUA_EVENT_SET_STRING("phase", "began");
    LUA_EVENT_SET_TOLUA_PTR("nodeA", (void*)pNodeA, pNodeA->_getToLuaClassName());
    LUA_EVENT_SET_TOLUA_PTR("nodeB", (void*)pNodeB, pNodeB->_getToLuaClassName());
    LUA_EVENT_SET_TOLUA_PTR("target", (void*)pNodeA, pNodeA->_getToLuaClassName());

    // World point of collision... is this correct?
    b2WorldManifold wm;
    pContact->GetWorldManifold(&wm);
    float dx = g_Sim->scaleP2D(wm.points[0].x);
    float dy = g_Sim->scaleP2D(wm.points[0].y);
    LUA_EVENT_SET_NUMBER("x", dx);
    LUA_EVENT_SET_NUMBER("y", dy);

    lua_getfield(g_L, LUA_GLOBALSINDEX, "handleNodeEvent");
	lua_pushvalue(g_L, -2); // On stack: handleNodeEvent(event)
    tolua_pushusertype(g_L, (void*)pNodeA, pNodeA->_getToLuaClassName()); // On stack: handleNodeEvent(event, node)

    lua_gettop(g_L);
    int s = lua_pcall(g_L, 2, 1, 0);
    lua_gettop(g_L);
    LUA_REPORT_ERRORS(g_L, s);
    lua_gettop(g_L);
    lua_pop(g_L, 3);
    lua_gettop(g_L);
}
//------------------------------------------------------------------------------
void QContactListener::EndContact(b2Contact* pContact)
{
    QNode* pNodeA = (QNode*)pContact->GetFixtureA()->GetBody()->GetUserData();
    QNode* pNodeB = (QNode*)pContact->GetFixtureB()->GetBody()->GetUserData();

    lua_gettop(g_L);

    LUA_EVENT_PREPARE("collision"); // On stack: event
    LUA_EVENT_SET_STRING("phase", "ended");
    LUA_EVENT_SET_TOLUA_PTR("nodeA", (void*)pNodeA, pNodeA->_getToLuaClassName());
    LUA_EVENT_SET_TOLUA_PTR("nodeB", (void*)pNodeB, pNodeB->_getToLuaClassName());
    LUA_EVENT_SET_TOLUA_PTR("target", (void*)pNodeA, pNodeA->_getToLuaClassName());

    lua_getfield(g_L, LUA_GLOBALSINDEX, "handleNodeEvent");
	lua_pushvalue(g_L, -2); // On stack: handleNodeEvent(event)
    tolua_pushusertype(g_L, (void*)pNodeA, pNodeA->_getToLuaClassName()); // On stack: handleNodeEvent(event, node)

    lua_gettop(g_L);
    int s = lua_pcall(g_L, 2, 1, 0);
    lua_gettop(g_L);
    LUA_REPORT_ERRORS(g_L, s);
    lua_gettop(g_L);
    lua_pop(g_L, 3);
    lua_gettop(g_L);
}
//------------------------------------------------------------------------------
void QContactListener::PostSolve(b2Contact* pContact, const b2ContactImpulse* pImpulse)
{
    QNode* pNodeA = (QNode*)pContact->GetFixtureA()->GetBody()->GetUserData();
    QNode* pNodeB = (QNode*)pContact->GetFixtureB()->GetBody()->GetUserData();

    LUA_EVENT_PREPARE("collisionPostSolve"); // On stack: event
    LUA_EVENT_SET_STRING("phase", "ended");
    LUA_EVENT_SET_TOLUA_PTR("nodeA", (void*)pNodeA, pNodeA->_getToLuaClassName());
    LUA_EVENT_SET_TOLUA_PTR("nodeB", (void*)pNodeB, pNodeB->_getToLuaClassName());
    LUA_EVENT_SET_TOLUA_PTR("target", (void*)pNodeA, pNodeA->_getToLuaClassName());
    QContact con(pContact);
    LUA_EVENT_SET_TOLUA_PTR("contact", (void*)&con, "quick::QPhysics::Contact");

    // Force (impulse)
    float f = g_Sim->scaleP2D(pImpulse->normalImpulses[0]);
    LUA_EVENT_SET_NUMBER("impulse", f);

    lua_getfield(g_L, LUA_GLOBALSINDEX, "handleNodeEvent");
	lua_pushvalue(g_L, -2); // On stack: handleNodeEvent(event)
    tolua_pushusertype(g_L, (void*)pNodeA, pNodeA->_getToLuaClassName()); // On stack: handleNodeEvent(event, node)

    int s = lua_pcall(g_L, 2, 1, 0);
    LUA_REPORT_ERRORS(g_L, s);
    lua_pop(g_L, 2);

    lua_gettop(g_L);
}