//--------------------------------------------------------------------------------------
// 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 <string>

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

//--------------------------------------------------------------------------------------
// Constantes
//--------------------------------------------------------------------------------------
// Tipos de juegos
#define     GAME_1PLAYER          1     ///< Juego un jugador
#define     GAME_2PLAYER_FIGHT    2     ///< Juego dos jugadores a lucha
#define     GAME_2PLAYER_OBJS     3     ///< Juego dos jugadores a objetivos

// Otras constantes
#define     GAME_TIME_INI_GAME    -1.0f	///< Tiempo de inicio del juego
#define     GAME_TIME_OBJ		  1     ///< Segundos para aparición del objetivo
#define     GAME_TIME_ELE		  2     ///< Segundos para aparición de los elementos
#define     GAME_LOW_TIME		  11.0f ///< Tiempo bajo dónde se emite el sonido de aviso

//--------------------------------------------------------------------------------------
/// 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 1
    std::basic_string<wchar_t> m_awLVehicle1;
    /// Path del vehículo del jugador 2
    std::basic_string<wchar_t> m_awLVehicle2;
    /// Nombre del jugador local
    std::basic_string<wchar_t> m_awLName;
} 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_pLPlayer1;         ///< Puntero al jugador 1
    CPlayerLocal                    *m_pLPlayer2;         ///< Puntero al jugador 2

	float							m_pTime;			  ///< Tiempo disponible en el momento actual
	float							m_pLastTime;		  ///< Tiempo disponible en el momento anterior
    bool                            m_bChangeTime;        ///< Flag que indica si se cambió el marcador de tiempo

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

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

	/// Para actualizar el tiempo durante el juego
	bool updateTime(void);

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 1
    CPlayerLocal *getLocalPlayer1(void)		{return m_pLPlayer1;}
    /// Función observadora del jugador 2
    CPlayerLocal *getLocalPlayer2(void)		{return m_pLPlayer2;}
    /// Función observadora de la arena del juego
    C3DObjArena *getArena(void)				{return m_pArena;}
    /// Función observadora del tipo de juego
    int getType(void)						{return m_iType;}

    /// 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
