/***************************************************************************
 *   copyright       : (C) 2009-2022 by Pascal Brachet                     *
 *   https://www.xm1math.net/algobox/                                      *
 *                                                                         *
 *   This program 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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   @license GPL-2.0+ <https://spdx.org/licenses/GPL-2.0+.html>           *
 ***************************************************************************/

#include <QtGui>
#include <QMenuBar>
#include <QScrollBar>
#include <QToolBar>
#include <QFileDialog>
#include <QStatusBar>
#include <QMessageBox>

#include "jsmainwindow.h"
#include "geticon.h"


JSMainWindow::JSMainWindow(QWidget* parent, int fontsize): QMainWindow( parent)
{
//setWindowTitle("AlgoBox");
#if defined(Q_OS_MAC)
setWindowIcon(QIcon(":/images/algobox128.png"));
#else
setWindowIcon(getIcon(":/images/algobox22.png"));
#endif
setIconSize(QSize(22,22 ));
jsEditView = new JSEditorView(this);
jsEditView->setFontSize(fontsize);
setCentralWidget(jsEditView);

createActions();
createMenus();
createToolBars();
createStatusBar();

connect(jsEditView->editor->document(), SIGNAL(contentsChanged()),this, SLOT(documentWasModified()));

setCurrentFile("");
setUnifiedTitleAndToolBarOnMac(true);
}



void JSMainWindow::closeEvent(QCloseEvent *event)

{
    if (maybeSave()) {
        jsEditView->editor->clear();
        setCurrentFile("");
        event->accept();
    } else {
        event->ignore();
    }
}



void JSMainWindow::newFile()

{
    if (maybeSave()) {
        jsEditView->editor->clear();
        setCurrentFile("");
    }
}



void JSMainWindow::open()

{
    if (maybeSave()) {
        QString fileName = QFileDialog::getOpenFileName(this,QString::fromUtf8("Ouvrir Extension"),QDir::homePath(),"Fichier javascript (*.js)");
        if (!fileName.isEmpty())
            loadFile(fileName);
    }
}



bool JSMainWindow::save()

{
    if (curFile.isEmpty()) {
        return saveAs();
    } else {
        return saveFile(curFile);
    }
}



bool JSMainWindow::saveAs()

{
    QString fileName = QFileDialog::getSaveFileName(this,QString::fromUtf8("Enregistrer sous"),QDir::homePath(),QString::fromUtf8("Fichier javascript (*.js)"));
    if (fileName.isEmpty())
        return false;

    return saveFile(fileName);
}




void JSMainWindow::documentWasModified()
{
    setWindowModified(jsEditView->editor->document()->isModified());
}



void JSMainWindow::createActions()

