/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtCore module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
**   * Redistributions of source code must retain the above copyright
**     notice, this list of conditions and the following disclaimer.
**   * Redistributions in binary form must reproduce the above copyright
**     notice, this list of conditions and the following disclaimer in
**     the documentation and/or other materials provided with the
**     distribution.
**   * Neither the name of The Qt Company Ltd nor the names of its
**     contributors may be used to endorse or promote products derived
**     from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/

//Own
#include "states.h"
#include "graphicsscene.h"
#include "boat.h"
#include "submarine.h"
#include "torpedo.h"
#include "animationmanager.h"
#include "progressitem.h"
#include "textinformationitem.h"

//Qt
#include <QFinalState>
#include <QGraphicsView>
#include <QKeyEventTransition>
#include <QMessageBox>
#include <QRandomGenerator>
#include <QStateMachine>

PlayState::PlayState(GraphicsScene *scene, QState *parent)
    : QState(parent), scene(scene), machine(nullptr),
      currentLevel(0), score(0)
{
}

PlayState::~PlayState()
{
    delete machine;
}

void PlayState::onEntry(QEvent *)
{
    //We are now playing?
    if (machine) {
        machine->stop();
        //we hide the information
        scene->textInformationItem->hide();
        scene->clearScene();
        currentLevel = 0;
        score = 0;
        delete machine;
    }

    machine = new QStateMachine;

    //This state is when player is playing
    LevelState *levelState = new LevelState(scene, this, machine);

    //This state is when the player is actually playing but the game is not paused
    QState *playingState = new QState(levelState);
    levelState->setInitialState(playingState);

    //This state is when the game is paused
    PauseState *pauseState = new PauseState(scene, levelState);

    //We have one view, it receive the key press event
    QKeyEventTransition *pressPplay = new QKeyEventTransition(scene->views().at(0), QEvent::KeyPress, Qt::Key_P);
    pressPplay->setTargetState(pauseState);
    QKeyEventTransition *pressPpause = new QKeyEventTransition(scene->views().at(0), QEvent::KeyPress, Qt::Key_P);
    pressPpause->setTargetState(playingState);

    //Pause "P" is triggered, the player pause the game
    playingState->addTransition(pressPplay);

    //To get back playing when the game has been paused
    pauseState->addTransition(pressPpause);

    //This state is when player have lost
    LostState *lostState = new LostState(scene, this, machine);

    //This state is when player have won
    WinState *winState = new WinState(scene, this, machine);

    //The boat has been destroyed then the game is finished
    levelState->addTransition(scene->boat, &Boat::boatExecutionFinished,lostState);

    //This transition check if we won or not
    WinTransition *winTransition = new WinTransition(scene, this, winState);

    //The boat has been destroyed then the game is finished
    levelState->addTransition(winTransition);

    //This state is an animation when the score changed
    UpdateScoreState *scoreState = new UpdateScoreState(levelState);

    //This transition update the score when a submarine die
    UpdateScoreTransition *scoreTransition = new UpdateScoreTransition(scene, this, levelState);
    scoreTransition->setTargetState(scoreState);

    //The boat has been destroyed then the game is finished
    playingState->addTransition(scoreTransition);

    //We go back to play state
    scoreState->addTransition(playingState);

    //We start playing!!!
    machine->setInitialState(levelState);

    //Final state
    QFinalState *finalState = new QFinalState(machine);

    //This transition is triggered when the player press space after completing a level
    CustomSpaceTransition *spaceTransition = new CustomSpaceTransition(scene->views().at(0), this, QEvent::KeyPress, Qt::Key_Space);
    spaceTransition->setTargetState(levelState);
    winState->addTransition(spaceTransition);

    //We lost we should reach the final state
    lostState->addTransition(lostState, &QState::finished, finalState);

    machine->start();
}

LevelState::LevelState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game)
{
}
void LevelState::onEntry(QEvent *)
{
    initializeLevel();
}

