/***************************************************************************
                          CompilationTreeView.cpp  -  description
                             -------------------
    begin                : Tue Jul 24 2001
    copyright            : (C) 2001 by Alex Podolsky
    email                : alexpod@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.                                   *
 *                                                                         *
 ***************************************************************************/

#include <iostream.h>
// QT includes
#include <qdir.h>
#include <qstringlist.h>
#include <qpushbutton.h>
#include <qclipboard.h>
#include <qapp.h>
#include <qfileinfo.h>
#include <qdragobject.h>
#include <qevent.h>
#include <qregexp.h>

// KDE includes
#include <kurl.h>
#include <klocale.h>
#include <kconfig.h>
#include <kapplication.h>
#include <kpropsdlg.h>
#include <kopenwith.h>
#include <kmessagebox.h>
#include <klistview.h>
#include <kfiledialog.h>
#include <kio/netaccess.h>

// CDBO includes
#include "CompilationTreeView.h"
#include "CompilationTreeView.moc"
#include "CdboFileItem.h"
#include "FolderItem.h"

CompilationTreeView::CompilationTreeView( QWidget *parent, const char *name) : KListView(parent, name){

	setAcceptDrops(true);
	setDropVisualizer(true);

	top = new CdboFileItem(this, "topNodeInCDBOWithStrangePath");
	parentForDrop = top;
	
	saved = true;
	listFileName = "";

	//////////////////////////////////////////////////////////////////////

	connect(  this, SIGNAL(dropped (QDropEvent *, QListViewItem *)),
						this, SLOT(dropOcurred(QDropEvent *, QListViewItem *)));
	
	
}
//================================================
CompilationTreeView::~CompilationTreeView(){
}

//====================================
//====================================
//=====  UTILITIES ====================
//====================================
//====================================
//============================================================
QString CompilationTreeView::currentItemPath(){
	QListViewItem *item = currentItem();
	
	if ( !item || item == top) return "";
	
	CdboFileItem *cur = dynamic_cast<CdboFileItem *> (item);
	if( cur )
		return cur->getFilePath();
	else
		return "";	
}

//============================================================
QString CompilationTreeView::currentItemName(){
	QListViewItem *item = currentItem();
	if ( !item || item == top) return "";
	
	CdboFileItem *cur = dynamic_cast<CdboFileItem *> (item);
	if( cur )
		return cur->getFileName();
	else
		return "";
}
//============================================================
void CompilationTreeView::setParentForDrop(QListViewItem *item){
	if ( !item || item == top){
		parentForDrop = top;
		return;
	}
	FolderItem *i = dynamic_cast<FolderItem *> (item);
	if(!i)
		parentForDrop = dynamic_cast<CdboFileItem *> (item->parent());
	else
		parentForDrop = dynamic_cast<CdboFileItem *> (item);
}
//============================================================
int CompilationTreeView::currentItemSize(){
	QListViewItem *item = currentItem();
	if ( !item || item == top) return 0;
	
	CdboFileItem *cur = dynamic_cast<CdboFileItem *> (item);
	if( cur )
		return cur->getFileSize();	
	else
		return 0;

}
//========================
bool CompilationTreeView::isEmpty(){////////////////////////////////////////////////????????????????????????///
	if(top->childCount() == 0){
		KMessageBox::detailedSorry(this,
			i18n("Compilation list is empty!"),
			i18n("You must populate the compilation list with the files you\nwish to have on your new CD."\
			     " To accomplish this, just\ndrag the source files or directories from one of the upper\n(source) views down"\
			     " into the compilation view. This option\ncan then be used to burn your files on to CD."));
		return true;
	}
	return false;
}

