// ----------------------------------------------------------------------------
// Include the main OGRE header files
// Ogre.h just expands to including lots of individual OGRE header files
// ----------------------------------------------------------------------------
#include <Ogre.h>
// ----------------------------------------------------------------------------
// Include the OGRE example framework
// This includes the classes defined to make getting an OGRE application running
// a lot easier. It automatically sets up all the main objects and allows you to
// just override the bits you want to instead of writing it all from scratch.
// ----------------------------------------------------------------------------
#include <ExampleApplication.h>

// ----------------------------------------------------------------------------
// Define the application object
// This is derived from ExampleApplication which is the class OGRE provides to
// make it easier to set up OGRE without rewriting the same code all the time.
// You can override extra methods of ExampleApplication if you want to further
// specialise the setup routine, otherwise the only mandatory override is the
// 'createScene' method which is where you set up your own personal scene.
// ----------------------------------------------------------------------------

// ----------------------------------------------------------------------------

class MyFirstListener : public ExampleFrameListener, public OIS::KeyListener, public OIS::MouseListener
{
    private:
    protected:
    public:
    MyFirstListener(RenderWindow* win, Camera* cam, const std::string &debugText) : ExampleFrameListener(win, cam)
    {
        mDebugText = debugText;
        mMouse->setEventCallback(this);
        mKeyboard->setEventCallback(this);
    }

    bool frameStarted(const FrameEvent& evt)
    {
        if(ExampleFrameListener::frameStarted(evt)==false)
            return false;

            //do stuff here

        return true;
    }

    bool mouseMoved(const OIS::MouseEvent &arg)
    {
        return true;
    }

    bool mousePressed(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
    {
        return true;
    }

    bool mouseReleased(const OIS::MouseEvent &arg, OIS::MouseButtonID id)
    {
        return true;
    }

    bool keyPressed(const OIS::KeyEvent &arg)
    {
        return true;
    }

    bool keyReleased(const OIS::KeyEvent &arg)
    {
        return true;
    }
};

// ----------------------------------------------------------------------------

class SampleApp : public ExampleApplication
{
public:
    std::string mDebugText;

    // Basic constructor
    SampleApp()
    {mDebugText="";}

protected:

    // Just override the mandatory create scene method
    void createScene(void)
    {
        // Create the SkyBox
        mSceneMgr->setSkyBox(true, "Examples/CloudyNoonSkyBox");

        // Create a light
        Light* myLight = mSceneMgr->createLight("Light0");
        myLight->setType(Light::LT_POINT);
        myLight->setPosition(0, 40, 0);
        myLight->setDiffuseColour(1, 1, 1);
        myLight->setSpecularColour(1, 1, 1);

        Entity *ent = mSceneMgr->createEntity("head", "ogrehead.mesh");

        mSceneMgr->getRootSceneNode()->createChildSceneNode()->attachObject(ent);
    }

    void createFrameListener(void)
    {
        mFrameListener = new MyFirstListener(mWindow, mCamera, mDebugText);

        if(mFrameListener)
            mRoot->addFrameListener(mFrameListener);
    }
};


// ----------------------------------------------------------------------------
// Main function, just boots the application object
// ----------------------------------------------------------------------------
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
#define WIN32_LEAN_AND_MEAN
#include "windows.h"
INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )
#else
int main(int argc, char **argv)
#endif
{
    // Create application object
    SampleApp app;

    try
    {
        app.go();
    }
    catch( Exception& e )
    {
#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
        MessageBox( NULL, e.getFullDescription().c_str(), "An exception has occured!", MB_OK | MB_ICONERROR | MB_TASKMODAL);
#else

        std::cerr << "An exception has occured: " << e.getFullDescription();
#endif
    }

    return 0;
}
