//	Application.h - Base class for all NiallsAVLib backends.
//  ----------------------------------------------------------------------------
//	This file is part of 'NiallsAVLib', base code for any kind of audiovisual
//	apps.
//	Copyright (C) 2012  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 "ResourceManager.h"
#include "CmdLineParams.h"
#include "AppSettings.h"
#include "GameState.h"
#include "TwoFloats.h"

#include <stdint.h>

class AudioDevice;
typedef shared_ptr<AudioDevice> AudioDevicePtr;

//------------------------------------------------------------------------------
///	Base class for all NiallsAVLib backends.
class Application
{
  public:
	///	Constructor.
	Application() {};
	///	Destructor.
	virtual ~Application() {};

	///	Initialises the application.
	virtual void initialise(CmdLineParams& cmdLine) = 0;

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

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

	///	Quits the game.
	virtual void quit() = 0;

	///	Sets the mouse position.
	virtual void setMousePos(const TwoFloats& pos) = 0;
	///	Grabs mouse focus (useful for playing in a window).
	virtual void grabMouse(bool val) = 0;

	///	Moves to the next game state.
	virtual void nextState(const std::wstring newState, const std::wstring extra) = 0;
	///	Registers a game state with the application.
	/*!
		\param stateName The name by which the state can be referred to (i.e.
		to switch to this state you will just call nextState(<stateName>) from
		another GameState). The stateName can be anything *EXCEPT*
		"-start state-", which is an internal name used by LoadingScreen.
		\param stateCreator The creator object used to construct the state.
		\param isStartState If this is true, this state will be loaded on
		startup as soon as LoadingScreen has finished loading its resources.
	 */
	virtual void registerGameState(const std::wstring& stateName,
								   const GameStateCreatorBase *stateCreator,
								   bool isStartState = false) = 0;

	///	Returns the number of milliseconds since the app was started.
	virtual uint32_t getTimeSinceStart() const = 0;

	///	Returns this application's AppSettings instance.
	virtual const AppSettings& getAppSettings() const = 0;
	///	Returns this application's ResourceManager instance.
	virtual const ResourceManager& getResourceManager() const = 0;
	///	Returns this application's GlobalData instance.
	virtual GlobalDataPtr& getGlobalData() = 0;
	///	Returns this application's drawing area size.
	virtual const TwoFloats& getDrawingAreaSize() const = 0;
	///	Returns this application's audio device.
	virtual AudioDevicePtr& getAudioDevice() = 0;

	///	Sets the audio device to use.
	/*!
		\param newDevice This device will be deleted by the Application. Do
		not delete it yourself.

		This will stop audio processing from the current AudioDevice, and
		restart it once the new device has been set up.
	 */
	virtual void setAudioDevice(AudioDevice *newDevice) = 0;
};

#endif
