/*********************************************************************/
/*                                                                   */
/* Copyright 2022-2023 Rémi Synave - remi.synave@univ-littoral.fr    */
/*                                                                   */
/* This file is part of DSL.                                         */
/* This software uses Qt to build the Graphical User Interface       */
/* https://www.qt.io/                                                */
/*                                                                   */
/* DSL 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.                            */
/*                                                                   */
/* DSL 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 DSL. If not, see <http://www.gnu.org/licenses/>.       */
/*                                                                   */
/*********************************************************************/

#include <QIcon>
#include <QGuiApplication>
#include <QScreen>
#include <QWidget>
#include <QMenuBar>
#include <QFileDialog>
#include <QUrl>
#include <QFileInfo>
#include <QInputDialog>
#include <QDirIterator>

#include <QDebug>

#include <iostream>
#include <filesystem>

#include "MainWindow.hpp"


MainWindow::MainWindow ()
{
  setWindowIcon(QIcon("../dsl.ico"));
  
  createActions ();
  createMenus ();

  openedImage = -1;
  directoryname = NULL;
  suffix = NULL;
  filenames = NULL;
  autoLoad = true;

  setWindowTitle (tr ("DSL - Draw Strength Line"));

  QScreen *screen = QGuiApplication::primaryScreen ();
  QRect screenGeometry = screen->geometry ();
  int screenWidth = screenGeometry.width () - 200;
  int screenHeight = screenGeometry.height () - 200;
  
  wa = new WorkArea (screenWidth, screenHeight, this);
  wa->setReadOnly(false);
  setCentralWidget (wa);

  setFixedSize (screenWidth, screenHeight);
}

void
MainWindow::openFile ()
{
  if(this->checkModificationinProgress() == QMessageBox::Yes){
    QString filename = QFileDialog::getOpenFileName (this,
						     QObject::tr ("Open image file"),
						     QDir::currentPath (),
						     QObject::tr("Images files (*.jpg *.png);;All files (*.*)"));

    if(!filename.isEmpty()) {
    
      directoryname = new QString(QString(filename).remove(QUrl(filename).fileName()));
    
      bool ok;
      suffix = new QString(QInputDialog::getText(this, tr("Suffix for your json files"),
						 tr("Suffix to use :"), QLineEdit::Normal,
						 "_"+QDir::home().dirName(), &ok));

      if(ok)
	{
	  delete filenames;
	  filenames = new QStringList();
	
	  QDirIterator it(*directoryname, {"*.jpg", "*.png"}, QDir::Files);
	  while (it.hasNext()) {
	    filenames->append( it.next() );
	  }
	  filenames->sort();
	
	  for(int i = 0; i <filenames->size() ; i++)
	    {
	      if(filename == (filenames->at(i)))
		openedImage = i;
	    }

	  QDir::setCurrent(*directoryname);
	  loadImage();
	}
    }
  }
}

void
MainWindow::loadImage()
{
  wa->loadImage (filenames->at(openedImage).toStdString ());
  if(autoLoad)
    {
      QString jsonFile(QDir::currentPath ().append("/").append(QFileInfo(filenames->at(openedImage)).baseName().append(*suffix).append(".json")));
      if(QFile(jsonFile).exists()){
	wa->loadSL(QDir::currentPath ().append("/").append(QFileInfo(filenames->at(openedImage)).baseName().append(*suffix).append(".json")).toStdString());
      }
    }
  wa->repaint();
  wa->setModificationInProgress(false);
  setFixedSize (wa->geometry().width(), wa->geometry().height()+wa->geometry().y());
}

void
MainWindow::save ()
{
  QString toSave =  QDir::currentPath ().append("/").append(QFileInfo(filenames->at(openedImage)).baseName().append(*suffix).append(".json"));
  wa->saveStrengthLine (toSave.toStdString ());
}

void
MainWindow::exportPNG ()
{
  QString toSave =  QDir::currentPath ().append("/").append(QFileInfo(filenames->at(openedImage)).baseName().append(*suffix).append(".png"));
  wa->exportPNG (toSave.toStdString ());
}

QMessageBox::StandardButton
MainWindow::checkModificationinProgress()
{
  if(wa->getModificationInProgress())
    return QMessageBox::question(this, "Modification in progress", "Do you really want to change the image ? Modifications in progress will be lost.");
  return QMessageBox::Yes;
}

void
MainWindow::firstImage ()
{
  if(filenames != NULL)
    if(filenames->size() > 1)
      if(this->checkModificationinProgress() == QMessageBox::Yes){
	openedImage = 0;
	loadImage();
      }
}

void
MainWindow::previousImage ()
{
  if(filenames != NULL)
    if(filenames->size() > 1)
      if(this->checkModificationinProgress() == QMessageBox::Yes){
	openedImage = (openedImage-1+filenames->size())%(filenames->size());
	loadImage();
      }
}

