/** Copyright (c) 2020-2023 The Creators of Simphone

    class LoginDialog (QDialog): parent of all login screen classes (Generate, SeedGen, ShowSeed, Login, KeyGen)

    See the file COPYING.LESSER.txt for copying permission.
**/

#include "qtfix.h"
#include "consoledialog.h"
#include "contacts.h"
#include "chatframe.h"
#include "settings.h"
#include "usermanual.h"
#include "about.h"

#include <QKeyEvent>

static int g_loginXpos = -1, g_loginYpos = -1;
int LoginDialog::mc_modal = 0;

LoginDialog::LoginDialog(QWidget * parent)
  : Parent(parent)
{
  mc_modal = 0;
}

LoginDialog::~LoginDialog()
{
  mc_modal = 0;
  savePosition();
}

void LoginDialog::savePosition()
{
  g_loginXpos = pos().x();
  g_loginYpos = pos().y();
}

void LoginDialog::restorePosition()
{
  if (g_loginXpos > 0 || g_loginYpos > 0) move(g_loginXpos, g_loginYpos);
}

int LoginDialog::adjustToBiggerSize()
{
  int oldWidth = size().width();
  int oldHeight = size().height();
  resize(sizeHint());
  int newWidth = size().width();
  int newHeight = size().height();
  if (newWidth < oldWidth || newHeight < oldHeight) {
    resize(newWidth < oldWidth ? oldWidth : newWidth, newHeight < oldHeight ? oldHeight : newHeight);
  }
  return width();
}

int LoginDialog::exec()
{
  restorePosition();
  SimCore::get()->setLoginDialog(this);
  int result = Parent::exec();
  SimCore::get()->setLoginDialog(0);
  return result;
}

void LoginDialog::showEvent(QShowEvent * event)
{
  restorePosition();
  Parent::showEvent(event);
}

void LoginDialog::hideEvent(QHideEvent * event)
{
  savePosition();
  Parent::hideEvent(event);
}

void LoginDialog::changeEvent(QEvent * event)
{
  if (event->type() == QEvent::FontChange) done(-2);
  Parent::changeEvent(event);
}

bool LoginDialog::checkKey(QKeyEvent * event)
{
  if (qtfix::hasAltModifier(event, Qt::AltModifier | Qt::MetaModifier)) {
    switch (event->key()) {
      case Qt::Key_A: on_actionAudioDevices_triggered(); return true;
      case Qt::Key_C: on_actionConsole_triggered(); return true;
      case Qt::Key_Q: on_actionQuit_triggered(); return true;
    }
  }

  return false;
}

bool LoginDialog::eventFilter(QObject * obj, QEvent * event)
{
  if (event->type() == QEvent::KeyPress) {
    QKeyEvent * keyEvent = static_cast<QKeyEvent *>(event);
    if (checkKey(keyEvent)) return true;
  }

  return Parent::eventFilter(obj, event);
}

void LoginDialog::keyPressEvent(QKeyEvent * event)
{
  if (!checkKey(event) && event->key() != Qt::Key_Escape) Parent::keyPressEvent(event);
}

void LoginDialog::prepareLanguage(QMenu * help, QAction * english, QAction * french, QAction * german)
{
  QString language(SimParam::getString("ui.login.language"));
  if (!language.compare("English", Qt::CaseInsensitive)) {
    english->setChecked(true);
  } else if (!language.compare("French", Qt::CaseInsensitive)) {
    french->setChecked(true);
  } else if (!language.compare("German", Qt::CaseInsensitive)) {
    german->setChecked(true);
  }
  if (help) {
    qtfix::fixMenuIndicator(english, help, QFont());
    qtfix::fixMenuIndicator(french, help, QFont());
    qtfix::fixMenuIndicator(german, help, QFont());
  }
}

void LoginDialog::setLanguage(const QString & name, QAction * language0, QAction * language1, QAction * language2)
{
  QString qs = "";
  if (language0->isChecked()) {
    language1->setChecked(false);
    language2->setChecked(false);
    qs = name;
  }
  SimParam::set("ui.login.language", qs.toUtf8().data(), false);
  qtfix::setLanguage(qs);
}

void LoginDialog::on_actionEnglish_triggered(QAction * english, QAction * french, QAction * german)
{
  setLanguage("english", english, french, german);
}

void LoginDialog::on_actionFrench_triggered(QAction * english, QAction * french, QAction * german)
{
  setLanguage("french", french, english, german);
}

void LoginDialog::on_actionGerman_triggered(QAction * english, QAction * french, QAction * german)
{
  setLanguage("german", german, english, french);
}

void LoginDialog::on_actionQuit_triggered()
{
  done(-1);
}

void LoginDialog::on_actionConsole_triggered()
{
  Contact * c = SimCore::getContact(SimCore::get()->getTestContactId());
  // do not open console if already open - it would not work and even crash
  if (!c || !c->m_chatFrame || !c->m_chatFrame->isVisible()) {
    ConsoleDialog console(0, true);
    if (console.exec() < 0) done(-1);
  }
}

void LoginDialog::on_actionAudioDevices_triggered()
{
  if (Settings::isActive()) return;

  mc_modal++;
  if (!sim_audio_check_talking_()) {
    Settings * s = new Settings(this, 'l');
    s->prepareAudio(true);
    s->exec();
  } else {
    QMessageBox::warning(this, tr("Choose audio devices"),
                         tr("Hang up your audio test, before choosing new audio devices."));
  }
  mc_modal--;
}

void LoginDialog::on_actionUserManual_triggered()
{
  UserManual * um = new UserManual(0);
  qtfix::showMaximizedWindow(um);
  mc_modal++;
  um->exec();
  mc_modal--;
}

void LoginDialog::on_actionAbout_triggered()
{
  About * a = new About(0);
  mc_modal++;
  a->exec();
  mc_modal--;
}
