#include <qtimer.h>
#include <qdragobject.h>
#include <qregexp.h>

#include <kiconloader.h>
#include <kstddirs.h>
#include <kapp.h>
#include <kaction.h>
#include <klocale.h>
#include <kfiledialog.h>
#include <kmessagebox.h>
#include <klibloader.h>
#include <kstdaction.h>
#include <khelpmenu.h>
#include <kedittoolbar.h>

#include "kviewpart.h"
#include "kviewshell.moc"


//TODO -- use the statusbar
//TODO -- don't stay open when no file, go directly to KFileDialog


KViewShell::KViewShell(QString partname, KAboutData *about)
  : KParts::MainWindow(), _partname(partname)
{
  // create the viewer part

  // Try to load
  KLibFactory *factory = KLibLoader::self()->factory("libkviewpart");
  if (factory)
  {
    QStringList args;
    args << _partname;
    view = (KViewPart*) factory->create(this, "kviewpart", "KViewPart", args);
  }
  else
    {
      KMessageBox::error(this, "No libkviewpart found !");
      exit(-1);
    }

  setView(view->widget());


  // file menu
  KStdAction::open(this, SLOT(slotFileOpen()), actionCollection());
  recent = KStdAction::openRecent (this, SLOT(openURL(const KURL &)), actionCollection());
  closeAction = KStdAction::close(this, SLOT(slotFileClose()), actionCollection());
  KStdAction::quit (this, SLOT(slotQuit()), actionCollection());

  // settings menu
  showtoolbar = KStdAction::showToolbar(this, SLOT(slotShowToolBar()), actionCollection());
  showstatusbar = KStdAction::showStatusbar(this, SLOT(slotShowStatusBar()), actionCollection());

  m_helpMenu = new KHelpMenu( this, about, true, actionCollection() );

  setXMLFile( locate( "config", "ui/ui_standards.rc" ) );
  setXMLFile( "kviewshell.rc", true );

  createGUI(view);

  readSettings();

  resize (600,300);

  checkActions();

  setAcceptDrops(true);
}


void KViewShell::checkActions()
{
  bool doc = !view->url().isEmpty();

  closeAction->setEnabled(doc);
}


KViewShell::~KViewShell()
{
  writeSettings();
  delete view;
}


void KViewShell::slotQuit()
{
  kapp->closeAllWindows();
  kapp->quit();
}


void KViewShell::readSettings()
{
  KConfig *config = kapp->config();

  config->setGroup("General");

  showtoolbar->setChecked(config->readBoolEntry("ShowToolBar", true));
  slotShowToolBar();

  showstatusbar->setChecked (config->readBoolEntry ("ShowStatusBar", true));
  slotShowStatusBar();

  recent->loadEntries(config, QString("%1-RecentFiles").arg(_partname));
}


void KViewShell::writeSettings()
{
  KConfig *config = kapp->config();

  config->setGroup( "General" );

  config->writeEntry ("ShowToolBar", showtoolbar->isChecked());
  config->writeEntry ("ShowStatusBar", showstatusbar->isChecked());

  recent->saveEntries(config, QString("%1-RecentFiles").arg(_partname));

  config->sync();
}


void KViewShell::openURL(const KURL &url)
{
  if (view->openURL(url))
    {
      recent->addURL(url);
      checkActions();
    }
}


void KViewShell::slotFileOpen()
{
  KURL url = KFileDialog::getOpenURL(QString::null, view->fileFormats().join("\n"));

  if (!url.isEmpty())
    openURL(url);
}


void KViewShell::slotFileClose()
{
  view->closeURL();

  checkActions();
}


void KViewShell::slotShowStatusBar()
{
  if (showstatusbar->isChecked())
    statusBar()->show();
  else
    statusBar()->hide();
}


void KViewShell::slotShowToolBar()
{
  if (showtoolbar->isChecked())
    toolBar()->show();
  else
    toolBar()->hide();
}


void KViewShell::slotEditToolbar()
{
  KEditToolbar dlg(actionCollection());
  if (dlg.exec())
    createGUI(view);
}


void KViewShell::dragEnterEvent(QDragEnterEvent *event)
{
  if (QUriDrag::canDecode(event))
    {
      QStringList urls;
      QUriDrag::decodeToUnicodeUris(event, urls);
      if (urls.count() > 0)
	{
	  // look if the extension is right
	  QStringList list = view->fileFormats();
	  QStringList::Iterator it;
	  for (it = list.begin(); it != list.end(); ++it)
	    {
	      QString ext = *it;
	      int pos = ext.find('|');
	      if (pos >= 0)
		ext = ext.left(pos);

	      QRegExp re(ext, false, true);
	      if (re.match(urls[0]) >= 0)
		{
		  event->accept(true);
		  return;
		}
	    }

	}
    }
  
  event->accept(false);
}


void KViewShell::dropEvent(QDropEvent *event)
{
  if (QUriDrag::canDecode(event))
    {
      QStringList urls;
      QUriDrag::decodeToUnicodeUris(event, urls);
      if (urls.count() > 0)
	openURL(KURL(urls[0]));
    }
}


