/****************************************************************************
** Dooble - The Secure Internet Web Browser
**
** Copyright (c) 2008, 2009, 2010 Alexis Megas,
** Gunther van Dooble, and the Dooble Team.
** All rights reserved.
**
** License: GPL2 only:
** 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; version 2 of the License only.
**
** 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
** or see here: http://www.gnu.org/licenses/gpl.html
**
** For the WebKit library, please see: http://webkit.org.
**
** THE CODE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY
** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
** PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
** ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
** INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
** IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
** ARISING IN ANY WAY OUT OF THE USE OF THIS APPLICATION, EVEN IF ADVISED
** OF THE POSSIBILITY OF SUCH DAMAGE.
**
** Please report all praise, requests, bugs, and problems to the project
** team and administrators: http://sf.net/projects/dooble.
**
** You can find us listed at our project page. New team members are welcome.
** The name of the authors should not be used to endorse or promote products
** derived from Dooble without specific prior written permission.
** If you use this code for other projects, please let us know.
**
** Web sites:
**   http://sf.net/projects/dooble
**   http://dooble.sf.net
****************************************************************************/

#include <QDir>
#include <QFile>
#include <QMenu>
#include <QWidget>
#include <QPainter>
#include <QProcess>
#include <QComboBox>
#include <QSettings>
#include <QSizeGrip>
#include <QFileDialog>
#include <QMouseEvent>
#include <QMdiSubWindow>
#include <QDesktopServices>
#ifdef Q_WS_X11
#include <QX11EmbedContainer>
#endif

#include "dooble.h"
#include "ddesktopwidget.h"
#include "ui_applicationPropertiesWindow.h"

ddesktopwidget::ddesktopwidget(QWidget *parent):QMdiArea(parent)
{
  if(parent)
    connect(parent,
	    SIGNAL(updateDesktopBackground(void)),
	    this,
	    SLOT(slotBackgroundImageChanged(void)));

  setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
  setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);

  if(dooble::s_settings.contains("desktopBackground"))
    setBackground(QImage(dooble::s_settings.value("desktopBackground").
			 toString()));
  else
    {
      QDir currentDir(QDir::currentPath());
      QString fileName(QString
		       ("%1/Images/doobledesktop_background_ublue.png").arg
		       (currentDir.path()));
      QSettings settings;

      settings.setValue("desktopBackground", fileName);
      dooble::s_settings["desktopBackground"] = fileName;
      setBackground(QImage(fileName));
    }

  showFileManagerWindow();
  setVisible(false);
}

ddesktopwidget::~ddesktopwidget()
{
}

void ddesktopwidget::mousePressEvent(QMouseEvent *event)
{
  if(event && event->button() == Qt::RightButton)
    {
      QMenu menu(this);

      menu.addAction(tr("&Change Desktop Background"),
		     this, SLOT(slotChangeDesktopBackground(void)));
#ifdef Q_WS_X11
      menu.addSeparator();
      menu.addAction(tr("&Launch Terminal"),
		     this, SLOT(slotLaunchTerminal(void)));
#endif
      menu.exec(QCursor::pos());
    }

  QMdiArea::mousePressEvent(event);
}

