#include "gamemenu.h"
#include "gamescene.h"
#include "gameprofile.h"
#include "gamesound.h"
#include "gamewidget.h"

void MenuWidget::keyPressEvent(QKeyEvent *keyEvent)
{
    if (isActive()) {
        switch (keyEvent->key()) {
          case Qt::Key_Escape: {
            switch (currentIndex()) {
              case MENU_MAIN:
                  on_bExit_clicked();
                  break;
              case MENU_OPTIONS:
                  on_bOptBack_clicked();
                  break;
              case MENU_PAUSE:
                  on_bPauseBack_clicked();
                  break;
              case MENU_GRAPHICS:
                  on_bGraphicsBack_clicked();
                  break;
              case MENU_AUDIO:
                  on_bAudioBack_clicked();
                  break;
              case MENU_PROFILE: {
                  if (m_newplayer || m_renameplayer)
                      on_bProfileCancel_clicked();
                  else
                      on_bProfileBack_clicked();
                  break;
              }
//              case MENU_HALL:
//                  on_bHallBack_clicked();
//                  break;
              case MENU_HELP:
                  on_bHelpBack_clicked();
                  break;
              case MENU_CREDITS:
                  on_bCreditsBack_clicked();
                  break;
              case MENU_LEVELS:
                  on_bLevelsBack_clicked();
                  break;
            }
          }
          break;

          case Qt::Key_Return:
          case Qt::Key_Enter: {
              if (currentIndex() == MENU_PROFILE && (m_newplayer || m_renameplayer))
                  on_bProfileOk_clicked();
          }
          break;
       }
       keyEvent->accept();
    }
}

////////////////////////////////////////////////////////////////////////////////
void MenuWidget::on_bNew_clicked()
{
    if (gameProfile->currentPlayer()->name.isEmpty()) {
       // show profile select menu
       startAfterSelect = true;
       on_bOptProfile_clicked();
    }
    else {
       // start new game
       emit menuNew();
    }
}

void MenuWidget::on_bContinue_clicked()
{
    emit menuContinue();
}

void MenuWidget::on_bOptions_clicked()
{
    setCurrentIndex(MENU_OPTIONS);
}

/*
void MenuWidget::on_bHall_clicked()
{
    updateHallOfFame();
    setCurrentIndex(MENU_HALL);
}
*/

void MenuWidget::on_bHelp_clicked()
{
    setCurrentIndex(MENU_HELP);
}

void MenuWidget::on_bCredits_clicked()
{
    setCurrentIndex(MENU_CREDITS);
}

void MenuWidget::on_bExit_clicked()
{
    emit menuExit();
}

void MenuWidget::on_bOptGraphics_clicked()
{
    setCurrentIndex(MENU_GRAPHICS);

    // set themes list
    ui.lwThemes->clear();
    ui.lwThemes->addItems(gameProfile->themesList());
    QList<QListWidgetItem *> found = ui.lwThemes->findItems(gameProfile->currentTheme(), Qt::MatchFixedString);
    if (found.count())
        ui.lwThemes->setCurrentItem(found.at(0));
    else
        ui.lwThemes->setCurrentRow(0);

    // set video mode
    ui.rbFullscreenMode->setChecked(gameProfile->isFullscreen());
    ui.rbCurrentMode->setChecked(gameProfile->isWindowed());
    ui.rbWindowMode->setChecked(! gameProfile->isFullscreen() && ! gameProfile->isWindowed());

    ui.cbAccel->setChecked(gameProfile->isAccelerated());
}

void MenuWidget::on_bOptSound_clicked()
{
  setCurrentIndex(MENU_AUDIO);

  // sounds
  ui.cbVolumeSound->setValue(gameProfile->currentPlayer()->soundVolume);
  ui.cbMuteSound->setChecked(gameProfile->currentPlayer()->soundVolume == 0);

  // music
  ui.cbVolumeMusic->setValue(gameProfile->currentPlayer()->musicVolume);
  ui.cbMuteMusic->setChecked(!gameProfile->currentPlayer()->musicEnabled);
}

