/*Copyright (C) 2010-2020 Duncan Deveaux

This file is part of Hikou no mizu.

Hikou no mizu 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.

Hikou no mizu 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 Hikou no mizu.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "CharactersMenu.hpp"
#include "Engines/GameEngine.hpp"

CharactersMenu::CharactersMenu(GameEngine *gameEngine) : m_selectionIx(1),
m_gameEngine(gameEngine), m_window(gameEngine->getWindow()),
m_configuration(gameEngine->getConfiguration()), m_playersNo(2)
{
    
}

void CharactersMenu::characterSelected()
{
    if (m_selectionIx <= m_playersNo)
        m_selectionPreview.readyCharacter(m_selectionIx++);
}

void CharactersMenu::characterFocused(int character)
{
    Character newCharacter;
    if (character == CHARACTER_HIKOU)
        newCharacter = Character("Hikou", CHARACTER_TYPE_HUMAN);
    else if (character == CHARACTER_HIKOU_AI)
        newCharacter = Character("Hikou", CHARACTER_TYPE_AI);
    else if (character == CHARACTER_TAKINO)
        newCharacter = Character("Takino", CHARACTER_TYPE_HUMAN);
    else
        newCharacter = Character("Takino", CHARACTER_TYPE_AI);
    
    m_selectionPreview.setCharacter(m_selectionIx, newCharacter, m_textureManager);
}

void CharactersMenu::cleanPreview()
{
    m_selectionIx = 1;
    
    /// Character selection preview
    m_selectionPreview = CharacterSelectionPanel(*m_fontManager.getFont("fonts/default.ttf", 30), m_playersNo); 
    m_selectionPreview.setPosition((m_window->getViewWidth() - m_selectionPreview.getWidth()) / 2, 260);
}


void CharactersMenu::setPlayersNo(int playersNo)
{
    m_playersNo = playersNo;
}

//Screen virtual method
void CharactersMenu::run()
{
    cleanPreview();
    
    //Init variables
        //Get view size
    Vector viewSize = Vector(m_window->getViewWidth(), m_window->getViewHeight());
    
        //Background + Titles
    
    Sprite background( (*m_textureManager.getTexture("gfx/ui/nikko.png")), Box(0, 0, 1920.f / 2048, 1080.f / 2048) );
    background.setScale(viewSize.x / background.getWidth(), viewSize.y / background.getHeight());
    
    Text title("Characters selection", *m_fontManager.getFont("fonts/intuitive.ttf", 74));
    title.setColor(Color(255, 255, 255));
    
    title.setXPosition(10);
    title.setYPosition(10);
    
    Text subtitle("Select the characters that will be fighting", *m_fontManager.getFont("fonts/intuitive.ttf", 30));
    subtitle.setColor(Color(222, 222, 222));
    
    subtitle.setXPosition(viewSize.x - subtitle.getWidth() - 10);
    subtitle.setYPosition(title.getYPosition() + title.getHeight() + 20);
    
    Polygon titleBack = Polygon::rectangle(0, 0, viewSize.x,
                                            subtitle.getYPosition() + subtitle.getHeight() + 10,
                                            Color(66, 112, 174), Color(0, 0, 0));
    titleBack.setBorderSize(0.f);
    
        //Menu
    Sprite menu_default( (*m_textureManager.getTexture("gfx/ui/ui.png")), Box(15.f / 512, 128.f / 512, 1.f / 512, 1.f / 512) );
    Sprite menu_hover( (*m_textureManager.getTexture("gfx/ui/ui.png")), Box(5.f / 512, 128.f / 512, 1.f / 512, 1.f / 512) );
    
    SkinBox skin(225.f, 60.f, menu_default, menu_hover);
    
    CharacterChooser chooser(*m_fontManager.getFont("fonts/default.ttf", 32), skin);
    chooser.setPosition((viewSize.x - chooser.getWidth()) / 2, 130);
    
    chooser.initialize((*this));
    
    
    //Playlist handling
    pthread_mutex_t notifierMutex = PTHREAD_MUTEX_INITIALIZER;
    
    PlaylistNotifier notifier;
    notifier.setNotifyTime(2000.f);
    notifier.setFonts(*m_fontManager.getFont("fonts/default.ttf", 20), *m_fontManager.getFont("fonts/SourceHanSansJP-Normal.otf", 14));
    
    notifier.setPosition( viewSize.x - notifier.getWidth() - 20, viewSize.y - notifier.getHeight() - 20 );
    
    PlaylistPlayer::playlistSetNotifier(PLAYLIST_MENU, &notifier, &notifierMutex);
    
    
    std::vector<std::string> playersList;
    std::vector<int> playersType;
    
    //Start screen loop
    Timer time;
    Vector mouse;
    
    float frameTime = 0.f;
    
    SDL_Event event;
    while (1)
    {
        //Manage time
        frameTime = time.getTime();
        time.reset();
        
        //Manage events
        while (m_window->pollEvent(event))
        {
            switch (event.type)
            {
                case SDL_QUIT: //Application closed
                    m_gameEngine->exit();
                    
                    PlaylistPlayer::playlistSetNotifier(PLAYLIST_MENU, NULL, NULL);
                    pthread_mutex_destroy(&notifierMutex);
                    return;
                break;
                
                case SDL_WINDOWEVENT:
                    if (event.window.event == SDL_WINDOWEVENT_RESIZED) //Window resized
                        m_window->resizeView();
                break;
                
                case SDL_JOYDEVICEADDED:
                    m_gameEngine->getJoystickManager().loadJoystick(event.jdevice.which);
                break;
                
                case SDL_JOYDEVICEREMOVED:
                    m_gameEngine->getJoystickManager().removeJoystick(event.jdevice.which);
                    m_configuration->updatePlayerDevices(event.jdevice.which);
                break;
                
                case SDL_MOUSEBUTTONUP: //Mouse clicked
                    mouse.x = event.button.x;
                    mouse.y = event.button.y;
                    
                    chooser.mouseClick(m_window->viewCoords(mouse));
                    chooser.mouseMove(m_window->viewCoords(mouse)); //Update the panel with the new selection.
                break;
                
                case SDL_MOUSEMOTION: //Mouse moved
                    mouse.x = event.motion.x;
                    mouse.y = event.motion.y;
                    
                    chooser.mouseMove(m_window->viewCoords(mouse));
                break;
                
                case SDL_KEYDOWN:
                    // Escape was pressed, undo last character selection if possible or quit.
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                    {
                        if (m_selectionIx == 1) // Back to main menu.
                        {
                            m_gameEngine->initMainMenu();
                            
                            PlaylistPlayer::playlistSetNotifier(PLAYLIST_MENU, NULL, NULL);
                            pthread_mutex_destroy(&notifierMutex);
                            return;
                            
                        } else if (m_selectionIx > 0 && m_selectionIx < m_playersNo + 1) {
                            
                            m_selectionPreview.resetCharacter(m_selectionIx);
                            m_selectionPreview.unreadyCharacter(--m_selectionIx);
                        }
                    }
                
                break;
            }
        }
        
        m_selectionPreview.update(frameTime);
        
        if (m_selectionIx == m_playersNo + 1) // Selection ended
        {
            std::vector<std::string> playersList;
            std::vector<int> playersType;
            
            for (unsigned int i = 1; i <= m_selectionPreview.getSize(); i++)
            {
                Character selection = m_selectionPreview.getCharacter(i);
                playersList.push_back(selection.name);
                playersType.push_back(selection.type);
            }
            
            m_gameEngine->confFight_players(playersList, playersType);
            m_gameEngine->initArenaMenu();
            
            PlaylistPlayer::playlistSetNotifier(PLAYLIST_MENU, NULL, NULL);
            pthread_mutex_destroy(&notifierMutex);
            return;
        }
        
        //Display
            //Clear
        m_window->clear();
        
            //Draw
        background.draw();
        
        titleBack.draw();
        title.draw();
        subtitle.draw();
        
        m_selectionPreview.draw();
        chooser.draw();
        
            //Playlist notifier
        pthread_mutex_lock(&notifierMutex);
        
        notifier.update();
        notifier.draw();
        
        pthread_mutex_unlock(&notifierMutex);
        
            //Render
        m_window->flush();
    }
}