void ddesktopwidget::slotChangeDesktopBackground(void)
{
  QFileDialog *fileDialog = 0;

  if(!fileDialogWindow)
    {
      fileDialog = new QFileDialog(this);
      fileDialog->setWindowTitle(tr("Dooble Web Browser: Desktop "
				    "Background Image Selection"));
      fileDialog->setFileMode(QFileDialog::ExistingFile);
      fileDialog->setLabelText(QFileDialog::Accept, tr("&Select"));
      fileDialog->setDirectory(QDir::currentPath());
      fileDialogWindow = new QMdiSubWindow(this);

      QSettings settings(dooble::s_settings.value("iconSet").toString(),
			 QSettings::IniFormat);

      fileDialogWindow->setWindowIcon
	(QIcon(settings.value("windowIcon").toString()));
      fileDialogWindow->setWidget(fileDialog);
      fileDialogWindow->adjustSize();
      fileDialogWindow->setAttribute(Qt::WA_DeleteOnClose);
      connect(fileDialog,
	      SIGNAL(finished(int)),
	      fileDialogWindow,
	      SLOT(deleteLater(void)));
      connect(fileDialogWindow,
	      SIGNAL(destroyed(QObject *)),
	      fileDialog,
	      SLOT(deleteLater(void)));
    }

  /*
  ** Center the file dialog.
  */

  QPoint p(0, 0);

  if(width() >= fileDialogWindow->width())
    p.setX(width() / 2 - fileDialogWindow->width() / 2);
  else
    p.setX(-(fileDialogWindow->width() / 2 - width() / 2));

  if(height() >= fileDialogWindow->height())
    p.setY(height() / 2 - fileDialogWindow->height() / 2);
  else
    p.setY(-(fileDialogWindow->height() / 2 - height() / 2));

  fileDialogWindow->move(p);
  fileDialogWindow->showNormal();

  if(fileDialog)
    if(fileDialog->exec() == QDialog::Accepted)
      {
	QString fileName("");
	QStringList list(fileDialog->selectedFiles());

	/*
	** list.size() is 0 under Mac OS X for Qt 4.6.3. Why?
	** Here's a workaround.
	*/

#ifdef Q_WS_MAC
	if(list.isEmpty())
	  {
	    QString directoryName("");

	    foreach(QWidget *w, fileDialog->findChildren<QWidget *> ())
	      if(qobject_cast<QLineEdit *> (w))
		fileName = qobject_cast<QLineEdit *> (w)->text();
	      else if(qobject_cast<QComboBox *> (w) &&
		      QFileInfo(qobject_cast<QComboBox *> (w)->
				currentText()).exists())
		directoryName = qobject_cast<QComboBox *> (w)->currentText();

	    fileName = directoryName + QDir::separator() + fileName;
	  }
	else
	  fileName = list[0];
#else
	if(!list.isEmpty())
	  fileName = list[0];
#endif

	if(!fileName.isEmpty())
	  {
	    QSettings settings;

	    settings.setValue("desktopBackground", fileName);
	    dooble::s_settings["desktopBackground"] = fileName;
	    setBackground(QImage(fileName));
	    list.clear();
	    setVisible(false);
	    setVisible(true);
	    emit backgroundImageChanged();
	  }
      }
}

void ddesktopwidget::slotBackgroundImageChanged(void)
{
  if(dooble::s_settings.contains("desktopBackground"))
    {
      setBackground(QImage(dooble::s_settings.value
			   ("desktopBackground").toString()));
      setVisible(false);
      setVisible(true);
    }
}

void ddesktopwidget::slotAddApplicationIcon(void)
{
  QDialog *dialog = new QDialog(this);
  QMdiSubWindow *launchApplicationWindow = new QMdiSubWindow(this);
  Ui_applicationPropertiesWindow propertiesUI;

  propertiesUI.setupUi(dialog);
  dialog->setSizeGripEnabled(true);
  launchApplicationWindow->setWidget(dialog);
  launchApplicationWindow->adjustSize();
  launchApplicationWindow->setAttribute(Qt::WA_DeleteOnClose);
  connect(dialog,
	  SIGNAL(finished(int)),
	  launchApplicationWindow,
	  SLOT(deleteLater(void)));
  connect(launchApplicationWindow,
	  SIGNAL(destroyed(QObject *)),
	  dialog,
	  SLOT(deleteLater(void)));

  QPoint p(0, 0);

  if(width() >= launchApplicationWindow->width())
    p.setX(width() / 2 - launchApplicationWindow->width() / 2);
  else
    p.setX(launchApplicationWindow->width() / 2 - width() / 2);

  if(height() >= launchApplicationWindow->height())
    p.setY(height() / 2 - launchApplicationWindow->height() / 2);
  else
    p.setY(launchApplicationWindow->height() / 2 - height() / 2);

  launchApplicationWindow->move(p);
  launchApplicationWindow->showNormal();
}

