/***************************************************************************
 *   Copyright (C) 2007 by Ian Reinhart Geiser   *
 *   geiseri@yahoo.com   *
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 *   This program 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 this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include <QtGui>
#include "jot.h"

#include <QTextEdit>
#include <QTextStream>
#include <QCloseEvent>
#include <QFileDialog>
#include <QKeySequence>
#include <QActionGroup>

JotMainWindow::JotMainWindow()
{
	m_ui.setupUi(this);
	createActions();
      readSettings();
	m_ui.linkEditFrame->hide();
	m_ui.toolBar->addAction( m_ui.menuHeading->menuAction() );
	m_ui.actionNoHeading->setChecked(true);

	m_ui.wikiEditor->setAcceptRichText(true);
    m_ui.wikiEditor->setWordWrapMode(QTextOption::WordWrap);

	m_headings = new QActionGroup(this);
	m_headings->addAction( m_ui.actionNoHeading );
	m_headings->addAction( m_ui.actionHeading1 );
	m_headings->addAction( m_ui.actionHeading2 );
	m_headings->addAction( m_ui.actionHeading3 );
	m_headings->addAction( m_ui.actionHeading4 );
	m_headings->addAction( m_ui.actionHeading5 );
	m_headings->addAction( m_ui.actionHeading6 );
	m_headings->setExclusive(true);

    connect(m_ui.wikiEditor->document(), SIGNAL(contentsChanged()),
            this, SLOT(documentWasModified()));

      setCurrentFile("");
}

void JotMainWindow::closeEvent(QCloseEvent *event)
{
      if (maybeSave()) {
            writeSettings();
            event->accept();
      } else {
            event->ignore();
      }
}

void JotMainWindow::newFile()
{
      if (maybeSave()) {
            m_ui.wikiEditor->clear();
            setCurrentFile("");
      }
}

void JotMainWindow::open()
{
      if (maybeSave()) {
            QString fileName = QFileDialog::getOpenFileName(this);
            if (!fileName.isEmpty())
            loadFile(fileName);
      }
}

bool JotMainWindow::save()
{
      if (curFile.isEmpty()) {
            return saveAs();
      } else {
            return saveFile(curFile);
      }
}

bool JotMainWindow::saveAs()
{
      QString fileName = QFileDialog::getSaveFileName(this);
      if (fileName.isEmpty())
            return false;

      return saveFile(fileName);
}

void JotMainWindow::about()
{
      QMessageBox::about(this, tr("About Jot"),
            tr("The <b>Jot</b> example demonstrates how to "
                  "write modern GUI applications using Qt, with a menu bar, "
                  "toolbars, and a status bar."));
}

void JotMainWindow::documentWasModified()
{
      setWindowModified(true);
}

void JotMainWindow::createActions()
{

	m_ui.actionNew->setShortcut(QKeySequence::New);
	m_ui.actionOpen->setShortcut(QKeySequence::Open);
	m_ui.actionSave->setShortcut(QKeySequence::Save);
	m_ui.actionExit->setShortcut(tr("Ctrl+Q"));
	m_ui.actionCut->setShortcut(QKeySequence::Cut);
	m_ui.actionCopy->setShortcut(QKeySequence::Copy);
	m_ui.actionPaste->setShortcut(QKeySequence::Paste);
	m_ui.actionBold->setShortcut(QKeySequence::Bold);
	m_ui.actionItalics->setShortcut(QKeySequence::Italic);

	connect(m_ui.actionNew, SIGNAL(triggered()), this, SLOT(newFile()));
	connect(m_ui.actionOpen, SIGNAL(triggered()), this, SLOT(open()));
	connect(m_ui.actionSave, SIGNAL(triggered()), this, SLOT(save()));
	connect(m_ui.actionSaveAs, SIGNAL(triggered()), this, SLOT(saveAs()));
	connect(m_ui.actionExit, SIGNAL(triggered()), this, SLOT(close()));
	connect(m_ui.actionCut, SIGNAL(triggered()), m_ui.wikiEditor, SLOT(cut()));
	connect(m_ui.actionCopy, SIGNAL(triggered()), m_ui.wikiEditor, SLOT(copy()));
	connect(m_ui.actionPaste, SIGNAL(triggered()), m_ui.wikiEditor, SLOT(paste()));
	connect(m_ui.actionAboutJot, SIGNAL(triggered()), this, SLOT(about()));
	connect(m_ui.actionAboutQt, SIGNAL(triggered()), qApp, SLOT(aboutQt()));

	m_ui.actionCut->setEnabled(false);
	m_ui.actionCopy->setEnabled(false);
	connect(m_ui.wikiEditor, SIGNAL(copyAvailable(bool)),
		m_ui.actionCut, SLOT(setEnabled(bool)));
	connect(m_ui.wikiEditor, SIGNAL(copyAvailable(bool)),
		m_ui.actionCopy, SLOT(setEnabled(bool)));
}

void JotMainWindow::readSettings()
{
      QSettings settings("KDE", "Jot");
      QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
      QSize size = settings.value("size", QSize(400, 400)).toSize();
      resize(size);
      move(pos);
}

void JotMainWindow::writeSettings()
{
      QSettings settings("KDE", "Jot");
      settings.setValue("pos", pos());
      settings.setValue("size", size());
}

bool JotMainWindow::maybeSave()
{
      if (m_ui.wikiEditor->document()->isModified()) {
            int ret = QMessageBox::warning(this, tr("Jot"),
                        tr("The document has been modified.\n"
                        "Do you want to save your changes?"),
                        QMessageBox::Yes | QMessageBox::Default,
                        QMessageBox::No,
                        QMessageBox::Cancel | QMessageBox::Escape);
            if (ret == QMessageBox::Yes)
            return save();
            else if (ret == QMessageBox::Cancel)
            return false;
      }
      return true;
}

void JotMainWindow::loadFile(const QString &fileName)
{
      QFile file(fileName);
      if (!file.open(QFile::ReadOnly | QFile::Text)) {
            QMessageBox::warning(this, tr("Jot"),
                              tr("Cannot read file %1:\n%2.")
                              .arg(fileName)
                              .arg(file.errorString()));
            return;
      }

      QTextStream in(&file);
      QApplication::setOverrideCursor(Qt::WaitCursor);
      m_ui.wikiEditor->setHtml(in.readAll());
      QApplication::restoreOverrideCursor();

      setCurrentFile(fileName);
      statusBar()->showMessage(tr("File loaded"), 2000);
}

bool JotMainWindow::saveFile(const QString &fileName)
{
      QFile file(fileName);
      if (!file.open(QFile::WriteOnly | QFile::Text)) {
            QMessageBox::warning(this, tr("Jot"),
                              tr("Cannot write file %1:\n%2.")
                              .arg(fileName)
                              .arg(file.errorString()));
            return false;
      }

      QTextStream out(&file);
      QApplication::setOverrideCursor(Qt::WaitCursor);
      out << m_ui.wikiEditor->toHtml();
      QApplication::restoreOverrideCursor();

      setCurrentFile(fileName);
      statusBar()->showMessage(tr("File saved"), 2000);
      return true;
}

void JotMainWindow::setCurrentFile(const QString &fileName)
{
      curFile = fileName;
      m_ui.wikiEditor->document()->setModified(false);
      setWindowModified(false);

      QString shownName;
      if (curFile.isEmpty())
            shownName = "untitled.txt";
      else
            shownName = strippedName(curFile);

      setWindowTitle(tr("%1[*] - %2").arg(shownName).arg(tr("Jot")));
}

QString JotMainWindow::strippedName(const QString &fullFileName)
{
      return QFileInfo(fullFileName).fileName();
}

JotMainWindow::~JotMainWindow()
{

}

void JotMainWindow::on_actionBold_activated( )
{
	QTextCharFormat format = m_ui.wikiEditor->currentCharFormat();
	if( format.fontWeight() == QFont::Bold )
		format.setFontWeight( QFont::Normal );
	else
		format.setFontWeight( QFont::Bold );

	m_ui.wikiEditor->setCurrentCharFormat( format );
}

void JotMainWindow::on_wikiEditor_cursorPositionChanged( )
{
	QTextCharFormat format = m_ui.wikiEditor->currentCharFormat();
	m_ui.actionBold->setChecked(format.fontWeight() == QFont::Bold );
	m_ui.actionLink->setChecked( format.isAnchor() );

	if( format.isAnchor() )
		m_ui.linkEditFrame->show();
	else
		m_ui.linkEditFrame->hide();

	configureLinkEditor(  );
}

void JotMainWindow::on_actionLink_activated( )
{
	QTextCharFormat format = m_ui.wikiEditor->currentCharFormat();
	if( format.isAnchor())
	{
		format.setAnchor(false);
		format.setUnderlineStyle( QTextCharFormat::NoUnderline );
		format.setForeground(Qt::black);
	}
	else
	{
		format.setAnchor(true);
		format.setUnderlineStyle( QTextCharFormat::SingleUnderline );
		format.setForeground(Qt::blue);
	}
	m_ui.wikiEditor->mergeCurrentCharFormat( format );
	configureLinkEditor(  );
}

void JotMainWindow::configureLinkEditor( )
{
	QTextCharFormat format = m_ui.wikiEditor->currentCharFormat();
	if( format.isAnchor() )
	{
		m_ui.linkEditFrame->show();
		m_ui.linkUrl->setText( format.anchorHref() );
	}
	else
	{
		m_ui.linkEditFrame->hide();
		m_ui.linkUrl->clear();
	}
}

void JotMainWindow::on_linkUrl_textEdited( const QString & text )
{
	QTextCharFormat format = m_ui.wikiEditor->currentCharFormat();
	if( format.isAnchor() )
	{
		QTextCursor linkCursor = m_ui.wikiEditor->textCursor();
		int start = linkCursor.position();
		while( linkCursor.charFormat() == format && !linkCursor.atStart() )
		{
			linkCursor.movePosition( QTextCursor::Left );
		}
		linkCursor.setPosition( start, QTextCursor::KeepAnchor );
		while( linkCursor.charFormat() == format && !linkCursor.atEnd() )
		{
			linkCursor.movePosition( QTextCursor::Right, QTextCursor::KeepAnchor );
		}
		linkCursor.movePosition( QTextCursor::Left, QTextCursor::KeepAnchor );

		format.setAnchorHref( m_ui.linkUrl->text() );
		linkCursor.setCharFormat( format );
	}
}

void JotMainWindow::on_actionImage_activated( )
{
}

void JotMainWindow::on_actionHorizontalRule_activated( )
{
	QTextCursor cursor = m_ui.wikiEditor->textCursor();
	QTextBlockFormat blockFormat = cursor.blockFormat();
	QTextCharFormat charFormat = cursor.charFormat();
	cursor.insertHtml("<HR>");
	cursor.insertBlock(blockFormat, charFormat);
	m_ui.wikiEditor->setTextCursor(cursor);
}

void JotMainWindow::on_actionItalics_activated( )
{
}

void JotMainWindow::on_actionUnderline_activated( )
{
}

void JotMainWindow::on_actionNoHeading_activated( )
{
	// Select block remove all formatting.

	/*
        case Html_h2:
            charFormat.setFontWeight(QFont::Bold);
            charFormat.setProperty(QTextFormat::FontSizeAdjustment, int(2));
            margin[QTextHtmlParser::MarginTop] = 16;
            margin[QTextHtmlParser::MarginBottom] = 12;
            break;
        case Html_h3:
            charFormat.setFontWeight(QFont::Bold);
            charFormat.setProperty(QTextFormat::FontSizeAdjustment, int(1));
            margin[QTextHtmlParser::MarginTop] = 14;
            margin[QTextHtmlParser::MarginBottom] = 12;
            break;
        case Html_h4:
            charFormat.setFontWeight(QFont::Bold);
            charFormat.setProperty(QTextFormat::FontSizeAdjustment, int(0));
            margin[QTextHtmlParser::MarginTop] = 12;
            margin[QTextHtmlParser::MarginBottom] = 12;
            break;
        case Html_h5:
            charFormat.setFontWeight(QFont::Bold);
            charFormat.setProperty(QTextFormat::FontSizeAdjustment, int(-1));
            margin[QTextHtmlParser::MarginTop] = 12;
            margin[QTextHtmlParser::MarginBottom] = 4;
            break;
	*/
}

void JotMainWindow::on_actionHeading1_activated( )
{
	// Select current block.
	// Sec char format.
// 			case Html_h1:
// 		charFormat.setFontWeight(QFont::Bold);
// 		charFormat.setProperty(QTextFormat::FontSizeAdjustment, int(3));

}

void JotMainWindow::on_actionHeading2_activated( )
{
}

void JotMainWindow::on_actionHeading3_activated( )
{
}

void JotMainWindow::on_actionHeading4_activated( )
{
}

void JotMainWindow::on_actionHeading5_activated( )
{
}

void JotMainWindow::on_actionHeading6_activated( )
{
}

