//--------------------------------------------------------------------------------------
// Copyright (C) 2008 http://shift.delblanco.es
//--------------------------------------------------------------------------------------
// SHIFT Videogame 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 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.
//--------------------------------------------------------------------------------------
/// \file Game.h
/// Para gestionar un juego completo
/// Cada juego tiene asociado una arena y una lista de jugadores
/// Este módulo implementa todas las operaciones para gestionar el juego
//--------------------------------------------------------------------------------------
#pragma once
#ifndef __CGAME_H__
#define __CGAME_H__

//--------------------------------------------------------------------------------------
// Ficheros de cabecera
//--------------------------------------------------------------------------------------
#include <vector>
#include <string>

#include "PlayerLocal.h"
#include "PlayerRemote.h"
#include "3DObjArena.h"

//--------------------------------------------------------------------------------------
// Constantes
//--------------------------------------------------------------------------------------
// Tipos de juegos
#define     GAME_MONO_1           1     ///< Juego monojugador
#define     GAME_MULTI_1          2     ///< Juego multijugador por contador de objetivos
#define     GAME_MULTI_2          3     ///< Juego multijugador por contador de muertes
#define     GAME_MULTI_3          4     ///< Juego multijugador partida a muerte

#define     GAME_MAX_SEC_HEALTH   2.0f  ///< Máxima pérdida de vida por segundo permitida


//--------------------------------------------------------------------------------------
/// Tipo de dato con los datos de un juego, necesarios para la inicialización
//--------------------------------------------------------------------------------------
typedef struct
{
    /// Tipo de juego
    int m_iType;
    /// Path de la arena
    std::basic_string<wchar_t> m_awArena;
    /// Path del vehículo del jugador local
    std::basic_string<wchar_t> m_awLVehicle;
    /// Nombre del jugador local
    std::basic_string<wchar_t> m_awLName;

    /// Vector con los nombres de los jugadores remotos
    std::vector<std::basic_string<wchar_t> > m_aRIPs;
    /// Vector con los path de los vehículos de los jugadores remotos
    std::vector<std::basic_string<wchar_t> > m_aRVehicles;
    /// Vector con los nombres de los jugadores remotos
    std::vector<std::basic_string<wchar_t> > m_aRNames;

} SDataGame;

//--------------------------------------------------------------------------------------
/// Clase base para manejar los jugadores de la escena
//--------------------------------------------------------------------------------------
class CGame
{

private:  // Campos miembro

    bool                            m_bInit;              ///< Flag que indica si el objeto está inicializado
    int                             m_iType;              ///< Tipo de juego
    C3DObjArena                     *m_pArena;            ///< Puntero a la arena del juego
    CPlayerLocal                    *m_pLPlayer;          ///< Puntero al jugador local

	float							m_pObjetives;		  ///< Número de objetos capturados en cada momento
	float							m_pTime;			  ///< Tiempo disponible en el momento actual
	float							m_pLastTime;		  ///< Tiempo disponible en el momento anterior

	float							m_pLastHealth;		  ///< Última vida del vehículo
	float							m_pHealthSecond;      ///< Vida perdida durante el último segundo

	float							m_pLastRockets;		  ///< Último número de cohetes del vehículo
	float							m_pLastObjetives;	  ///< Último número de objetivos capturados

    C3DSound                        *m_pSndWin;           ///< Sonido de victoria
    C3DSound                        *m_pSndLose;          ///< Sonido de derrota
    C3DSound                        *m_pSndTime;          ///< Sonido de tiempo

    /// Vector con los jugadores remotos del juego, indexado por la IP de cada uno
    std::vector<CPlayerRemote*> m_aRPlayers;

	/// Para actualizar varios marcadores del GUI durante el juego
	void updateInfo();

public: // Métodos públicos

    /// Constructor
    CGame();
    /// Destructor
    ~CGame();

    /// Inicializa el juego
    bool initialize(SDataGame *dData);
    /// Renderiza los objetos del juego
    void render();
    /// Actualiza el juego
    void update();
    /// Libera los datos del juego
    void Release();

    /// Función observadora del jugador local
    CPlayerLocal *getLocalPlayer(void)		{return m_pLPlayer;}
    /// Función observadora de la arena del juego
    C3DObjArena *getArena(void)				{return m_pArena;}

	/// Función observadora del número de objetivos
	float getObjectives(void)				{return m_pObjetives;}

    /// Para activar el sonido de victoria
    void playWin(bool loop, long volume = 0, long frecuency = 0);
    /// Para saber si está activo el sonido de victoria
	bool isPlayWin(bool)					{return (m_pSndWin && m_pSndWin->isPlaying());}
    /// Para desactivar el sonido de victoria
	void stopWin(void)						{if(m_pSndWin) m_pSndWin->Stop();}

    /// Para activar el sonido de derrota
    void playLose(bool loop, long volume = 0, long frecuency = 0);
    /// Para saber si está activo el sonido de derrota
	bool isPlayLose(bool)					{return (m_pSndLose && m_pSndLose->isPlaying());}
    /// Para desactivar el sonido de derrota
	void stopLose(void)						{if(m_pSndLose) m_pSndLose->Stop();}

    /// Para activar el sonido de tiempo
    void playTime(bool loop, long volume = 0, long frecuency = 0);
    /// Para saber si está activo el sonido de tiempo
	bool isPlayTime(bool)					{return (m_pSndTime && m_pSndTime->isPlaying());}
    /// Para desactivar el sonido de tiempo
	void stopTime(void)						{if(m_pSndTime) m_pSndTime->Stop();}

};

#endif
