/*
	Wheels Of Steel
	Copyright (c) 2006, Darragh Coy.
	All rights reserved.
	Original work(s), source code & author(s) details available at: http://www.darraghcoy.com

	Redistribution and use in source and binary forms, with or without modification, are permitted 
	provided that the following conditions are met:

		* 	Redistributions of source code must retain the above copyright notice, this list of 
			conditions and the following disclaimer.
		* 	Redistributions in binary form must reproduce the above copyright notice, this list of 
			conditions and the following disclaimer in the documentation.
		* 	Neither the name of the author nor the names of contributors may be used to endorse or 
			promote products derived from this software without specific prior written permission.
		* 	The use of any third party libraries, modules or data files provided with the source 
			form of the program must follow and respect the individual licensing terms of these 
			components. You do not have permission to modify or circumvent the licensing terms for 
			provided third party components unless the third party licenses specifically allow this. 
			If you do not agree to the terms of provided third party components then you do not have 
			permission to use them in your derived work(s).
		* 	The terms of this license do not apply to separate (but related) distributions if supplied 
			by the author(s), only to the contents of this source distribution, derived works, and the 
			binaries produced by either modified or unmodified versions of the source code. The terms 
			of this license do not also apply to any third party libraries or components provided with 
			the source distribution. Such third party elements are licensed under their own separate 
			agreements.

	THIS SOFTWARE IS PROVIDED BY DARRAGH COY ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, 
	BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
	ARE DISCLAIMED. IN NO EVENT SHALL DARRAGH COY BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
	OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 
	OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
	IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef GAME_H
#define GAME_H

//##############################################################################
// C Includes
//##############################################################################

#include "ProgramError.h"
#include <stdlib.h>
#include <math.h>

//##############################################################################
// Defines
//##############################################################################

#define GAME_VERSION "1.02"

//##############################################################################
// Forward declarations
//##############################################################################

class Window;
class Timer;
class Camera;
class Track;
class TrackSection;
class TrackPopulator;
class Background;
class GameObjectManager;
class AIPlayer;
class Obj_Car;
class Bitmap;
class BitmapFont;
class Menu_BeginRace;
class Menu_EndRace;

//##############################################################################
//##############################################################################
//##############################################################################
//##############################################################################
//
//
// Class Name:   Game
// Purpose:      Main game logic and initialisation
//
//
//##############################################################################
//##############################################################################
//##############################################################################
//##############################################################################

class Game
{
 /*-----------------------------------------------------------------------------
 Public functions and data
 -----------------------------------------------------------------------------*/

 public:

        //----------------------------------------------------------------------
        // Constants
        //----------------------------------------------------------------------

        // Number of frames over which the current frame rate is determined

        static const unsigned FRAME_TIME_UPDATE_FRAMES;

        // Game resolution

        static const unsigned short RESOLUTION_X;			// game resoultion: x
        static const unsigned short RESOLUTION_Y;			// game resoultion: y

        // Starting position for the grid of cars

        static const float CAR_STARTING_Z;

        // How many sections from the end the race finishes at

        static const int RACE_FINISH_SECTION_FROM_END;

        // Hills and turns settings

        static const int HILLS_TURNS_START_FROM_START;		// how many sections from the start the hills and turns begin at
        static const int HILLS_TURNS_END_FROM_END;			// how many sections from the end   the hills and turns end at

        // Camera settings

        static const float CAMERA_CORNER_LEAN;				// amount the camera leans into turn when turning
        static const float CAMERA_OFFSET_Y;					// distance from target: y
        static const float CAMERA_OFFSET_Z;					// distance from target: z

        // General physics-y settings

        static const float GRAVITY;							// gravity amount
        static const float FRICTION_AIR;					// multiplier that controls how much contact with the air slows down an object
        static const float FRICTION_TRACK;					// multiplier that controls how much contact with the track slows down an object
        static const float FRICTION_GROUND;					// multiplier that controls how much contact with the rough ground slows down an object

        //----------------------------------------------------------------------
        // Functions
        //----------------------------------------------------------------------

        static void initGame
        (
            Window * window,                    // The game window

            unsigned trackLenght,               // Game setting: track lenght, in sections
            unsigned numCompetitors,            // Game setting: number of competitors
            float    minHillHeight,             // Game setting: minimum hill height
            float    maxHillHeight,             // Game setting: maximum hill height
            float    minTurnAmount,             // Game setting: minimum turn amount
            float    maxTurnAmount,             // Game setting: maximum turn amount
            float    playerSpeedHandicap,       // Game setting: amount of acceleration to subtract from acceleration of all AI cars
            float    aiCarGridSpeedDifference,  // Game setting: amount of difference in acceleration between AI cars on the grid. furhter back in the grid cars are slower.
            float    gridSpacing                // Game setting: spacing between cars on the starting grid
        );

        static void endGame();                  // finishes up the game

//##############################################################################
//##############################################################################
//##############################################################################
//##############################################################################

 /*-----------------------------------------------------------------------------
 Private functions and data
 -----------------------------------------------------------------------------*/

 private:

        //----------------------------------------------------------------------
        // Variables
        //----------------------------------------------------------------------

        static Window *         window;                     // Window that the game is being displayed in
        static bool             run;                        // Continue running the game?

        static float            timeToRaceStart;            // Time left in seconds till the race begins
        static float            timeToGoPromptEnd;          // Time left in seconds till the 'go!' prompt dissapeers
        static int              playerFinishPosition;       // Finishing position of the player. '-1' means player didn't finish race.

        static Timer  *         frameTimer;                 // Timing: times frame rate
        static float            frameTime;                  // Current game frame time in seconds: updated every so often
        static float            frameTimesAccum;            // Accumalted frame times for a number of frames
        static unsigned         frameTimesCounted;          // Number of frame times added to the accumalted frame times
        static Camera *         camera;                     // The game's camera
        static Background *     background;                 // The game's background
        static BitmapFont *     bitFont;                    // The game's bitmap font
        static Track *          track;                      // The game's track

        static Obj_Car  **      carArray;                   // The array of cars: first car is the players.
        static unsigned         carCount;                   // The number of cars in the game
        static AIPlayer **      aiArray;                    // CPU controlled players that move the other cars. Always 'num cars' - 1 ai players.

        static Bitmap * bmpHudGuageFL;      // hud speed guage: left and full
        static Bitmap * bmpHudGuageFR;      // hud speed guage: right and full
        static Bitmap * bmpHudGuageEL;      // hud speed guage: left and empty
        static Bitmap * bmpHudGuageER;      // hud speed guage: right and empty

        //----------------------------------------------------------------------
        // Functions
        //----------------------------------------------------------------------

        static void doInput                 (Window & window);      // Do the input
        static void gameLoop                (Window & window);      // Do the game loop
        static void drawScene               (Window & window);      // redraw the entire scene
        static void windowClosed            (Window & window);      // window closed event handler
        static void createCars();                                   // Create the cars that populate the track

}; // end of: class Game{}

//##############################################################################
// C++ Includes
//##############################################################################

#include "Window.h"
#include "Camera.h"
#include "Timer.h"
#include "Track.h"
#include "TrackSection.h"
#include "TrackPopulator.h"
#include "Background.h"
#include "GameObjectManager.h"
#include "AIPlayer.h"
#include "Obj_Car.h"
#include "Bitmap.h"
#include "BitmapFont.h"
#include "Menu_BeginRace.h"
#include "Menu_EndRace.h"

#endif // end of: ifndef GAME_H