void MenuWidget::on_bOptProfile_clicked()
{
    setCurrentIndex(MENU_PROFILE);
    // set name edit
    QString name = gameProfile->currentPlayer()->name;
    ui.leName->setText(name.isEmpty() ? tr("Player") : name);
    // set users list
    ui.lwPlayersList->clear();
    ui.lwPlayersList->addItem(tr("[New Player]"));
    ui.lwPlayersList->addItems(gameProfile->playerNames());

    QList<QListWidgetItem *> found = ui.lwPlayersList->findItems(name, Qt::MatchFixedString);
    if (found.count())
        ui.lwPlayersList->setCurrentItem(found.at(0));
    else
        ui.lwPlayersList->setCurrentRow(0);
}

void MenuWidget::on_bOptLevels_clicked()
{
    setCurrentIndex(MENU_LEVELS);

    // levels list
    QStringList ext; ext << "*.lpk";
    QStringList lpacks = QDir(GameWidget::getResourcePath() + "levels/").entryList(ext);
    ui.lwLevels->clear();
    for (int i = 0; i < lpacks.count(); i++) {
        QString name = lpacks.at(i).section('.',0,0);
        int cnt = gameProfile->levelPackCount(name);
        ui.lwLevels->addItem(QString("%1 [%2 levels]").arg(name).arg(cnt));
    }

    QList<QListWidgetItem *> found = ui.lwLevels->findItems(gameProfile->currentLevelPack(), Qt::MatchFixedString);
    if (found.count())
        ui.lwLevels->setCurrentItem(found.at(0));
    else
        ui.lwLevels->setCurrentRow(0);
}

void MenuWidget::on_bOptBack_clicked()
{
    setCurrentIndex(MENU_MAIN);
    startAfterSelect = false;
}

void MenuWidget::on_bPauseGraphics_clicked()
{
    on_bOptGraphics_clicked();
}

void MenuWidget::on_bPauseSound_clicked()
{
    on_bOptSound_clicked();
}

void MenuWidget::on_bPauseRestart_clicked()
{
    emit menuRestartLevel();
}

void MenuWidget::on_bPauseAbandon_clicked()
{
    emit menuAbandonGame();
}

void MenuWidget::on_bPauseBack_clicked()
{
    emit menuPauseBack();
}

void MenuWidget::on_bGraphicsOk_clicked()
{
    // apply options
    QListWidgetItem *lwi = ui.lwThemes->currentItem();
    if (lwi) {
        gameProfile->setCurrentTheme(lwi->text());
        emit menuThemeChanged();
    }


    bool fs = ui.rbFullscreenMode->isChecked();
    bool win = ui.rbCurrentMode->isChecked();
    if (fs != gameProfile->isFullscreen() || win != gameProfile->isWindowed())
    {
      gameProfile->setFullscreen(fs);
      gameProfile->setWindowed(win);
      emit menuVideoModeChanged();
    }

    bool acc = ui.cbAccel->isChecked();
    if (acc != gameProfile->isAccelerated())
    {
      QMessageBox::information(0, "Restart needed",
                               "In order to enable or disable acceleration, please restart JAG",
                               QMessageBox::Close);
    }
    gameProfile->setAccelerated(acc);

    on_bGraphicsBack_clicked();
}

void MenuWidget::on_bGraphicsBack_clicked()
{
    setCurrentIndex(gameProfile->isGameStarted() ? MENU_PAUSE : MENU_OPTIONS);
}

void MenuWidget::on_bAudioBack_clicked()
{
  setCurrentIndex(gameProfile->isGameStarted() ? MENU_PAUSE : MENU_OPTIONS);
}

void MenuWidget::on_cbVolumeMusic_valueChanged(int val)
{
  sndEngine->setMusicVolume(val);
  gameProfile->currentPlayer()->musicVolume = val;
}

void MenuWidget::on_cbMuteMusic_toggled(bool on)
{
  sndEngine->enableMusic(!on);
  gameProfile->currentPlayer()->musicEnabled = !on;

  ui.cbVolumeMusic->setEnabled(!on);
}

void MenuWidget::on_cbVolumeSound_valueChanged(int val)
{
  sndEngine->setChannelVolume(val);
  gameProfile->currentPlayer()->soundVolume = val;

  sndEngine->playSound(GameSound::sndBomb);
}

void MenuWidget::on_cbMuteSound_toggled(bool on)
{
  ui.cbVolumeSound->setEnabled(!on);

  if (on) {
    sndEngine->setChannelVolume(0);
    gameProfile->currentPlayer()->soundVolume = 0;
  }
  else {
    on_cbVolumeSound_valueChanged(ui.cbVolumeSound->value());
    gameProfile->currentPlayer()->soundVolume = ui.cbVolumeSound->value();
  }
}

