/*********************************************************************************
* C++ Implementation: kbearclassicmainwindow.cpp
* Description:
*
* Begin : mån mar 24 2003
* Author : Björn Sahlström <kbjorn@users.sourceforge.net> (C) 2003
* Copyright : See COPYING file that comes with this distribution
**********************************************************************************/

//////////////////////////////////////////////////////////////////////
// Qt specific include files
#include <qsplitter.h>
#include <qlayout.h>
#include <qpopupmenu.h>
#include <qdir.h>
#include <qwhatsthis.h>
#include <qtooltip.h>
#include <qtimer.h>
#include <qmap.h>
//////////////////////////////////////////////////////////////////////
// KDE specific include files
#include <kiconloader.h>
#include <klocale.h>
#include <kurl.h>
#include <kfileitem.h>
#include <kurldrag.h>
#include <kapplication.h>
#include <kconfig.h>
#include <kconfigbase.h>
#include <kglobal.h>
#include <kpushbutton.h>
#include <kdebug.h>
#include <dcopclient.h>
//////////////////////////////////////////////////////////////////////
// System specific include files
//////////////////////////////////////////////////////////////////////
// Application specific include files
#include "kbearclassicmainwindow.h"
#include "kbearpartmanager.h"
#include "transfermanager.h"
#include "kbearfilesyspartiface.h"
#include "kbearchildview.h"
#include "resource.h"


#include "kbearclassicmainwindow.moc"

using namespace KBear;
//-----------------------------------------------
KBearClassicMainWindow::KBearClassicMainWindow()
	:	KParts::DockMainWindow( 0L, "KBear",WDestructiveClose | WStyle_ContextHelp ),
		m_isClosing( false ),
		m_shared( new KBearMainWindowShared( this ) ),
		m_viewLocalCaption( i18n("Your Local File System" ) )
{
	setInstance( KGlobal::instance() );
	setCaption( VERSION );
	setupGUI();
	m_shared->createOutputToolbar( m_mainDockBase );
	setAutoSaveSettings( "MainWindow" );
	setXMLFile("kbearui.rc");
	setStandardToolBarMenuEnabled( true );
	actionCollection()->setHighlightingEnabled( true );
	// Important !!!!! we need to call createGUI before creating the outputtoolbar
	createGUI( 0L );
}
//-----------------------------------------------
KBearClassicMainWindow::~KBearClassicMainWindow() {
	delete m_shared;
}
//-----------------------------------------------
void KBearClassicMainWindow::initViewLocal() {
	KURL u( QDir::homeDirPath() );
	SiteInfo c( u );
	c.setProtocol( "file" );
	c.setLabel( m_viewLocalCaption );

	QString whatsThis = i18n("This Window displays your local file system.\n"
												"You can use this to transfer files and folders to or "
												"from a remote host by drag and drop.");

	m_viewLocal = new KBearChildView( m_leftView, c );
	connect( m_viewLocal, SIGNAL( selectionChanged() ), this, SLOT( slotSelectionChanged() ) );
	m_viewLocal->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding, 0, 0, m_viewLocal->sizePolicy().hasHeightForWidth() ) );
	QWhatsThis::add( m_viewLocal, whatsThis );
	m_leftView->addTab( m_viewLocal, m_viewLocalCaption );
