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

  Creation date: 18.07.2005 15:48
  Last modification date: 21.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 _COGLClass_H_
#define _COGLClass_H_

#include <SDL/SDL_opengl.h>
#include <list>
#include <vector>
#include "cmf/GameObjectsManager.h"

typedef enum {
	DT_DISSOLVE,
	DT_FADEIN,
	DT_FADEOUT
} DissolveType;

typedef enum {
	OSD_PANEL = 0,
	OSD_NRG_H,
	OSD_NRG_T,
	OSD_NRG_O,
	OSD_WEAPON,
	OSD_AMMO_H,
	OSD_AMMO_T,
	OSD_AMMO_O,
	OSD_BLUE_CARD,
	OSD_GREEN_CARD,
	OSD_RED_CARD,
	OSD_BOMB,
	OSD_PLOTTER,
	OSD_TEXT,
	OSD_ELEMENTS_COUNT
} OSDElement;

//define a mesh list - it will be used for sorting and rendering transparent meshes;
//we don't need a random access (which is slow in case of std::list) as we will access
//all the items sequentially (we will access them only while rendering); besides std::list
//has a constant insertion and deletion time, which is ideal for us
typedef std::list<Mesh3Dg *> Mesh3DgList;

typedef std::vector<GLuint> GLTextureIDVector;

class COSDClass {
friend class COGLClass;
private:
	GLuint   *mImages;
	uint32_t  mImgsCount;
	int32_t   mElementTex[OSD_ELEMENTS_COUNT];
	uint32_t  mDiff;
	float    *mVerts;
	float    *mTexCoords;

	char      mOSDText[128];
	float     mTextScrollSpeed;
	float     mTextPosOffset;
	uint32_t  mIncomingChars;
	float     mPlotterPosOffset;
	float     mPlotterWScale;
	float     mPlotterVerts[32];
	float     mPlotterTexCoords[32];
	int32_t   mPlotterElements;
	uint32_t  mNoiseTime;
	bool      mVisionNoise;
	GLuint    mNoiseTexNum[2];
	GLuint    mBloodTexNum;
	//for texture 512x256x32 (512kB)
	uint32_t  mBloodPixels[131072];

	//64x64 fields; one field is 8x8 pixels; 24 bits of color depth (3 bytes)
	//64*8 x 64*8 x 3
	uint8_t   mMapImage[786432];
	GLuint    mMapTextureNum;
	GLuint    mPosCursorTexNum;
	bool      mMap;

	GLsizei mScreenW;
	GLsizei mScreenH;
	void enable2D();
	void disable2D();
	void drawText();
	void drawHeartPlotter();
	void drawNoise();
	void deleteFXTextures();
	bool mPause;

public:

	COSDClass();
	void init(GLsizei width, GLsizei height);
	void clear();
	bool createImagesArray(uint32_t imagesCount);
	bool loadImg(uint32_t num, const char* mfaFilePath, const char* imgFileName);
	void setImage(uint32_t imgNum, OSDElement element);
	void deleteImages();
	void draw(float sin, float cos, uint32_t diff);
	void addText(const char *text);
	void setHeartSpeed(float heartBeat);
	void drawMap(uint8_t playerPosX, uint8_t playerPosY);
	void drawMapPos(MapDataType *mapPos, uint8_t posX, uint8_t posY, GameObjectsManager *objects);
	void mapOn();
	void mapOff();
	void addNoise(uint32_t *noiseLines);
	void freeNoise();
	void addBlood(uint8_t *bloodLines, int32_t elements);
	void drawBlood();
	void freeBlood();
	void setPause(bool pause) { mPause = pause; }
};

class COGLClass {
private:
	GameObjectsManager      *mObjects;
	Mesh3DgList       mTransparentMeshes;
	Mesh3DgList       mOpaqueMeshes;
	GLTextureIDVector mTextureIDs;

	float mSin;
	float mCos;
	float mCosHVA;
	float mX;
	float mZ;

	bool checkOGL();

	void createMeshLists();
	void setTextures(Mesh3Dg *mesh);

	void drawMeshes();
	void drawStencilMask(Mesh3Dg *mesh);
	bool loadTexture(uint32_t texNum);

public:
	COSDClass osd;

	bool initOGL(GLsizei width, GLsizei height);
	void freeOGL();

	bool setGOManager(GameObjectsManager *objects);

	void addMeshToRenderList(Mesh3Dg *mesh);
	void remMeshFromRenderList(Mesh3DgUID uid);

	void preDissolve(float r, float g, float b, DissolveType disType);
	void dissolveFrame(DissolveType disType, float fadeValue);

	void projectionMatrix(GLsizei width, GLsizei height);
	void setCamMatrix(float x, float z, float sin, float cos);
	void renderFrame();
};

bool checkGLExtension(const char *extname, const GLubyte *extlist);

#endif
