//	Application.h - Class handling the various application bits and pieces.
//  ----------------------------------------------------------------------------
//	This file is part of 'GameTemplate', a game.
//	Copyright (C) 2009  Niall Moody
//	
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 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 General Public License for more details.
//
//	You should have received a copy of the GNU General Public License
//	along with this program.  If not, see <http://www.gnu.org/licenses/>.
//	----------------------------------------------------------------------------

#ifndef APPLICATION_H_
#define APPLICATION_H_

#include "NiallsDrawingLib/Drawer.h"
#include "sound/BackgroundMusic.h"
#include "PortAudioDevice.h"

#include "SDL.h"
#include <vector>
#include <string>

class GameState;
typedef std::vector<std::string> CmdLineParams;

///	Class handling the various application bits and pieces.
class Application : public PortAudioCallback
{
  public:
	///	Constructor.
	/*!
		\param commandLine A vector containing all the command line parameters
		passed in.

		This will call SDL_Init() with the SDL_INIT_VIDEO and SDL_INIT_TIMER
		flags.  It will also open a window according to the command line
		arguments (e.g. fullscreen/windowed, geometry, bit depth etc.).
	 */
	Application(const CmdLineParams &commandLine);
	///	Destructor.
	/*!
		Will call SDL_Quit().
	 */
	~Application();

	///	Where the sound is generated and sent to the soundcard.
	void getAudio(float *input, float *output, int numSamples);

	///	The main event loop occurs inside this method.
	void eventLoop();

	///	Moves to the next state.
	void nextState(const std::string state);
	///	Quits the game.
	void quit();
  private:
	///	Called when a key down event is received.
	void keyDown(const SDL_keysym& keyPressed);
	///	Called when a key up event is received.
	void keyUp(const SDL_keysym& keyPressed);

	///	Called when a mouse down event is received.
	void mouseDown(int button, int posX, int posY);
	///	Called when a mouse up event is received.
	void mouseUp(int button, int posX, int posY);
	///	Called when a mouse move event is received.
	void mouseMove(int posX, int posY);

	///	Called when a joystick y axis changes.
	void joyYMove(bool dir);
	///	Called when a joystick x axis changes.
	void joyXMove(bool dir);
	///	Called when a joystick button is pressed.
	void joyDown(int button);

	///	Helper method to create a jpeg file.
	void writeJpeg(unsigned char *pixels, const std::string& filename);

	///	Helper method to load drawer's glyphs from Fonts.cpp.
	void loadGlyphs();

	///	The current game state.
	GameState *state;

	///	Our PortAudioDevice.
	PortAudioDevice portAudioDevice;
	///	The background music.
	BackgroundMusic music;

	///	We set this to true when it's time to quit the program.
	bool timeToQuit;
	///	We use this to determine if we need to repaint the screen immediately.
	Uint32 lastRepaint;

	///	The width of the window.
	int width;
	///	The height of the window.
	int height;
	///	True if we're not playing any sound.
	bool noSound;
	///	True if we're not playing the background music.
	bool noMusic;
	///	The path to files we may be rendering offline.
	std::string offlineFilename;
	///	The number of seconds we're going to render offline for.
	unsigned int offlineTime;

	///	For playing with a joystick instead of the keyboard.
	SDL_Joystick *joystick;
	///	Used to avoid 'stickiness' issues.
	bool joyUpIsDown;
	///	Used to avoid 'stickiness' issues.
	bool joyDownIsDown;
	///	Used to avoid 'stickiness' issues.
	bool joyLeftIsDown;
	///	Used to avoid 'stickiness' issues.
	bool joyRightIsDown;

	///	Draws everything on screen.
	Drawer *drawer;
};

#endif