void LevelState::initializeLevel()
{
    //we re-init the boat
    scene->boat->setPos(scene->width()/2, scene->sealLevel() - scene->boat->size().height());
    scene->boat->setCurrentSpeed(0);
    scene->boat->setCurrentDirection(Boat::None);
    scene->boat->setBombsLaunched(0);
    scene->boat->show();
    scene->setFocusItem(scene->boat, Qt::OtherFocusReason);
    scene->boat->run();

    scene->progressItem->setScore(game->score);
    scene->progressItem->setLevel(game->currentLevel + 1);

    const GraphicsScene::LevelDescription currentLevelDescription = scene->levelsData.value(game->currentLevel);
    for (const QPair<int,int> &subContent : currentLevelDescription.submarines) {

        GraphicsScene::SubmarineDescription submarineDesc = scene->submarinesData.at(subContent.first);

        for (int j = 0; j < subContent.second; ++j ) {
            SubMarine *sub = new SubMarine(submarineDesc.type, submarineDesc.name, submarineDesc.points);
            scene->addItem(sub);
            int random = QRandomGenerator::global()->bounded(15) + 1;
            qreal x = random == 13 || random == 5 ? 0 : scene->width() - sub->size().width();
            qreal y = scene->height() -(QRandomGenerator::global()->bounded(150) + 1) - sub->size().height();
            sub->setPos(x,y);
            sub->setCurrentDirection(x == 0 ? SubMarine::Right : SubMarine::Left);
            sub->setCurrentSpeed(QRandomGenerator::global()->bounded(3) + 1);
        }
    }
}

/** Pause State */
PauseState::PauseState(GraphicsScene *scene, QState *parent) : QState(parent), scene(scene)
{
}

void PauseState::onEntry(QEvent *)
{
    AnimationManager::self()->pauseAll();
    scene->boat->setEnabled(false);
}
void PauseState::onExit(QEvent *)
{
    AnimationManager::self()->resumeAll();
    scene->boat->setEnabled(true);
    scene->boat->setFocus();
}

/** Lost State */
LostState::LostState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game)
{
}

void LostState::onEntry(QEvent *)
{
    //The message to display
    QString message = QString("You lose on level %1. Your score is %2.").arg(game->currentLevel+1).arg(game->score);

    //We set the level back to 0
    game->currentLevel = 0;

    //We set the score back to 0
    game->score = 0;

    //We clear the scene
    scene->clearScene();

    //We inform the player
    scene->textInformationItem->setMessage(message);
    scene->textInformationItem->show();
}

void LostState::onExit(QEvent *)
{
    //we hide the information
    scene->textInformationItem->hide();
}

/** Win State */
WinState::WinState(GraphicsScene *scene, PlayState *game, QState *parent) : QState(parent), scene(scene), game(game)
{
}

void WinState::onEntry(QEvent *)
{
    //We clear the scene
    scene->clearScene();

    QString message;
    if (scene->levelsData.size() - 1 != game->currentLevel) {
        message = QString("You win the level %1. Your score is %2.\nPress Space to continue.").arg(game->currentLevel+1).arg(game->score);
        //We increment the level number
        game->currentLevel++;
    } else {
        message = QString("You finish the game on level %1. Your score is %2.").arg(game->currentLevel+1).arg(game->score);
        //We set the level back to 0
        game->currentLevel = 0;
        //We set the score back to 0
        game->score = 0;
    }

    //We inform the player
    scene->textInformationItem->setMessage(message);
    scene->textInformationItem->show();
}

void WinState::onExit(QEvent *)
{
    //we hide the information
    scene->textInformationItem->hide();
}

/** UpdateScore State */
UpdateScoreState::UpdateScoreState(QState *parent) : QState(parent)
{
}

/** Win transition */
UpdateScoreTransition::UpdateScoreTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target)
    : QSignalTransition(scene, &GraphicsScene::subMarineDestroyed),
      game(game), scene(scene)
{
    setTargetState(target);
}

bool UpdateScoreTransition::eventTest(QEvent *event)
{
    if (!QSignalTransition::eventTest(event))
        return false;
    QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(event);
    game->score += se->arguments().at(0).toInt();
    scene->progressItem->setScore(game->score);
    return true;
}

/** Win transition */
WinTransition::WinTransition(GraphicsScene *scene, PlayState *game, QAbstractState *target)
    : QSignalTransition(scene, &GraphicsScene::allSubMarineDestroyed),
      game(game), scene(scene)
{
    setTargetState(target);
}

bool WinTransition::eventTest(QEvent *event)
{
    if (!QSignalTransition::eventTest(event))
        return false;
    QStateMachine::SignalEvent *se = static_cast<QStateMachine::SignalEvent*>(event);
    game->score += se->arguments().at(0).toInt();
    scene->progressItem->setScore(game->score);
    return true;
}

/** Space transition */
CustomSpaceTransition::CustomSpaceTransition(QWidget *widget, PlayState *game, QEvent::Type type, int key)
    : QKeyEventTransition(widget, type, key), game(game)
{
}

bool CustomSpaceTransition::eventTest(QEvent *event)
{
    if (!QKeyEventTransition::eventTest(event))
        return false;
    return (game->currentLevel != 0);
}
