/*
-----------------------------------------------------------------------------
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt.
-----------------------------------------------------------------------------
*/

/**
    \file 
        test.h
    \brief
        Small aplication to play with Ogre engine.
    \author
        Luis Javier Fornero
*/


#include "ExampleApplication.h"

typedef struct _Veritech
{
	AnimationState* mAnimState1;
	AnimationState* mAnimState2;
	Entity *entity;
	SceneNode* node;
	
} Veritech;


class RobotechFrameListener : public ExampleFrameListener
{
protected:

	SceneNode* mVFNode;
	AnimationState* mVFAnimationState1;
	AnimationState* mVFAnimationState2;
	Entity * mVFEntity;

public:
    SpaceFrameListener(RenderWindow* win, Camera* cam, Veritech *robot) : ExampleFrameListener(win, cam)
    {

		mVFNode = robot->node;
		mVFEntity = robot->entity;
        // Walk animation
		mVFAnimationState1 = robot->mAnimState1;
		// ComeOne animation
		mVFAnimationState2 = robot->mAnimState2;

    };

    bool frameStarted(const FrameEvent& evt)
    {
		// Move upto 20 units/second
		Real MoveFactor = 20.0 * evt.timeSinceLastFrame;

		// Copy the current state of the input devices
		if(!ExampleFrameListener::frameStarted(evt))
            return false;

		mInputDevice->capture();

		// Move the ship node!
		if(mInputDevice->isKeyDown(Ogre::KC_I))
		{
			// Play Walk animation and translate
			mVFNode->translate(0.0, 0.0, MoveFactor);
			mVFAnimationState2->addTime(evt.timeSinceLastFrame);
		
		}

		if(mInputDevice->isKeyDown(Ogre::KC_K))
		{
		  // Play ComeOn animation and translate		
		  mVFNode->translate(0.0, 0.0, -MoveFactor);
		  mVFAnimationState1->addTime(evt.timeSinceLastFrame);
		}

		if(mInputDevice->isKeyDown(Ogre::KC_J))
		{
		  mVFNode->translate(-MoveFactor, 0.0, 0.0);
		}

		if(mInputDevice->isKeyDown(Ogre::KC_L))
		{
		  mVFNode->translate(MoveFactor, 0.0, 0.0);
		}

		return true;
    }

};

class RobotechApplication : public ExampleApplication
{
protected:
	Veritech VF;
	SceneNode* node;

	void createScene(void)
    {
		// Set a low level of ambient lighting so we can see the ship
		mSceneMgr->setAmbientLight(ColourValue(0.5, 0.5, 0.5));

        // Use the "Canyon" skybox
        mSceneMgr->setSkyBox(true, "Examples/canyon");

		// Load "vf1j", our Robotech Mech
		VF.entity = mSceneMgr->createEntity("vf1j", "vf1j.mesh");
		// Set its material name
		VF.entity->setMaterialName("vf1j_text");

		// Create a Scene Node and attach our mech to it
		VF.node = static_cast<SceneNode*>(mSceneMgr->getRootSceneNode()->createChild());
		VF.node->attachObject(VF.entity);
		// move it 10 units up (feets will be on the ground)
		VF.node->translate(0, 10, 0);
		// Small animation, shake hands and move lazers		
		VF.mAnimState1 = VF.entity->getAnimationState("ComeOn");
		VF.mAnimState1->setEnabled(true);
		// Move legs
		VF.mAnimState2 = VF.entity->getAnimationState("Walk");
		VF.mAnimState2->setEnabled(true);

		// Create a light
        Light* l = mSceneMgr->createLight("MainLight");
        // Point light, warm colour and set position
        l->setPosition(-20,0,0);
		l->setDiffuseColour( 231,206,134);
		
    }

	void createFrameListener(void)
    {
		// This is where we instantiate our own frame listener
        mFrameListener= new SpaceFrameListener(mWindow, mCamera, &VF);
        mRoot->addFrameListener(mFrameListener);
    }

    virtual void chooseSceneManager(void)
    {
        // Get the SceneManager, in this case a generic one
        mSceneMgr = mRoot->getSceneManager( ST_EXTERIOR_CLOSE );
    }


};