//	m_viewLocal->show();
	m_leftView->showPage( m_viewLocal );
	static_cast<KToggleAction*>(actionCollection()->action("show_local"))->setChecked( true );
}
//-----------------------------------------------
const KBearChildViewIface* KBearClassicMainWindow::getCurrentView() {
	KBearChildViewIface* view = dynamic_cast<KBearChildViewIface*>( m_rightView->currentPage() );
	return view;
}
//-----------------------------------------------
const KBearChildViewIface* KBearClassicMainWindow::getLocalView() {
	return m_viewLocal;
}
//-----------------------------------------------
DCOPRef KBearClassicMainWindow::currentChildView() {
	DCOPRef res;
	KBearChildView* view = dynamic_cast<KBearChildView*>( m_rightView->currentPage() );
	if( ! view )
		return res;

	return DCOPRef( kapp->dcopClient()->appId(), view->objId() );
}
//-----------------------------------------------
void KBearClassicMainWindow::setupGUI() {
	m_splitter = new QSplitter(this, "MainSplitter" );
	m_splitter->setOpaqueResize( true );
	m_splitter->setSizePolicy( QSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding));

	m_leftView = new KDockTabGroup( m_splitter, "LeftView" );
	m_buttonWidget = new QWidget( m_splitter, "ButtonWidget" );
	QGridLayout* buttonWidgetLayout = new QGridLayout( m_buttonWidget, 1, 1, 0, -1, "dirSynchWidgetLayout");

	buttonWidgetLayout->addItem( new QSpacerItem( 0, 10, QSizePolicy::Minimum, QSizePolicy::Expanding), 0, 0 );

	m_toRemoteButton = new KPushButton(m_buttonWidget, "m_toRemoteButton" );
	m_toRemoteButton->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed, 0, 0, m_toRemoteButton->sizePolicy().hasHeightForWidth() ) );
	m_toRemoteButton->setPixmap( BarIcon("forward") );
	m_toRemoteButton->setEnabled( false );
	QString tmp = i18n( "Push this button if you want to copy/move selected items to the remote filesystem." );
	QToolTip::add( m_toRemoteButton, tmp );
	QWhatsThis::add( m_toRemoteButton, tmp );

	buttonWidgetLayout->addWidget( m_toRemoteButton, 1, 0 );
	buttonWidgetLayout->addItem( new QSpacerItem( 0, 2, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding), 2, 0 );

	m_toLocalButton = new KPushButton(m_buttonWidget, "m_toLocalButton" );
	m_toLocalButton->setSizePolicy( QSizePolicy( QSizePolicy::Minimum, QSizePolicy::Fixed, 0, 0, m_toLocalButton->sizePolicy().hasHeightForWidth() ) );
	m_toLocalButton->setPixmap( BarIcon("back") );
	m_toLocalButton->setEnabled( false );
	tmp = i18n( "Push this button if you want to copy/move selected items to the local filesystem." );
	QToolTip::add( m_toLocalButton, tmp );
	QWhatsThis::add( m_toLocalButton, tmp );

	buttonWidgetLayout->addWidget( m_toLocalButton, 3, 0 );

	buttonWidgetLayout->addItem( new QSpacerItem( 0, 10, QSizePolicy::Minimum, QSizePolicy::Expanding), 4, 0 );

	m_rightView = new KDockTabGroup( m_buttonWidget, "RightView" );
	m_rightView->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding, 0, 0, m_rightView->sizePolicy().hasHeightForWidth() ) );
	buttonWidgetLayout->addMultiCellWidget( m_rightView, 0, 4, 1, 1 );

	buttonWidgetLayout->activate();

	m_mainDockBase = createDockWidget( "MainDockBase", QPixmap(), this );
	m_mainDockBase->setWidget( m_splitter );
	m_mainDockBase->setDockSite( KDockWidget::DockCorner );
	m_mainDockBase->setEnableDocking( KDockWidget::DockNone );
	setView( m_mainDockBase ); // central widget in a KDE mainwindow
	setMainDockWidget( m_mainDockBase );

	KParts::DockMainWindow::statusBar()->show();

	connect( m_toRemoteButton, SIGNAL( clicked() ), this, SLOT( slotTransferButtonClicked() ) );
	connect( m_toLocalButton, SIGNAL( clicked() ), this, SLOT( slotTransferButtonClicked() ) );
}
//-----------------------------------------------
void KBearClassicMainWindow::slotTransferButtonClicked() {
	QObject* obj = (QObject*)sender();
	KBearChildViewIface* sourceView = 0L;
	KBearChildViewIface* destView = 0L;
	if( obj == m_toRemoteButton ) {
		sourceView = m_viewLocal;
		destView = (KBearChildViewIface*)getCurrentView();
	}
	else {
		destView = m_viewLocal;
		sourceView = (KBearChildViewIface*)getCurrentView();
	}
	if( sourceView && destView ) {
		KURL::List urls;
		QMap<QString, QString> metaData;
		KFileItemListIterator it( * sourceView->selectedItems() );
		for ( ; it.current(); ++it ){
			urls.append( (*it)->url() );
			metaData.insert( (*it)->url().url(), (*it)->mimetype() );
		}

		metaData.insert( "SourceID", QString::number( sourceView->siteInfo().ID() ) );
		metaData.insert("DestID", QString::number( destView->siteInfo().ID() ) );
		metaData.insert("DestURL", destView->currentURL() );
		metaData.insert("Action", "copy" );
		KURLDrag* dragObject = KURLDrag::newDrag( urls, metaData, static_cast<KBearChildView*>(sourceView) );

		TransferManager::getInstance()->addTransfers( dragObject );
	}
}
//-----------------------------------------------
void KBearClassicMainWindow::slotSelectionChanged() {
	KBearChildView* view = (KBearChildView*)sender();
	if( ! view || ! view->part() )
		return;
	if( view == m_viewLocal ) {
		m_toRemoteButton->setEnabled( ! view->part()->selectedURLs().empty() );
	}
	else if( view == m_rightView->currentPage() ){
		m_toLocalButton->setEnabled( ! view->part()->selectedURLs().empty() );
	}
}
//-----------------------------------------------
void KBearClassicMainWindow::init() {
	m_shared->init();
	API::getInstance()->partManager()->setAllowNestedParts( true );

	connect( API::getInstance()->partManager(), SIGNAL( activePartChanged( KParts::Part* ) ), this, SLOT( createGUI( KParts::Part* ) ) );
	connect( API::getInstance()->core(), SIGNAL( newToolbarConfig() ), this, SLOT( fillWindowMenu() ) );

	initViewLocal();

	readProperties( kapp->config() );
	KParts::DockMainWindow::statusBar()->message(i18n( "Ready." ));
	kapp->processEvents();

}
//-----------------------------------------------
void KBearClassicMainWindow::readProperties( KConfig* config ) {
	m_shared->readProperties( config );
	QString group = config->group();
	KConfigGroupSaver cs( config, group.isEmpty() ? "General": group   );

	config->setGroup( "General" );
	readViewSettings();

	readDockConfig(config, "ClassicDockState");

}
//-----------------------------------------------
void KBearClassicMainWindow::saveProperties( KConfig* config ) {
	QString group = config->group();
	KConfigGroupSaver cs( config, group.isEmpty() ? "General": group   );

	m_shared->saveProperties( config );
	writeDockConfig(config, "ClassicDockState");
	m_viewLocal->saveProperties( config, "View Settings" );

	config->sync();
}
//-----------------------------------------------
void KBearClassicMainWindow::slotCloseChildView() {
	QWidget* view = (QWidget*)QObject::sender();
	m_rightView->removePage( view );
	delete view;
}
//-----------------------------------------------
KBearChildViewIface* KBearClassicMainWindow::createClient( const SiteInfo& info, const QString& whatsThis ) {
	KBearChildView* w = new KBearChildView( m_rightView, info );
	connect( w, SIGNAL( selectionChanged() ), this, SLOT( slotSelectionChanged() ) );
	connect( w, SIGNAL( closeMe() ), this, SLOT( slotCloseChildView() ) );
	QWhatsThis::add( w, whatsThis );
	m_rightView->addTab( w, info.label() );
	m_rightView->showPage( w );

	return w;
}
//-----------------------------------------------
void KBearClassicMainWindow::setLocalPath( const QString& path ) {
	m_viewLocal->setPath( path );
}
//-----------------------------------------------
void KBearClassicMainWindow::readViewSettings() {
	KConfigGroupSaver cs( kapp->config(), kapp->config()->group() );
	m_viewLocal->readProperties( kapp->config(), "View Settings" );
	for( int i = 0; m_rightView->count(); i++ ) {
		KBearChildView* childView = static_cast<KBearChildView*>( m_rightView->page( i ) );
		childView->readProperties( kapp->config(), "View Settings" );
	}

}
//-----------------------------------------------
bool KBearClassicMainWindow::queryClose() {
	kdDebug()<<"KBearClassicMainWindow::queryClose()"<<endl;

	if( m_isClosing )
		return true;
	
	QTimer::singleShot( 0, API::getInstance()->core(), SLOT( requestShutDown() ) );
	return false;
}
//-----------------------------------------------
void KBearClassicMainWindow::realClose() {
	kdDebug()<<"KBearClassicMainWindow::realClose()"<<endl;

	// if user want to save ' run time settings'
	KConfigGroupSaver cs( kapp->config(), kapp->config()->group() );
	kapp->config()->setGroup( "General" );
	kapp->config()->writeEntry( "First Run", false );
	if( kapp->config()->readBoolEntry( "Run Time Settings", true) )
		saveProperties( kapp->config() );

	kapp->config()->sync();

	closeAll();
	m_leftView->removePage( m_viewLocal );
	delete m_viewLocal;

	m_isClosing = true;
	QTimer::singleShot( 100, this , SLOT( slotClose() ) );
}
//-----------------------------------------------
void KBearClassicMainWindow::slotClose() {
	close();
}
//-----------------------------------------------
void KBearClassicMainWindow::raiseMainWindow() {
	raise();
}
//-----------------------------------------------
void KBearClassicMainWindow::embedOutputPluginView( QWidget* view, const QString& name, const QString& toolTip ) {
	m_shared->embedOutputPluginView( view, name, toolTip );
}
//-----------------------------------------------
void KBearClassicMainWindow::removeOutputPluginView( QWidget* view ) {
	m_shared->removeOutputPluginView( view );
}
//-----------------------------------------------
void KBearClassicMainWindow::raiseView(QWidget* /*view*/ ) {
	// More to come ?
}
//-----------------------------------------------
KParts::DockMainWindow* KBearClassicMainWindow::mainWindow() {
	return this;
}
//-----------------------------------------------
void KBearClassicMainWindow::createGUI( KParts::Part* part ) {
	KParts::DockMainWindow::createGUI( part );
	if( ! m_pWindowMenu ) {
		m_pWindowMenu = static_cast<QPopupMenu*>(guiFactory()->container("window", this));
	  	connect( m_pWindowMenu, SIGNAL(aboutToShow()), this, SLOT(fillWindowMenu()) );
	}
}
//-----------------------------------------------
void KBearClassicMainWindow::showViewLocal(){
	if( m_viewLocal == 0L )
		return;

	KToggleAction* action = static_cast<KToggleAction*>(actionCollection()->action("show_local"));
	QPtrListIterator<KParts::Part> it( * API::getInstance()->partManager()->parts() );
	bool partRegistered = false;
	for( ; it.current(); ++it ) {
		if( m_viewLocal->part() == it.current() ) {
			partRegistered = true;
			break;
		}
	}

	if( action->isChecked() ) {
		if( ! partRegistered )
			API::getInstance()->partManager()->addPart( m_viewLocal->part() );
		m_leftView->show();
	}
	else if( ! action->isChecked() ) {
		m_viewLocal->hide();
		if( partRegistered )
			API::getInstance()->partManager()->removePart( m_viewLocal->part() );
		m_leftView->hide();
	}
}
//-----------------------------------------------
void KBearClassicMainWindow::fillWindowMenu() {
	static QString windowListStr = QString::fromLatin1("window_list_");

	m_pWindowMenu = static_cast<QPopupMenu*>(guiFactory()->container("window", this));

	action("window_close")->setEnabled( m_rightView->count() > 0 );
	action("window_close_all")->setEnabled( m_rightView->count() > 0 );

	// for all child frame windows: give an ID to every window and connect them in the end with windowMenuItemActivated()
	unplugActionList( "window_list" );

	m_windowListActions.clear();

	QWidget* pView = 0L;

	for( int i = 0; i < m_rightView->count(); i++ ) {
		pView = m_rightView->page( i );

		QString 	item = QString::fromLatin1(" ") + m_rightView->label( i );

		// insert the window entry sorted in alphabetical order
		unsigned int indx;
		unsigned int windowItemCount = m_windowListActions.count();
		bool inserted = false;
		QString tmpString = windowListStr + item;
		KRadioAction* radioAction = new KRadioAction( item, 0, this, SLOT(slotClickedInWindowMenu()), this, tmpString.latin1() );
		radioAction->setChecked( pView == m_rightView->currentPage() );

		for( indx = 0; indx < windowItemCount; indx++) {
			tmpString = m_windowListActions.at( indx )->text();
			if( tmpString.right( tmpString.length()-2) > item.right( item.length()-2)) {
				m_windowListActions.insert( indx, radioAction );
				inserted = true;
				indx = windowItemCount+1;  // break the loop
			}
		}
		if( ! inserted ) {  // append it
			m_windowListActions.append( radioAction );
		}
	}

	plugActionList("window_list", m_windowListActions );
}
//-----------------------------------------------
void KBearClassicMainWindow::slotClickedInWindowMenu() {
	static QString windowListStr = QString::fromLatin1("window_list_");
	QObject* object = (QObject*)sender();
	for( int i = 0; i < m_rightView->count(); i++ ) {
		if( object->name() == windowListStr + QString::fromLatin1(" ") + m_rightView->label( i ) ) {
			m_rightView->setCurrentPage( i );
			return;
		}
	}
}
//-----------------------------------------------
void KBearClassicMainWindow::applyUISettings() {
	readViewSettings();
}
//-----------------------------------------------
void KBearClassicMainWindow::closeCurrentView() {
	QWidget* w = m_rightView->currentPage();
	if( ! w )
		return;
	m_rightView->removePage( w );
	delete w;
}
//-----------------------------------------------
void KBearClassicMainWindow::closeAll() {
	QWidget* w = 0L;
	while( m_rightView->count() ) {
		w = m_rightView->page( 0 );
		if( w ) {
			m_rightView->removePage( w );
			delete w;
		}
	}

}
//-----------------------------------------------
QPtrList<KBearChildViewIface> KBearClassicMainWindow::childViews() {
	QPtrList<KBearChildViewIface> childViews;
	childViews.append( m_viewLocal );

	for( int i = 0; m_rightView->count(); i++ ) {
		childViews.append( dynamic_cast<KBearChildView*>( m_rightView->page( i ) ) );
	}
	return childViews;
}
//-----------------------------------------------
