/********************************************************************
 *  Nomes: Gabriel Capella                       Números USP: 8962078 
 *         João Herique Luciano                               8535957
 * 
 *  Tarefa:    RedCore - EP2 MAC0463
 *  Arquivo:   GameScene.h
 *  Descrição: Classe do cenário e do mecanismo de jogo
 ********************************************************************/

#ifndef GameScene_h
#define GameScene_h

#include "cocos2d.h"
#include "GameScene/Paddle.h"

class GameScene : public cocos2d::Layer {
    public:
        /**
         * @brief Cria a cena do jogo
         * 
         * @param level - nível atual do jogo
         * @return - Ponteiro para objeto da cena do jogo
         */
        static cocos2d::Scene* createScene(int level);

        /**
         * @brief Inicializa essa classe
         *
         */
        virtual bool init();

        /**
         * @brief Processa o contato entre duas formas no jogo
         * 
         * @param contact objeto representando o contato entre duas formas no cocos2d
         * @return Indicador de que houve colisão
         */
        bool onContactBegin(cocos2d::PhysicsContact& contact);

        /**
         * @brief Macro do cocos2d-x para criar um método create() para certa classe
         * 
         * @param  Nome da classe cujo método create() será criado
         */
        CREATE_FUNC(GameScene);

        /**
         * @brief configura o jogo para um certo nível
         * 
         * @param level nível do jogo
         */
        void setLevel(int level);

        /**
         * @brief Mostra um(a) alerta/mensagem na tela do jogo
         * 
         * @param text string contendo a mensagem a ser mostrada
         */
        void alert(std::string text); // Mostra alerta
    private:

        /**
         * @brief Caso de colisão entre a bola e a parte inferior da tela
         * 
         * @param ball Nó representando a bola que colidiu com a parte inferior da tela
         */
        void caseBallCollision (cocos2d::Node *ball);

        /**
         * @brief Caso de colisão entre a bola e o núcleo
         * 
         * @param core Nó da árvore que representa o núcleo
         * @param ball Nó da árvore que representa a bola
         */
        void caseBallCore (cocos2d::Node *core, cocos2d::Node *ball);

        /**
         * @brief Caso onde o usuário pegou o power-up de salvar o nível
         * 
         * @param powerup_ball Nó que representa o power-up
         */
        void caseSaveLevel(Node *powerup_ball);

        /**
         * @brief Substitui a cena atual pela cena do próximo nível
         * 
         */
        void nextLevel();

        /**
         * @brief Salva o nível atual
         */
        void saveLevel();

        /**
         * @brief Define a probabilidade de aparição e a geração do power
         *        up das bolas triplas
         */
        void tripleBallsAppearance();

        /**
         * @brief Caso onde o usuário pegou o power-up de bolas triplas
         * 
         * @param powerup_ball Nó que representa o power-up
         */
        void caseTripleBalls(Node *powerup_ball);

        /**
         * @brief Define a probabilidade de aparição e a geração
         *        do power up de aumento/diminução da pá
         */
        void paddleBallAppearance();

        /**
         * @brief Caso onde o usuário pegou o power-up de
         *        aumento/diminuição da pá
         * 
         * @param powerup_ball Nó que representa o power-up
         */
        void casePaddleBall(Node *powerup_ball);

        /**
         * @brief Define a probabilidade de aparição e a geração
         *        do power up da super-bola
         */ 
        void superBallAppearance();

        /**
         * @brief Caso onde o usuário pegou o power-up da super-bola
         * 
         * @param powerup_ball Nó que representa o power-up
         */
        void caseSuperBall(Node *powerup_ball);

        /**
         * @brief Adiciona e joga uma nova bola na cena
         */
        void addAndThrowBall();

        /**
         * @brief Remove as bolas e os power-ups que estão na tela
         */
        void removeBallsAndPowersUP();

        /**
         * @brief Cria a bolinha que representa o power-up
         * 
         * @param color Cor da bolinha
         * @param tag identificação da bolinha (usada no tratamento de colisões)
         */
        void createPowerUpBody(cocos2d::Color4B color, int tag);

        /**
         * @brief Cria um delay com callback que será usado na aparição dos
         *        power-ups
         * 
         * @param func função a ser chamada no callback
         */
        void delayCallback(const std::function<void ()> &func);

        /**
         * Nível atual
         */
        int level;

        /**
         * Indica se o jogo já acabou
         */
        bool over;

        /**
         * Ponteiro para a pá do jogo
         */
        Paddle * paddle;

        /**
         * Lista de bolas na cena
         */
        cocos2d::Node* balls;

        /**
         * Lista de power-ups na cena
         */
        cocos2d::Node* power_ups;

        /**
         * Tamanho da tela
         */
        double height, width; // tamanho do quadro

        /**
         * Última vez que a bola colidiu no jogo
         */
        unsigned long int last_touch;
};

#endif /* GameScene_h */
