#ifndef __GAMEFRAMELISTENER_H__
#define __GAMEFRAMELISTENER_H__

#include "Ogre.h"
#include "OgreKeyEvent.h"
#include "OgreEventListeners.h"
#include "OgreStringConverter.h"
#include "OgreException.h"

#include "CEGUI_fix.h"

#include "GameWorldClient.h"

using namespace Ogre;
using namespace DinastyOnline::Network;

namespace DinastyOnline {
	namespace Graphics {

		class GameFrameListener: public FrameListener, public KeyListener, public MouseListener, public MouseMotionListener {
		protected:
			Real mMoveSpeed;
			Degree mRotateSpeed;
			Overlay* mDebugOverlay;

			EventProcessor* mEventProcessor;
			Camera* mCamera;

			RenderWindow* mWindow;

			RaySceneQuery *mRaySceneQuery;	   // The ray scene query pointer
			SceneManager *mSceneMgr;		   // A pointer to the scene manager
			CEGUI::Renderer *mGUIRenderer;	   // cegui renderer
			bool mLMouseDown, mRMouseDown;	   // True if the mouse buttons are down
			SceneNode *mCamNode;			// The SceneNode the camera is currently attached to
			bool mContinue;					// Whether to continue rendering or not
			Vector3 mDirection;				// Value to move the camera in the correct direction

			AnimationState *mAnimationState; // The current animation state of the object
			Real mWalkSpeed;				 // The speed at which the object is moving
			Real mDistance;					 // The distance the object has left to travel
			Vector3 mWalkDirection;			 // The direction the object is moving
			Vector3 mDestination;			 // The destination the object is moving towards
			std::deque<Vector3> mWalkList;	 // The list of points we are walking to
			int mCount;
			bool menuInteraction;			// For changing how input is controlled
			bool gameStarted;
			
			GameWorldClient *world;

			void updateStats(void);

		public:
			GameFrameListener(RenderWindow* win, Camera* cam, SceneManager *sceneManager, CEGUI::Renderer *renderer, std::deque<Vector3> &walk);

			virtual ~GameFrameListener();

			/// When a CEGUI menu appears, the framelistener has to operate in a different way
			void setMenuInteraction(bool interaction);

			/// Main menu closed and scene created, we can init
			void startGame(GameWorldClient *world);

			/// Stop
			void requestShutdown(void);

			/// Debug info
			void showDebugOverlay(bool show);

			/// Update movements
			bool frameStarted(const FrameEvent& evt);

			bool frameEnded(const FrameEvent& evt);
			/// Keyboard interaction
			void keyClicked(KeyEvent* e);
			void keyPressed(KeyEvent* e);
			void keyReleased(KeyEvent* e);

			/// Mouse interaction
			virtual void mouseClicked(MouseEvent* e);
			virtual void mouseEntered(MouseEvent* e);
			virtual void mouseExited(MouseEvent* e);
			virtual void mousePressed(MouseEvent* e);
			virtual void mouseReleased(MouseEvent* e);
			virtual void mouseMoved (MouseEvent *e);
			// This is when the mouse is clicked, held and dragged.
			virtual void mouseDragged (MouseEvent *e);

			/// Rotate the robot with the correct orientation
			bool rotateRobot();

		};

	}
}

#endif