{
    newAct = new QAction(getIcon(":/images/nouveau22.png"), QString::fromUtf8("&Nouveau"), this);
    newAct->setShortcuts(QKeySequence::New);
    connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));


    openAct = new QAction(getIcon(":/images/ouvrir22.png"), QString::fromUtf8("&Ouvrir"), this);
    openAct->setShortcuts(QKeySequence::Open);
    connect(openAct, SIGNAL(triggered()), this, SLOT(open()));


    saveAct = new QAction(getIcon(":/images/sauver22.png"), QString::fromUtf8("&Sauver"), this);
    saveAct->setShortcuts(QKeySequence::Save);
    connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));

    saveAsAct = new QAction(getIcon(":/images/sauversous.png"),QString::fromUtf8("Sauver So&us"), this);
    saveAsAct->setShortcuts(QKeySequence::SaveAs);
    connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));


    exitAct = new QAction(QString::fromUtf8("&Quitter"), this);
    exitAct->setShortcuts(QKeySequence::Quit);
    connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));


    cutAct = new QAction(getIcon(":/images/couper22.png"), QString::fromUtf8("Co&uper"), this);
    cutAct->setShortcuts(QKeySequence::Cut);
    connect(cutAct, SIGNAL(triggered()), jsEditView->editor, SLOT(cut()));

    copyAct = new QAction(getIcon(":/images/copier22.png"), QString::fromUtf8("Cop&ier"), this);
    copyAct->setShortcuts(QKeySequence::Copy);
    connect(copyAct, SIGNAL(triggered()), jsEditView->editor, SLOT(copy()));

    pasteAct = new QAction(getIcon(":/images/coller22.png"), QString::fromUtf8("C&oller"), this);
    pasteAct->setShortcuts(QKeySequence::Paste);
    connect(pasteAct, SIGNAL(triggered()), jsEditView->editor, SLOT(paste()));
    
    undoAct = new QAction(getIcon(":/images/undo22.png"), QString::fromUtf8("&Défaire"), this);
    undoAct->setShortcuts(QKeySequence::Undo);
    connect(undoAct, SIGNAL(triggered()), jsEditView->editor, SLOT(undo()));

    redoAct = new QAction(getIcon(":/images/redo22.png"), QString::fromUtf8("&Refaire"), this);
    redoAct->setShortcuts(QKeySequence::Redo);
    connect(redoAct, SIGNAL(triggered()), jsEditView->editor, SLOT(redo()));



    cutAct->setEnabled(false);
    copyAct->setEnabled(false);
    undoAct->setEnabled(false);
    redoAct->setEnabled(false);
    connect(jsEditView->editor, SIGNAL(copyAvailable(bool)),
            cutAct, SLOT(setEnabled(bool)));
    connect(jsEditView->editor, SIGNAL(copyAvailable(bool)),
            copyAct, SLOT(setEnabled(bool)));
    connect(jsEditView->editor->document(), SIGNAL(undoAvailable(bool)),
            undoAct, SLOT(setEnabled(bool)));
    connect(jsEditView->editor->document(), SIGNAL(redoAvailable(bool)),
            redoAct, SLOT(setEnabled(bool)));
}



void JSMainWindow::createMenus()

{
fileMenu = menuBar()->addMenu(QString::fromUtf8("&Fichier"));
fileMenu->addAction(newAct);

fileMenu->addAction(openAct);

fileMenu->addAction(saveAct);

fileMenu->addAction(saveAsAct);
fileMenu->addSeparator();
fileMenu->addAction(exitAct);

editMenu = menuBar()->addMenu(QString::fromUtf8("&Edition"));
editMenu->addAction(cutAct);
editMenu->addAction(copyAct);
editMenu->addAction(pasteAct);
QAction *Act;
Act = new QAction(QString::fromUtf8("&Sélectionner tout"), this);
Act->setShortcut(QKeySequence::SelectAll);
connect(Act, SIGNAL(triggered()), jsEditView->editor, SLOT(wantReplace()));
editMenu->addAction(Act);
editMenu->addSeparator();
editMenu->addAction(undoAct);
editMenu->addAction(redoAct);



Act = new QAction(QString::fromUtf8("&Chercher"), this);
Act->setShortcut(QKeySequence::Find);
connect(Act, SIGNAL(triggered()), jsEditView->editor, SLOT(wantFind()));
editMenu->addAction(Act);

Act = new QAction(QString::fromUtf8("&Remplacer"), this);
Act->setShortcut(QKeySequence::Replace);
connect(Act, SIGNAL(triggered()), jsEditView->editor, SLOT(wantReplace()));
editMenu->addAction(Act);

editMenu->addSeparator();

Act = new QAction(QString::fromUtf8("I&ndenter sélection"), this);
connect(Act, SIGNAL(triggered()), jsEditView->editor, SLOT(indentSelection()));
editMenu->addAction(Act);

Act = new QAction(QString::fromUtf8("Désinden&ter sélection"), this);
connect(Act, SIGNAL(triggered()), jsEditView->editor, SLOT(unindentSelection()));
editMenu->addAction(Act);

editMenu->addSeparator();

Act = new QAction(QString::fromUtf8("Co&mmenter sélection"), this);
connect(Act, SIGNAL(triggered()), jsEditView->editor, SLOT(commentSelection()));
editMenu->addAction(Act);

Act = new QAction(QString::fromUtf8("Décomm&enter sélection"), this);
connect(Act, SIGNAL(triggered()), jsEditView->editor, SLOT(uncommentSelection()));
editMenu->addAction(Act);

}