void ddesktopwidget::slotOK(void)
{
}

void ddesktopwidget::showFileManagerWindow(const QUrl &url)
{
  QSettings settings(dooble::s_settings.value("iconSet").toString(),
		     QSettings::IniFormat);
  QMdiSubWindow *fileManagerWindow = new QMdiSubWindow(this);

  Q_UNUSED(new QSizeGrip(fileManagerWindow));
  fileManagerWindow->setWindowTitle
    (tr("Dooble Web Browser: File Manager"));
  fileManagerWindow->setWindowIcon
    (QIcon(settings.value("windowIcon").toString()));

  dfilemanager *fileManager = new dfilemanager(fileManagerWindow);

  connect(fileManagerWindow,
	  SIGNAL(destroyed(QObject *)),
	  fileManager,
	  SLOT(deleteLater(void)));
  fileManagerWindow->setWidget(fileManager);
  fileManagerWindow->setAttribute(Qt::WA_DeleteOnClose);
  fileManagerWindow->adjustSize();

  if(url.isEmpty())
    {
      QString path("");

      if(dooble::s_settings.contains("settingsWindow/myRetrievedFiles"))
	path = dooble::s_settings.value
	  ("settingsWindow/myRetrievedFiles").toString();
      else
	{
	  path = QDesktopServices::storageLocation
	    (QDesktopServices::DesktopLocation);

	  if(path.isEmpty() || !QFile::exists(path) ||
	     !QFileInfo(path).isReadable())
	    path = QDir::homePath();
	}

      qobject_cast<dfilemanager *> (fileManagerWindow->widget())->load
	(QUrl::fromLocalFile(path));
    }
  else
    qobject_cast<dfilemanager *> (fileManagerWindow->widget())->load(url);

  fileManagerWindow->showNormal();
}

#ifdef Q_WS_X11
void ddesktopwidget::slotLaunchTerminal(void)
{
  QSettings settings(dooble::s_settings.value("iconSet").toString(),
		     QSettings::IniFormat);
  QMdiSubWindow *terminalWindow = new QMdiSubWindow(this);
  QX11EmbedWidget *container = new QX11EmbedWidget(this);

  connect(terminalWindow,
	  SIGNAL(destroyed(QObject *)),
	  container,
	  SLOT(deleteLater(void)));
  terminalWindow->setWindowTitle
    (tr("Dooble Web Browser: Terminal"));
  terminalWindow->setWindowIcon
    (QIcon(settings.value("windowIcon").toString()));
  terminalWindow->setWidget(container);
  terminalWindow->setAttribute(Qt::WA_DeleteOnClose);
  terminalWindow->setWindowFlags
    ((terminalWindow->windowFlags() | Qt::CustomizeWindowHint) &
     ~Qt::WindowMaximizeButtonHint);
  container->show();

  QProcess *process = new QProcess(container);

  connect(process,
	  SIGNAL(error(QProcess::ProcessError)),
	  terminalWindow,
	  SLOT(deleteLater(void)));
  connect(process,
	  SIGNAL(finished(int, QProcess::ExitStatus)),
	  terminalWindow,
	  SLOT(deleteLater(void)));

  QStringList arguments;

  arguments << "-sb";
  arguments << "-into" << QString::number(container->winId());
  process->start("xterm", arguments);
  arguments.clear();
  connect(terminalWindow,
	  SIGNAL(destroyed(QObject *)),
	  process,
	  SLOT(kill(void)));
  connect(terminalWindow,
	  SIGNAL(destroyed(QObject *)),
	  process,
	  SLOT(deleteLater(void)));
  terminalWindow->resize(675, 450);
}
#else
void ddesktopwidget::slotLaunchTerminal(void)
{
}
#endif

void ddesktopwidget::enterEvent(QEvent *event)
{
  QMdiArea::enterEvent(event);
  emit viewEntered();
}