void MenuWidget::on_rbArcade_toggled(bool on)
{
    gameProfile->currentPlayer()->currentLevelPackInfo()->mode = on ? 0 : 1;
}

void MenuWidget::on_rbPuzzle_toggled(bool on)
{
    gameProfile->currentPlayer()->currentLevelPackInfo()->mode = on ? 1 : 0;
}

void MenuWidget::on_sliDifficulty_valueChanged(int val)
{
    gameProfile->currentPlayer()->currentLevelPackInfo()->diff = val;
    QString qs;
    switch (val) {
        case 1: qs = tr("Easy"); break;
        case 2: qs = tr("Normal"); break;
        case 3: qs = tr("Hard"); break;
        default: qs = "";
    }
    ui.labelDiff->setText(qs);
}

void MenuWidget::on_bGameStart_clicked()
{
    emit menuGameStart();
}

void MenuWidget::on_bProfileCancel_clicked()
{
    m_newplayer = false;
    m_renameplayer = false;
    ui.gbPlayerName->setEnabled(false);
    ui.gbPlayersList->setEnabled(true);
    ui.lwPlayersList->setFocus();
}

void MenuWidget::on_bProfileOk_clicked()
{
    QString name = ui.leName->text().simplified();
    if (name.isEmpty())
      return;

    if (m_newplayer) {
        QList<QListWidgetItem *> found = ui.lwPlayersList->findItems(name, Qt::MatchFixedString);
        if (found.isEmpty()) {
            ui.lwPlayersList->addItem(name);
            gameProfile->setCurrentPlayer(name);
        }
    }
    else if (m_renameplayer) {
        gameProfile->renamePlayer(ui.lwPlayersList->currentItem()->text(), name);
        ui.lwPlayersList->currentItem()->setText(name);
    }

    ui.gbPlayerName->setEnabled(false);
    ui.gbPlayersList->setEnabled(true);
    ui.lwPlayersList->setFocus();
}

void MenuWidget::on_bProfileSelect_clicked()
{
    if (ui.lwPlayersList->currentRow() == 0) { // new player clicked
        ui.gbPlayerName->setEnabled(true);
        ui.gbPlayersList->setEnabled(false);
        ui.leName->setText(tr("Player"));
        ui.leName->selectAll();
        ui.leName->setFocus();
        m_newplayer = true;
    }
    else {
        if (ui.lwPlayersList->currentItem()) {
            QString name = ui.lwPlayersList->currentItem()->text();
            if (!name.isEmpty()) {
                // update video mode
                bool fs = gameProfile->isFullscreen();
                bool win = gameProfile->isWindowed();
                gameProfile->setCurrentPlayer(name);
                if (fs != gameProfile->isFullscreen() || win != gameProfile->isWindowed())
                    emit menuVideoModeChanged();

                // update sound settings
                sndEngine->setChannelVolume(gameProfile->currentPlayer()->soundVolume);
                sndEngine->setMusicVolume(gameProfile->currentPlayer()->musicVolume);
                sndEngine->enableMusic(gameProfile->currentPlayer()->musicEnabled);

                if (startAfterSelect)
                    emit menuNew();
                else
                    on_bProfileBack_clicked();
            }
        }
    }
}

void MenuWidget::on_bProfileRename_clicked()
{
    if (ui.lwPlayersList->currentRow() > 0) {
        ui.gbPlayerName->setEnabled(true);
        ui.gbPlayersList->setEnabled(false);
        ui.leName->setText(ui.lwPlayersList->currentItem()->text());
        ui.leName->selectAll();
        ui.leName->setFocus();
        m_renameplayer = true;
    }
}

void MenuWidget::on_bProfileDelete_clicked()
{
    if (ui.lwPlayersList->currentRow() <= 0) return;

    int row = ui.lwPlayersList->currentRow();
    QListWidgetItem *item = ui.lwPlayersList->takeItem(row);
    if (item) {
        gameProfile->removePlayer(item->text());
        delete item;
    }
    if (row > 0 && row < ui.lwPlayersList->count())
        ui.lwPlayersList->setCurrentRow(row);

}

