/*
  File name: CCytadelaGame.h
  Copyright: (C) 2005 - 2008 Tomasz Kazmierczak

  Creation date: 18.07.2005 15:37
  Last modification date: 15.12.2008

  This file is part of Cytadela

 *   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 _CCYTADELAGAME_H_
#define _CCYTADELAGAME_H_

#include <stdint.h>
#include <map>
#include "GameControl.h"
#include "CInfoText.h"
#include "Localization.h"
#include "CCytadelaConfig.h"
#include "CytadelaDefinitions.h"

#define USERTEXT_LEN         8
#define USERTEXT_LENMINUS1   7

typedef enum {
	ACT_FIRE = 0,
	ACT_FORWARD,
	ACT_BACKWARD,
	ACT_TURN_LEFT,
	ACT_TURN_RIGHT,
	ACT_STRAFE_LEFT,
	ACT_STRAFE_RIGHT,
	ACT_NUM_ACTIONS
} Actions;

enum GameStateWeaponsNums {
	GSWPN_HANDGUN =        0x0001,
	GSWPN_SHOTGUN =        0x0002,
	GSWPN_MASHINEGUN =     0x0004,
	GSWPN_FLAMER =         0x0008,
	GSWPN_BLASTER =        0x0010,
	GSWPN_ROCKETLAUNCHER = 0x0020,
};

typedef enum {
	SIT_MEDIPACK = 0,
	SIT_POTION,
	SIT_BEER,
	SIT_BOMB,
} SimpleItemType;

typedef std::map<UsableItemType, UsableItem *> UsableItemsMap;
typedef std::map<SimpleItemType, Item *> SimpleItemsMap;

struct GameState {
	uint32_t totalTime;
	uint16_t energy;
	uint16_t ammo[NumberOfWeaponTypes];
	uint16_t weapons;
	uint16_t killed;
	uint8_t  bomb;
	bool   difficult;
	bool   exitGame;
	bool   visionNoise;
};

class CCytadelaGame {
private:
	//objects
	CSDLClass *mSDL;
	COGLClass *mOGL;
	GameControl *mGameCtrl;
	Localization *mLocInterface;
	CCytadelaConfig *mConfig;

	//coords
	float mRotY;
	float mSin;
	float mCos;
	float mX;
	float mZ;
	uint8_t mPosition[2];

	//times
	uint32_t mDiff;
	uint32_t mLastTime;
	uint32_t mTotalTime;
	uint32_t mPauseStartTime;

	//booleans
	bool   mPause;
	bool   mMap;
	bool   mFireOnce;
	bool   mDifficult;

	//text related
	CInfoText *mTexts;
	char  mPlayerText[USERTEXT_LEN];
	const char *mLastErrorDesc;

	//counters
	uint16_t mEnergy;
	uint8_t  mBomb;

	//walk related
	float mWalkSpeed;
	float mStandardWalkSpeed;
	uint32_t mPotion;

	bool mFinishedLevel;

	int32_t mBeer;

	int32_t mLowEnergySoundNumber;

	UsableItemsMap  mUsableItems;
	SimpleItemsMap  mSimpleItems;
	UsableItem     *mSelectedItem;

	bool mActionMap[ACT_NUM_ACTIONS];

	bool processInput();
	void processRotationAngle();
	bool isCode(const char *code);
	void doActions(Actions action);
	void handleInput(SDLKey key);
	void takeWeapon(Weapon *weapon);
	void takeCard(Card *card);
	void takeAmmo(Ammo *ammo);
	void takeItem(int32_t mtlNum);
	void fire();

	bool decEnergy(uint16_t energy);
	void drawBloodOnScreen();

	void initUserInterface();
	void drawAmmoCounter();
	void drawEnergyCounter();
	void drawCardsCounters();

	void fadeIn();
	void fadeOut();

	bool loadImages();
	bool loadItemSounds();
	bool loadGameCtrlSounds();
public:
	bool initGame(COGLClass *ogl, GameState *state, CInfoText *texts);
	void freeGame();
	const char *getLastErrorDesc();
	bool runGame(const char *level, GameState *state);
};

#endif