void JSMainWindow::createToolBars()
{
fileToolBar = addToolBar(QString::fromUtf8("Fichier"));
fileToolBar->addAction(newAct);

fileToolBar->addAction(openAct);

fileToolBar->addAction(saveAct);
fileToolBar->setFloatable(false);
fileToolBar->setOrientation(Qt::Horizontal);
fileToolBar->setMovable(false);
fileToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
editToolBar = addToolBar(QString::fromUtf8("Edition"));
editToolBar->addAction(cutAct);
editToolBar->addAction(copyAct);
editToolBar->addAction(pasteAct);
editToolBar->addAction(undoAct);
editToolBar->addAction(redoAct);
editToolBar->setFloatable(false);
editToolBar->setOrientation(Qt::Horizontal);
editToolBar->setMovable(false);
editToolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
}



void JSMainWindow::createStatusBar()

{
    statusBar()->showMessage(QString::fromUtf8("Prêt"));
}




bool JSMainWindow::maybeSave()

{
    if (jsEditView->editor->document()->isModified()) {
	switch(  QMessageBox::warning(this,QString::fromUtf8("AlgoBox : "),
					QString::fromUtf8("Le code courant a été modifié.\nVoulez-vous l'enregistrer avant de quitter?"),
					QString::fromUtf8("Enregistrer"), QString::fromUtf8("Ne pas enregistrer"), QString::fromUtf8("Abandon"),
					0,
					2 ) )
		{
		case 0:
		return save();
		break;
		case 1:
		return true;  
		break;
		case 2:
		default:
		return false;
		break;
		}
    }
    return true;
}



void JSMainWindow::loadFile(const QString &fileName)

{
    QFile file(fileName);
    if (!file.open(QFile::ReadOnly | QFile::Text)) {
        QMessageBox::warning(this, QString::fromUtf8("AlgoBox : "),
                             QString::fromUtf8("Impossible de lire le fichier %1:\n%2.")
                             .arg(fileName)
                             .arg(file.errorString()));
        return;
    }

    QTextStream in(&file);
#ifndef QT_NO_CURSOR
    QApplication::setOverrideCursor(Qt::WaitCursor);
#endif
    jsEditView->editor->setPlainText(in.readAll());
#ifndef QT_NO_CURSOR
    QApplication::restoreOverrideCursor();
#endif

    setCurrentFile(fileName);
    statusBar()->showMessage(QString::fromUtf8("Fichier chargé"), 2000);
}



bool JSMainWindow::saveFile(const QString &fileName)

{
    QFile file(fileName);
    if (!file.open(QFile::WriteOnly | QFile::Text)) {
        QMessageBox::warning(this, QString::fromUtf8("AlgoBox"),
                             QString::fromUtf8("Impossible d'écrire le fichier %1:\n%2.")
                             .arg(fileName)
                             .arg(file.errorString()));
        return false;
    }

    QTextStream out(&file);
#ifndef QT_NO_CURSOR
    QApplication::setOverrideCursor(Qt::WaitCursor);
#endif
    out << jsEditView->editor->toPlainText();
#ifndef QT_NO_CURSOR
    QApplication::restoreOverrideCursor();
#endif

    setCurrentFile(fileName);
    statusBar()->showMessage(QString::fromUtf8("Fichier sauvé"), 2000);
    return true;
}



void JSMainWindow::setCurrentFile(const QString &fileName)

{
    curFile = fileName;
    jsEditView->editor->document()->setModified(false);
    setWindowModified(false);

    QString shownName = curFile;
    if (curFile.isEmpty())
        shownName = "sanstitre.js";
    setWindowFilePath(shownName);
}



QString JSMainWindow::strippedName(const QString &fullFileName)

{
    return QFileInfo(fullFileName).fileName();
}