void MenuWidget::on_bProfileBack_clicked()
{
    on_bProfileCancel_clicked();
    setCurrentIndex(MENU_OPTIONS);
}

void MenuWidget::on_lwPlayersList_itemDoubleClicked(QListWidgetItem *item)
{
    on_bProfileSelect_clicked();
}

/*
void MenuWidget::on_bHallBack_clicked()
{
    setCurrentIndex(MENU_MAIN);
}
*/

void MenuWidget::on_bHelpBack_clicked()
{
    setCurrentIndex(MENU_MAIN);
}

void MenuWidget::on_bCreditsBack_clicked()
{
    setCurrentIndex(MENU_MAIN);
}

void MenuWidget::on_bLevelsOk_clicked()
{
    emit menuLevelPack();
}

void MenuWidget::on_bLevelsBack_clicked()
{
    setCurrentIndex(MENU_OPTIONS);
}

void MenuWidget::on_lwLevels_itemDoubleClicked(QListWidgetItem *item)
{
    on_bLevelsOk_clicked();
}

////////////////////////////////////////////////////////////////////////////////
void GameScene::on_menuNew()
{
    if (menu->isActive()) {
        // ask confirmation
        if (gameProfile->currentPlayer()->currentLevelPackInfo()->level > 1) {
            menu->hide();
            if (!dconfirm->exec(tr("Current progress will be lost.\nAre you sure you want to start new game?"))) {
                menu->showNormal();
                return;
            }
        }

        menu->setMenuPage(MENU_GAME);
        menu->activate();
    }
}

void GameScene::on_menuContinue()
{
    if (gameProfile->currentPlayer()->currentLevelPackInfo()->level > max_level) return;

    menu->activate(false);
    gameProfile->setGameStarted(true);
    gameProfile->setGamePaused(false);
    initLevel(gameProfile->currentPlayer()->currentLevelPackInfo()->level);
}

void GameScene::on_menuExit()
{
    // ask confirmation
    menu->hide();
    if (dconfirm->exec(tr("Are you sure you want to quit JAG?"))) {
        stopGame();
        qApp->quit();
    }
    menu->showNormal();
}

void GameScene::on_menuPauseBack()
{
    menu->activate(false);
    continueGame();
}

void GameScene::on_menuRestartLevel()
{
    menu->hide();
    if (dconfirm->exec(tr("Current level progress will be lost.\nAre you sure you want to restart?")))
    {
        initLevel(gameProfile->currentPlayer()->currentLevelPackInfo()->level);
        on_menuPauseBack();
        return;
    }
    menu->showNormal();
}

void GameScene::on_menuAbandonGame()
{
    menu->hide();
    if (dconfirm->exec(tr("Current level progress will be lost.\nAre you sure you want to quit?")))
    {
        // go to main menu
        exitToMainMenu();
    }
    menu->showNormal();
}

void GameScene::on_menuThemeChanged()
{
   myLock = true;
   initTheme();
   drawConcretesOnBackground();
   drawHUDonBackground();
   myLock = false;
}

void GameScene::on_menuGameStart()
{
    menu->activate(false);
    gameProfile->setGameStarted(true);
    gameProfile->setGamePaused(false);
    gameProfile->currentPlayer()->currentLevelPackInfo()->init();
    initLevel(1);
}

void GameScene::on_menuLevelPack()
{
    // ask to change levelpack
    menu->hide();
    QString name = menu->selectedLevelPack();
    if (gameProfile->currentLevelPack() != name) {
        if (!dconfirm->exec(tr("Are you sure you want to select this level pack?"))) {
            menu->showNormal();
            return;
        }
        gameProfile->setCurrentLevelPack(name);
        max_level = gameProfile->levelPackCount(gameProfile->currentLevelPack());
        update();
    }
    menu->showNormal();
    menu->setCurrentIndex(MENU_OPTIONS);
}

bool GameScene::confirmExit()
{
    if (gameProfile->isGameStarted())
    {
        pauseGame();
    }
    if (menu->isActive())
        menu->hide();

    if (dconfirm->exec(tr("Any unsaved progress will be lost.\nAre you sure you want to quit JAG?")))
        return true;

    if (menu->isActive())
        menu->showNormal();
    if (gameProfile->isGamePaused()) {
        menu->activate(false);
        continueGame();
    }
    return false;
}