void
MainWindow::nextImage ()
{
  if(filenames != NULL)
    if(filenames->size() > 1)
      if(this->checkModificationinProgress() == QMessageBox::Yes){
	openedImage = (openedImage+1)%(filenames->size());
	loadImage();
      }
}

void
MainWindow::lastImage ()
{
  if(filenames != NULL)
    if(filenames->size() > 1)
      if(this->checkModificationinProgress() == QMessageBox::Yes){
	openedImage = filenames->size()-1;
	loadImage();
      }
}

void
MainWindow::automaticLoading ()
{
  autoLoad = !autoLoad;
  automaticLoadingAct->setChecked(!autoLoad);
}


void
MainWindow::readOnly ()
{
  if(wa->getReadOnly()){
    wa->setReadOnly(false);
    readOnlyAct->setText(tr ("W&ritable"));
  }else{
    wa->setReadOnly(true);
    readOnlyAct->setText(tr ("&Read Only"));
  }
  wa->repaint();
}

void
MainWindow::about (){
  QMessageBox::information(this, "About", "DSL - Draw Strength Line\nVersion 1.0\n\nRémi Synave - remi.synave@univ-littoral.fr\n\nGNU GENERAL PUBLIC LICENSE Version 3");
}


void
MainWindow::createActions ()
{
  openAct = new QAction (tr ("&Open image"), this);
  openAct->setShortcuts (QKeySequence::Open);
  connect (openAct, &QAction::triggered, this, &MainWindow::openFile);

  saveAct = new QAction (tr ("&Save"), this);
  saveAct->setShortcuts (QKeySequence::Save);
  connect (saveAct, &QAction::triggered, this, &MainWindow::save);

  exportAct = new QAction (tr ("&Export in PNG"), this);
  exportAct->setShortcut (QKeySequence(Qt::CTRL | Qt::Key_E));
  connect (exportAct, &QAction::triggered, this, &MainWindow::exportPNG);

  exitAct = new QAction (tr ("E&xit"), this);
  exitAct->setShortcuts (QKeySequence::Quit);
  connect (exitAct, &QAction::triggered, this, &QWidget::close);

  automaticLoadingAct = new QAction (tr ("Automatic &Loading Line json file"), this);
  automaticLoadingAct->setShortcut (QKeySequence(Qt::CTRL | Qt::Key_L));
  automaticLoadingAct->setCheckable(true);
  automaticLoadingAct->setChecked(true);
  connect (automaticLoadingAct, &QAction::triggered, this, &MainWindow::automaticLoading);

  readOnlyAct = new QAction (tr ("&Read Only"), this);
  readOnlyAct->setShortcut (QKeySequence(Qt::CTRL | Qt::Key_R));
  connect (readOnlyAct, &QAction::triggered, this, &MainWindow::readOnly);

  firstImageAct = new QAction (tr ("First"), this);
  firstImageAct->setShortcuts (QKeySequence::MoveToPreviousLine);
  connect (firstImageAct, &QAction::triggered, this, &MainWindow::firstImage);

  previousImageAct = new QAction (tr ("Previous"), this);
  previousImageAct->setShortcuts (QKeySequence::MoveToPreviousChar);
  connect (previousImageAct, &QAction::triggered, this, &MainWindow::previousImage);
  
  nextImageAct = new QAction (tr ("Next"), this);
  nextImageAct->setShortcuts (QKeySequence::MoveToNextChar);
  connect (nextImageAct, &QAction::triggered, this, &MainWindow::nextImage);

  lastImageAct = new QAction (tr ("Last"), this);
  lastImageAct->setShortcuts (QKeySequence::MoveToNextLine);
  connect (lastImageAct, &QAction::triggered, this, &MainWindow::lastImage);

  aboutAct = new QAction (tr ("About"), this);
  connect (aboutAct, &QAction::triggered, this, &MainWindow::about);
}

void
MainWindow::createMenus ()
{
  fileMenu = menuBar ()->addMenu (tr ("&File"));
  fileMenu->addAction (openAct);
  fileMenu->addAction (saveAct);
  fileMenu->addAction (exportAct);

  fileMenu->addSeparator ();

  fileMenu->addAction (exitAct);

  editMenu = menuBar()->addMenu(tr("&Edit"));
  editMenu->addAction (automaticLoadingAct);
  editMenu->addAction (readOnlyAct);

  imageMenu = menuBar ()->addMenu (tr ("&Image"));
  imageMenu->addAction (firstImageAct);
  imageMenu->addAction (previousImageAct);
  imageMenu->addAction (nextImageAct);
  imageMenu->addAction (lastImageAct);

  
  menuBar()->addAction(aboutAct);
}
