/***************************************************************************
                          kbearsitemanagertreeview.cpp  -  description
                             -------------------
    begin                : fre mar 15 2002
    copyright            : (C) 2003 by Björn Sahlström
    email                : kbjorn@users.sourceforge.net
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

//////////////////////////////////////////////////////////////////////
// Qt specific include files
#include <qdragobject.h>
//////////////////////////////////////////////////////////////////////
// KDE specific include files
#include <kiconloader.h>
#include <kmimetype.h>
#include <klocale.h>
#include <kdebug.h>
//////////////////////////////////////////////////////////////////////
// Application specific include files
#include "kbearsitemanagertreeview.h"
#include "kbearsitemanager.h"

#ifndef AUTO_OPEN_TIME
#define AUTO_OPEN_TIME
	static int autoOpenTime = 750;
#endif
// ------------------------- class KBearSiteManagerTreeViewItem --------------------------
QPixmap* KBearSiteManagerTreeViewItem::m_folderOpen = 0L;
QPixmap* KBearSiteManagerTreeViewItem::m_folderClosed = 0L;
//-----------------------------------------------
KBearSiteManagerTreeViewItem::KBearSiteManagerTreeViewItem( QListView* parent, const QString& text )
	:	QListViewItem(parent,text)
{
	setExpandable( true );
	if( m_folderOpen == 0L )
		m_folderOpen = new QPixmap(KGlobal::iconLoader()->loadIcon("folder_open", KIcon::Small ));
	if( m_folderClosed == 0L )
		m_folderClosed = new QPixmap(KMimeType::mimeType("inode/directory")->pixmap(KIcon::Small) );
}
//-----------------------------------------------
KBearSiteManagerTreeViewItem::KBearSiteManagerTreeViewItem( QListViewItem* parent, const QString& text )
	:	QListViewItem(parent,text)
{
	setExpandable( true );
	if( m_folderOpen == 0L )
		m_folderOpen = new QPixmap(KGlobal::iconLoader()->loadIcon("folder_open", KIcon::Small ));
	if( m_folderClosed == 0L )
		m_folderClosed = new QPixmap(KMimeType::mimeType("inode/directory")->pixmap(KIcon::Small) );
}
//-----------------------------------------------
KBearSiteManagerTreeViewItem::~KBearSiteManagerTreeViewItem(){
}
//-----------------------------------------------
void KBearSiteManagerTreeViewItem::setOpen( bool o ) {
	if ( ! isExpandable() ) {
		return;
	}
	else if( o ) {
		setPixmap( *m_folderOpen );
	}
	else {
		setPixmap( *m_folderClosed );
	}
	QListViewItem::setOpen( o );
}
//-----------------------------------------------
void KBearSiteManagerTreeViewItem::setPixmap( const QPixmap& p ) {
	m_pixmap = p;
	QListViewItem::setPixmap( 0, p );
	setup();
	widthChanged( 0 );
	invalidateHeight();
	repaint();
}

// ------------------------- class KBearSiteManagerTreeView --------------------------
KBearSiteManagerTreeView::KBearSiteManagerTreeView(QWidget *parent, const char *name )
	:	KListView(parent,name), m_dropItem( 0L ),	
		m_currentBeforeDropItem( 0L ), m_autoOpenTimer(this)
{
	setItemsRenameable( false );
	setupGUI();
}
//-----------------------------------------------
KBearSiteManagerTreeView::~KBearSiteManagerTreeView(){
}
//-----------------------------------------------
void KBearSiteManagerTreeView::setupGUI()
{
	addColumn( i18n("Name") );
	setTooltipColumn( 0 );
	setRootIsDecorated( true );
	setShowSortIndicator( true );
	setFullWidth( false );
	setSelectionModeExt( KListView::Single );
	setDNDEnabled();
	setFocusPolicy( QWidget::WheelFocus );
	connect( &m_autoOpenTimer, SIGNAL( timeout() ), this, SLOT( slotOpenFolder() ) );
	connect( this, SIGNAL( executed( QListViewItem* ) ), this, SLOT( slotExecuted( QListViewItem*) ) );
}
//-----------------------------------------------
bool KBearSiteManagerTreeView::acceptDrag(QDropEvent* e ) const {
	return e->source() == viewport();
}
//-----------------------------------------------
void KBearSiteManagerTreeView::startDrag() {
	kdDebug()<<"KBearSiteManagerTreeView::startDrag()"<<endl;
	if(! selectedItem() )
		return;

//	KBearSiteManager* manager = static_cast<KBearSiteManager*>( parentWidget() );
// 	manager->checkModified();
	QPoint hotspot;
	QPixmap pixmap = * selectedItem()->pixmap(0);
	hotspot.setX( pixmap.width() / 2 );
	hotspot.setY( pixmap.height() / 2 );
	QString parent = getFullPath( selectedItem()->parent() );
	QString name = currentItem()->text( 0 );
	QStoredDrag* dragObject = new QStoredDrag( "application/x-qlistviewitem", viewport() );
	QByteArray data;
	QDataStream arg( data, IO_WriteOnly );
	arg << parent << name;
	dragObject->setEncodedData( data );
	dragObject->setPixmap( pixmap, hotspot );
	dragObject->drag();   // start the drag;
}
//-----------------------------------------------
void KBearSiteManagerTreeView::contentsDropEvent( QDropEvent* e ) {
	kdDebug()<<"KBearSiteManagerTreeView::contentsDropEvent()"<<endl;
	m_autoOpenTimer.stop();  // stop timer
	if( ! acceptDrag( e ) )
		return;

	QListViewItem* newParentItem = 0L;
	if( selectedItem() ) {
		if( selectedItem()->isExpandable() )
			 newParentItem = selectedItem();
		else
			newParentItem = selectedItem()->parent();
	}
	QString parent;
	QString name;
	QDataStream arg( e->encodedData("application/x-qlistviewitem"), IO_ReadOnly );
	arg >> parent;
	arg >> name;

	QListViewItem* parentItem = findParentByFullName( parent );
	QListViewItem* item = findItemByName( parentItem, name );
	if( item )
		emit moved( parent, name, newParentItem, item->isExpandable() );

	m_dropItem = 0; // reset
}
//-----------------------------------------------
void KBearSiteManagerTreeView::contentsDragEnterEvent( QDragEnterEvent *e ) {
	kdDebug()<<"KBearSiteManagerTreeView::contentsDragEnterEvent()"<<endl;
	if ( ! acceptDrag( e ) ) {
		e->ignore();
		return;
	}
	e->acceptAction();
	m_currentBeforeDropItem = selectedItem();
	QListViewItem* item = itemAt( contentsToViewport( e->pos() ) );
	if( item ) {
		m_dropItem = item; // set m_dropItem
		m_autoOpenTimer.start( autoOpenTime );  // start timer
	}
	else {
		m_dropItem = 0L;
	}
//	KListView::contentsDragEnterEvent( e );
}
//-----------------------------------------------
void KBearSiteManagerTreeView::contentsDragMoveEvent( QDragMoveEvent *e ) {
	kdDebug()<<"KBearSiteManagerTreeView::contentsDragMoveEvent()"<<endl;
	if ( ! acceptDrag( e ) ) {
		e->ignore();
		return;
	}
	e->acceptAction();
	QListViewItem* item = itemAt( contentsToViewport(  e->pos() ) );
	if ( item ) {
		setSelected( item, true );
		if( item != m_dropItem ) { // if this item isn't the same as m_dropItem
			m_autoOpenTimer.stop(); // stop timer
			m_dropItem = item; // set m_dropItem
			m_autoOpenTimer.start( autoOpenTime ); // start timer
		}
	}
	else {
		if( selectedItem() )
			setSelected( selectedItem(), false );
		m_autoOpenTimer.stop();
		m_dropItem = 0L;
	}
//	KListView::contentsDragMoveEvent( e );
}
//-----------------------------------------------
void KBearSiteManagerTreeView::contentsDragLeaveEvent( QDragLeaveEvent* ) {
	kdDebug()<<"KBearSiteManagerTreeView::contentsDragLeaveEvent()"<<endl;
	if( m_currentBeforeDropItem ) {
		setSelected( m_currentBeforeDropItem, true );
		ensureItemVisible( m_currentBeforeDropItem );
	}
	else
		setSelected( m_dropItem, false ); // no item selected

	m_autoOpenTimer.stop();  // stop timer
	m_dropItem = 0L;  // reset m_dropItem
//	KListView::contentsDragLeaveEvent( e );
}
//-----------------------------------------------
QString KBearSiteManagerTreeView::getParentString( QListViewItem* item ) const {
	return getFullPath( item->parent() );
}
//-----------------------------------------------
QString KBearSiteManagerTreeView::getFullPath( QListViewItem* item ) const {
	QString parentStr = QString::null;
	while( item ) {	
		if( parentStr.isNull() ) {
			parentStr = "/" + item->text( 0 ) ;
		}
		else {
			parentStr = "/" + item->text( 0 ) + parentStr;
		}
		item = item->parent();
	}
	return parentStr;
}
//-----------------------------------------------
QListViewItem* KBearSiteManagerTreeView::addSite( QListViewItem* parent, const QString& site ) {
	QPixmap pix(KGlobal::iconLoader()->loadIcon("ftp", KIcon::Small ));
	KBearSiteManagerTreeViewItem* item;
	if( parent )
		item = new KBearSiteManagerTreeViewItem( parent, site );
	else
		item = new KBearSiteManagerTreeViewItem( this, site );
	item->setExpandable( false );
	item->setPixmap( pix );
	return item;
}
//-----------------------------------------------
QListViewItem* KBearSiteManagerTreeView::addGroup( QListViewItem* parent, const QString& group ) {
	KBearSiteManagerTreeViewItem* item;
	if( parent )
		item = new KBearSiteManagerTreeViewItem( parent, group );
	else
		item = new KBearSiteManagerTreeViewItem( this, group );
	item->setOpen( false );
	return item;
}
//-----------------------------------------------
void KBearSiteManagerTreeView::slotExecuted( QListViewItem* item ) {
	if( ! item || ! item->isExpandable() )
		return;
	ensureItemVisible( item );
	setCurrentItem( item );
	setSelected( item, true );
	item->setOpen( ! item->isOpen() );
}
//-----------------------------------------------
void KBearSiteManagerTreeView::slotOpenFolder() {
	m_autoOpenTimer.stop();
	if( m_dropItem && m_dropItem->isExpandable() ) {   // if we have a folder
		emit executed( m_dropItem ); // open it
	}
}
//-----------------------------------------------
QListViewItem* KBearSiteManagerTreeView::findItemByName( const QListViewItem* parent, const QString& name ){
	QListViewItemIterator it( this );
	for ( ; it.current(); ++it ) {
		if ( it.current()->parent() == parent && it.current()->text( 0 ) == name )
			return it.current();
	}
	return 0L;
}
//-----------------------------------------------
QListViewItem* KBearSiteManagerTreeView::findParentByFullName( const QString& name ){
	if( name.isNull() )
		return 0L;
	QStringList nameList = QStringList::split( "/", name );
	QListViewItem* parent = 0L;
	QListViewItem* item = 0L;
	for( QStringList::Iterator iter = nameList.begin(); iter != nameList.end(); ++iter ) {
		item = findItemByName( parent, *iter );
		if( item )
			parent = item;
		else
			return parent;
	}
	return parent;
}
//-----------------------------------------------
void KBearSiteManagerTreeView::setDNDEnabled( bool enable ){
	setDragEnabled( enable );
	setDropVisualizer( enable );
	setAcceptDrops( enable );
	viewport()->setAcceptDrops( enable );
}
#ifndef NO_INCLUDE_MOCFILES
#include "kbearsitemanagertreeview.moc"
#endif
