/*
Copyright 2004 Jonathan Riddell <jr@jriddell.org>

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., 51 Franklin Steet, Fifth Floor, Boston, MA  02110-1301, USA.

*/
#include "gvdirpart.moc"

#include <tqcursor.h>
#include <tqfile.h>
#include <tqsplitter.h>
#include <tqvaluelist.h>

#include <kdebug.h>
#include <kdeversion.h>
#include <kaction.h>
#include <kicontheme.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kmimetype.h>
#include <kstandarddirs.h>
#include <kparts/browserextension.h>
#include <kparts/genericfactory.h>
#include <kio/job.h>

#include <gvcore/fileoperation.h>
#include <gvcore/archive.h>
#include <gvcore/cache.h>
#include <gvcore/document.h>
#include <gvcore/fileviewbase.h>
#include <gvcore/fileviewcontroller.h>
#include <gvcore/printdialog.h>
#include <gvcore/imageview.h>
#include <gvcore/slideshow.h>
#include <gvcore/thumbnailloadjob.h>

#include "config.h"
#include "gvdirpartconfig.h"

namespace Gwenview {

// For now let's duplicate
const char CONFIG_CACHE_GROUP[]="cache";


//Factory Code
typedef KParts::GenericFactory<GVDirPart> GVDirFactory;
K_EXPORT_COMPONENT_FACTORY( libgvdirpart /*library name*/, GVDirFactory )

GVDirPart::GVDirPart(TQWidget* parentWidget, const char* /*widgetName*/, TQObject* parent, const char* name,
		     const TQStringList &) : KParts::ReadOnlyPart( parent, name )  {
	GVDirFactory::instance()->iconLoader()->addAppDir( "gwenview");
	setInstance( GVDirFactory::instance() );
	KGlobal::locale()->insertCatalogue("gwenview");
	KGlobal::locale()->setActiveCatalogue("gwenview");

	mBrowserExtension = new GVDirPartBrowserExtension(this);

	mSplitter = new TQSplitter(Qt::Horizontal, parentWidget, "gwenview-kpart-splitter");
	mSplitter->setFocusPolicy(TQ_ClickFocus);
	mSplitter->setOpaqueResize(true);

	// Create the widgets
	mDocument = new Document(this);
	mFileViewController = new FileViewController(mSplitter, actionCollection());
	int width=GVDirPartConfig::fileViewWidth();
	if (width!=-1) {
		mFileViewController->resize(width, 10);
	}
	mImageView = new ImageView(mSplitter, mDocument, actionCollection());
	mSplitter->setResizeMode(mFileViewController, TQSplitter::KeepSize);

	mSlideShow = new SlideShow(mDocument);

	setWidget(mSplitter);

	KStdAction::saveAs( mDocument, TQT_SLOT(saveAs()), actionCollection(), "saveAs" );
	new KAction(i18n("Rotate &Left"), "rotate_ccw", CTRL + Key_L, this, TQT_SLOT(rotateLeft()), actionCollection(), "rotate_left");
	new KAction(i18n("Rotate &Right"), "rotate_cw", CTRL + Key_R, this, TQT_SLOT(rotateRight()), actionCollection(), "rotate_right");

	connect(mFileViewController, TQT_SIGNAL(requestContextMenu(const TQPoint&, bool)),
		mBrowserExtension, TQT_SLOT(openFileViewContextMenu(const TQPoint&, bool)) );

	connect(mFileViewController, TQT_SIGNAL(urlChanged(const KURL&)),
		mDocument, TQT_SLOT(setURL(const KURL&)) );

	connect(mFileViewController, TQT_SIGNAL(directoryChanged(const KURL&)),
		this, TQT_SLOT(directoryChanged(const KURL&)) );

	connect(mFileViewController, TQT_SIGNAL(selectionChanged()),
		mBrowserExtension, TQT_SLOT(updateActions()) );

	connect(mImageView, TQT_SIGNAL(requestContextMenu(const TQPoint&)),
		mBrowserExtension, TQT_SLOT(openImageViewContextMenu(const TQPoint&)) );

	connect(mSlideShow, TQT_SIGNAL(nextURL(const KURL&)),
		this, TQT_SLOT(slotSlideShowChanged(const KURL&)) );

	connect(mDocument, TQT_SIGNAL(loaded(const KURL&)),
		this, TQT_SLOT(loaded(const KURL&)) );

	// For wheel browsing
	connect(mImageView, TQT_SIGNAL(selectPrevious()),
		mFileViewController, TQT_SLOT(slotSelectPrevious()) );
	connect(mImageView, TQT_SIGNAL(selectNext()),
		mFileViewController, TQT_SLOT(slotSelectNext()) );

	mToggleSlideShow = new KToggleAction(i18n("Slide Show..."), "slideshow", 0, this, TQT_SLOT(toggleSlideShow()), actionCollection(), "slideshow");
	mToggleSlideShow->setCheckedState( i18n("Stop Slide Show" ));

	setXMLFile( "gvdirpart/gvdirpart.rc" );
	mBrowserExtension->updateActions();
}

GVDirPart::~GVDirPart() {
	GVDirPartConfig::setFileViewWidth(mFileViewController->width());
	GVDirPartConfig::writeConfig();
	delete mSlideShow;
}


void GVDirPart::partActivateEvent(KParts::PartActivateEvent* event) {
	if (event->activated()) {
		KConfig* config=new KConfig("gwenviewrc");
		Cache::instance()->readConfig(config,CONFIG_CACHE_GROUP);
		delete config;
	}
}


KAboutData* GVDirPart::createAboutData() {
	KAboutData* aboutData = new KAboutData( "gvdirpart", I18N_NOOP("GVDirPart"),
						"0.1", I18N_NOOP("Image Browser"),
						KAboutData::License_GPL,
						"(c) 2004, Jonathan Riddell <jr@jriddell.org>");
	return aboutData;
}

bool GVDirPart::openFile() {
	//unused because openURL implemented

	//mDocument->setFilename(mFile);
	return true;
}

bool GVDirPart::openURL(const KURL& url) {
	if (!url.isValid()) {
		return false;
	}

	emit started( 0 );
	m_url = url;
	m_url.adjustPath(1);

	emit setWindowCaption( m_url.prettyURL() );
	mFileViewController->setDirURL(m_url);

	return true;
}

void GVDirPart::loaded(const KURL& url) {
	TQString caption = url.filename();
	if( !mDocument->image().isNull())
		caption += TQString(" %1 x %2").arg(mDocument->width()).arg(mDocument->height());
	emit setWindowCaption(caption);
	emit completed();
}

KURL GVDirPart::pixmapURL() {
	return mDocument->url();
}

void GVDirPart::toggleSlideShow() {
	if (mToggleSlideShow->isChecked()) {
        KURL::List list;
        KFileItemListIterator it( *mFileViewController->currentFileView()->items() );
        for ( ; it.current(); ++it ) {
            KFileItem* item=it.current();
            if (!item->isDir() && !Archive::fileItemIsArchive(item)) {
                list.append(item->url());
            }
        }
        if (list.count()==0) {
			mToggleSlideShow->setChecked(false);
            return;
        }
		//FIXME turn on full screen here (anyone know how?)
		mSlideShow->start(list);
	} else {
		//FIXME turn off full screen here
		mSlideShow->stop();
	}
}

void GVDirPart::print() {
	KPrinter printer;
	if ( !mDocument->filename().isEmpty() ) {
		printer.setDocName( m_url.filename() );
		KPrinter::addDialogPage( new PrintDialogPage( mDocument, mImageView, "GV page"));

		if (printer.setup(mImageView, TQString(), true)) {
			mDocument->print(&printer);
		}
	}
}

void GVDirPart::rotateLeft() {
	mDocument->transform(ImageUtils::ROT_270);
}

void GVDirPart::rotateRight() {
	mDocument->transform(ImageUtils::ROT_90);
}

void GVDirPart::directoryChanged(const KURL& dirURL) {
	if( dirURL == m_url ) return;
	emit mBrowserExtension->openURLRequest(dirURL);
}

void GVDirPart::slotSlideShowChanged(const KURL& url) {
	mDocument->setURL( url );
	mFileViewController->setFileNameToSelect( url.filename());
}


/***** GVDirPartBrowserExtension *****/

GVDirPartBrowserExtension::GVDirPartBrowserExtension(GVDirPart* viewPart, const char* name)
	:KParts::BrowserExtension(viewPart, name) {
	mGVDirPart = viewPart;
	emit enableAction("print", true );
}

GVDirPartBrowserExtension::~GVDirPartBrowserExtension() {
}

void GVDirPartBrowserExtension::updateActions() {
	bool somethingSelected = mGVDirPart->fileViewController()->selectionSize() != 0;
	emit enableAction("trash", somethingSelected);
	emit enableAction("del", somethingSelected);
}

void GVDirPartBrowserExtension::del() {
	FileViewController* fv = mGVDirPart->fileViewController();
	FileOperation::realDelete(fv->selectedURLs(), fv);
	
}

void GVDirPartBrowserExtension::trash() {
	FileViewController* fv = mGVDirPart->fileViewController();
	FileOperation::trash(fv->selectedURLs(), fv);
}


void GVDirPartBrowserExtension::openFileViewContextMenu(const TQPoint& pos, bool onItem) {
    if (onItem) {
        const KFileItemList* items = mGVDirPart->fileViewController()->currentFileView()->selectedItems();
        emit popupMenu(pos, *items);
    } else {
        emit popupMenu(pos, mGVDirPart->fileViewController()->dirURL(), 0);
    }
}


void GVDirPartBrowserExtension::openImageViewContextMenu(const TQPoint& pos) {
	KURL url=mGVDirPart->url();
	TQString mimeType=KMimeType::findByURL(url)->name();
	emit popupMenu(pos, url, mimeType);
}


void GVDirPartBrowserExtension::print() {
	mGVDirPart->print();
}

} // namespace