//====================================
//====================================
//=====  ACTIONS ====================
//====================================
//====================================
void CompilationTreeView::remove(){
	QListViewItem *item = getItemForDeletion();
	if(!item) return;
	setCurrentItem(item);
	
	subtractFromTotal(currentItemSize() / 1024);
	fList.remove(currentItemPath());
	nameList.remove(currentItemName());
	
	top->takeItem(item);
	delete item;
	saved = false;
	emitGotCaption();
}
//============================================
QListViewItem* CompilationTreeView::getItemForDeletion(){
	QListViewItem *item = currentItem();
	if(!item || item == top) return 0;
	while(true){
		if(item->parent() == top)
			return item;
		item = item->parent();
	}
}
//---------------------------------------------------------------------------------------------
void CompilationTreeView::keyPressEvent(QKeyEvent *e){
	if(e->key() == Key_Delete){
		remove();
	}
	if(e->key() == Key_F5){
		slotReload();
	}
}
//============================================
void CompilationTreeView::slotProperties(){
	QListViewItem *item = currentItem();
	if ( !item)
		return;
	else if(item == top)
  		compilSettingsSlot();
  	else{
  		KPropertiesDialog *propDlg = new KPropertiesDialog( KURL( currentItemPath() ) );
  		connect( propDlg, SIGNAL( applied() ), this , SLOT( slotReload() ) );
  	}
}
//---------------------------------------------------------------------------------
void CompilationTreeView::openWithSlot(){
	QStringList list(currentItemPath());
	KFileOpenWithHandler *kfowh = new KFileOpenWithHandler();
	kfowh -> displayOpenWithDialog( KURL::List( list ) );
}
//---------------------------------------------------------------------------------------------
void CompilationTreeView::slotReload(){
	//empty
}
//---------------------------------------------------------------------------------------------
void CompilationTreeView::reloadTop(){
	if(!top)
		top = new CdboFileItem(this, "topNodeInCDBOWithStrangePath");
	
}
//---------------------------------------------------------------------------------------------
void CompilationTreeView::compilSettingsSlot(){
	//empty
}
//==============================
void CompilationTreeView::updateSettings(){
	//empty
}
//====================================
//====================================
//===== ADDING ITEMS ====================
//===================================
//====================================
bool CompilationTreeView::acceptDrag (QDropEvent* event) const{
	if(QTextDrag::canDecode(event))
		return true;
	else
		return false;
}
//====================================
void CompilationTreeView::dropOcurred(QDropEvent * e, QListViewItem */*item*/){
	//setParentForDrop(item);
	QString path;
	if(QTextDrag::decode(e, path)){
		if(path.find("file:") != -1){
			if(addMultipleItems(path))
				e->accept();
			else
				e->ignore();
		}
		else if(addItem(path))
			e->accept();
		else
			e->ignore();
	}	
	else
		e->ignore();	
}
//================================
bool CompilationTreeView::addMultipleItems(QString path){
	bool valid = true;
	QString buff;
	QStringList list(QStringList::split("\n",path));
	for(int i = 0; i < (int)list.count(); i++){
		buff = list[i].replace(QRegExp("file:"), "");
		
		int p =buff.length()-1;
		if(!buff[p].isLetterOrNumber() && !buff[p].isPunct())
			buff = buff.left(p);
			
		buff.simplifyWhiteSpace();
		if(!addItem(buff)){
			valid = false;
			break;
		}
	}	
	return valid;
}
//================================
bool CompilationTreeView::addMultipleItems(QStringList list){
	bool valid = true;
	QString buff;
	for(int i = 0; i < (int)list.count(); i++){
		buff = list[i];
		
		int p =buff.length()-1;
		if(!buff[p].isLetterOrNumber() && !buff[p].isPunct())
			buff = buff.left(p);
			
		buff.simplifyWhiteSpace();
		if(!addItem(buff)){
			valid = false;
			break;
		}
	}	
	return valid;
}
//=========================================
bool CompilationTreeView::addItem(QString path){
	return false;
}
//===========================================================
void CompilationTreeView::removeAll(){
	clear();
	fList.clear();
	nameList.clear();
	listFileName = "";
	top = 0;
	resetTotal();
	updateSettings();
	saved = false;
     	emitGotCaption();
}
void CompilationTreeView::resetTotal(){
	//empty
}
//==============================
void CompilationTreeView::subtractFromTotal(int){
	//empty
}
//==============================
void CompilationTreeView::emitGotCaption(){
	if(fList.count() == 0)
		emit gotCaption(listFileName, false);
	else
		emit gotCaption(listFileName, !saved);
}
