/***************************************************************************
                          FakeFoldersListView.cpp  -  description
                             -------------------
    begin                : Sat Dec 1 2001
    copyright            : (C) 2001 by Alex Podolsky
    email                : alexpod@users.sf.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 <qpixmap.h>
#include <qheader.h>
#include <qpopupmenu.h>
#include <qapp.h>
#include <qfileinfo.h>
#include <qstringlist.h>
#include <qstrlist.h>
#include <qlistview.h>
#include <qdragobject.h>
#include <qevent.h>
#include <qcursor.h>
#include <qprogressdialog.h>
#include <qregexp.h>

// KDE includes
#include <krun.h>
#include <klocale.h>
#include <kiconloader.h>
#include <kopenwith.h>
#include <kmessagebox.h>
#include <klistview.h>
#include <kconfig.h>
#include <kapplication.h>
#include <kio/netaccess.h>
#include <klineeditdlg.h>
#include <kio/job.h>
#include <kio/jobclasses.h>

// app includes
#include "FakeFoldersListView.h"
#include "FakeFoldersListView.moc"
#include "FakeFolderItem.h"
#include "FakeFilesListView.h"
#include "FakePropertiesDialog.h"
#include "../../CdboCompilationView.h"
#include "DriveInfoDialog.h"
#include "../EstimatePnl.h"

using namespace KIO;

FakeFoldersListView::FakeFoldersListView(QWidget *parent, const char *name):
 	KListView( parent, name ){	
	
 	doListern = false;
	setDragEnabled(true);
	setAcceptDrops(true);
	setDropVisualizer(true);
	//setDropHighlighter(true);
	
	
	/////////////////////////
	//setMinimumSize( QSize( 12, 0 ) );
	setRootIsDecorated( true );
	header()->hide();
	setSorting( 0 );
  	setFrameStyle( Panel | Sunken );
  	setLineWidth( 2 );
  	addColumn( i18n("Name") );
	//setFocusPolicy(QWidget::ClickFocus);
	
	config = new KConfig("cdbakeovenrc");
	
	config->setGroup("Default Settings");	
	showHidden = config->readBoolEntry("Show Hidden Items in Fake Folders List", true);
	
	//setAutoOpen(true);
//	dragedItem = 0;
	fakeListView = 0;
	dicts.setAutoDelete(true);
	multiple = false;
	top = 0;
	
	/////////////////////////////////////////////////////////
	folderMenu = new QPopupMenu();
	
	propertiesIndex = folderMenu -> insertItem( i18n("Folder(s) Properties"),   this ,SLOT(slotProperties()));
	removeIndex = folderMenu -> insertItem(UserIcon("cross"), i18n("Remove Folder(s)"), this ,SLOT(remove()));
	
	
	folderMenu -> insertSeparator();
	folderMenu -> insertItem( SmallIcon("folder_red"), i18n("Add New Directory..."), this ,SLOT(addNewFolder()));
	
	//folderMenu -> insertItem( BarIcon("reload"), i18n("Reload List"),   this ,SLOT(slotReload()));
	folderMenu -> insertSeparator();	
	folderMenu ->insertItem(UserIcon("isoSetup"), i18n("Modify ISO Image Properties"), this ,SLOT(compilSettingsSlot()));
	folderMenu ->insertItem(UserIcon("burn"), i18n("Create CD"), parent->parentWidget(),SLOT(createCD()));
	folderMenu ->insertItem(UserIcon("cdImageSm"),
		i18n("Create ISO Image"), parent->parentWidget(),SLOT(createISO()));
	
	copyMenu = new QPopupMenu();
	copyMenu ->insertItem(i18n("&Move Here"), this ,SLOT(moveItemsSlot()));
	copyMenu ->insertItem(SmallIcon("editcopy"), i18n("&Copy Here"), this ,SLOT(copyItemsSlot()));	
	
	//////////////////////////////////////////////////////////////////////

	connect(  this, SIGNAL(doubleClicked(QListViewItem *)),
						this, SLOT(slotSelectFile(QListViewItem *)));
	connect(  this, SIGNAL(clicked(QListViewItem *)),
						this, SLOT(slotSelectFileConst(QListViewItem *)));
	/*connect(  this, SIGNAL(selectionChanged(QListViewItem *)),
						this, SLOT(slotSelectFile(QListViewItem *)));*/
	connect(	this, SIGNAL(returnPressed(QListViewItem *)),
						this, SLOT(slotSelectFile(QListViewItem *)));
						
	connect( this, SIGNAL(rightButtonPressed(QListViewItem*, const QPoint&, int)),
					 this, SLOT(slotMenu(QListViewItem*, const QPoint&, int)));
					
					
	connect(  this, SIGNAL(dropped (QDropEvent *, QListViewItem *)),
						this, SLOT(dropOcurred(QDropEvent *, QListViewItem *)));
				
	/*connect(  this, SIGNAL(onItem(QListViewItem*)),
						this, SLOT(slotSelectFile(QListViewItem *)));
						
						*/
	updateSettings();
	parentForDrop = top;
}
//==================================================
FakeFoldersListView::~FakeFoldersListView(){
}
//==============================================================
void FakeFoldersListView::updateSettings(){
	//config->sync();
	if(config)
 		delete config;
	config = new KConfig("cdbakeovenrc");
	config->setGroup("ISO Settings");	
	QString fn = config->readEntry("Custom ISO Name", "cdboImage_<DATE>.iso");
	config->setGroup("Default Settings");	
	if(!top)
		top = new FakeFolderItem(this, fn);
	top->setPixmap(0,BarIcon("cdrom_unmount", KIcon::SizeSmall ));
	top->setText(0, fn);
}
//====================================
void FakeFoldersListView::setEstimate(EstimatePnl *e) {
	if(!e) return;
	
	estimate = e;
	connect(estimate->getRecalculateBtn(), SIGNAL(clicked ()),
						this, SLOT(resetSize()));
	connect(estimate, SIGNAL(recalculate ()),
						this, SLOT(resetSize()));
	
}
///======================================================
///======================================================
///========== FILE OPERATIONS =================
///======================================================
///======================================================
//==============================================================
QString FakeFoldersListView::getPathToTop(FakeFolderItem *item){
	if(item == top){
		return "/";
	}
	
	FakeFolderItem *tItem = item;
	QString path = item->getName() + "/";
	
	do {
		tItem = (FakeFolderItem *)tItem->parent();
		if(tItem == top){
			return "/" + path;
		}
		path = tItem->getName() + "/" + path;
	}while(tItem != 0);
	return path;
}
//=====================================
bool FakeFoldersListView::isParentOf(QListViewItem *i1, QListViewItem *i2){
	if(i2 == top)
		return false;
	
	QListViewItem *parentOf_i2 = i2->parent();
	while(parentOf_i2 != top) {
		if(parentOf_i2 == i1){
			return true;
		}
		parentOf_i2 = parentOf_i2->parent();
	}
	
	return false;
}
//=============================================
void FakeFoldersListView::slotSelectFile(QListViewItem *item){
	FakeFolderItem *ftf = dynamic_cast<FakeFolderItem *>(item);
	if (!ftf){
		return;
	}
	ftf->setOpen(!ftf->isOpen());
		
	emit folderClicked(ftf);
	parentForDrop = ftf;
	setSelected(item, true);
	ensureItemVisible(item);
}
//=============================================
void FakeFoldersListView::slotSelectFileConst(QListViewItem *item){
	FakeFolderItem *ftf = dynamic_cast<FakeFolderItem *>(item);
	if (!ftf)
		return;//ftf = top;
	
	emit folderClicked(ftf);
	parentForDrop = ftf;
	setSelected(item, true);
}
//=============================================
void FakeFoldersListView::setParentForDrop(QListViewItem *item){
	if ( !item )
		return;
	
	FakeFolderItem *ftf = dynamic_cast<FakeFolderItem *>(item);
	if (!ftf)
		return;//ftf = top;
	
	parentForDrop = ftf;
	setSelected(item, true);
}
//==============================================================
void FakeFoldersListView::slotMenu(QListViewItem *item, const QPoint &point, int){
	if(!item)
		item = top;
	setSelected(item, true);
	if(item == top){
		folderMenu->setItemEnabled(propertiesIndex, false);
		folderMenu->setItemEnabled(removeIndex, false);
	}
	else if(((FakeFolderItem *)item)->isImmutable()){
		folderMenu->setItemEnabled(propertiesIndex, true);
		folderMenu->setItemEnabled(removeIndex, false);
	}
	else{
		folderMenu->setItemEnabled(propertiesIndex, true);
		folderMenu->setItemEnabled(removeIndex, true);
	}
	folderMenu ->popup( point);
}
//============================================
void FakeFoldersListView::slotProperties(){
	if(multiple){
		if(!fakeListView){
			return;
		}
		fakeListView->filePropertiesSlot();
		multiple = false;
		return;
	}
	FakeFolderItem *ftf = dynamic_cast<FakeFolderItem *>(currentItem());
	if (!ftf)
		return;
  	new FakePropertiesDialog(ftf, this, "propDlg" );
}
//=============================================
void FakeFoldersListView::currentModifiedSlot(){
	emit modified();
	emit folderClicked(parentForDrop);
}
//=============================================
void FakeFoldersListView:: addNewFolder(){
	FakeFolderItem *ftf = dynamic_cast<FakeFolderItem *>(currentItem());
	if (!ftf)
		return;
	
	bool done = false, ok;
	QString name = "Directory";
	do{
		name = KLineEditDlg::getText("New Drectory", name, &ok, this);
		if(!ok)
			return;
		name = name.simplifyWhiteSpace();
		if(name.isEmpty()){
			int result = KMessageBox::warningYesNo(this,
					i18n("New folder name cannot be empty! "\
					"Would you like to choose another name?"),
        				i18n("No Name"),
        				KStdGuiItem::yes(),
        				KStdGuiItem::cancel());

			switch(result){
				case KMessageBox::Yes:
       				done = false;
       				break;
       			case KMessageBox::No:
       				return;
			}	
		}
		else if(ftf->containsEntry(name)){
			int result = KMessageBox::warningYesNo(this,
					i18n("An item with the same name already exists in this folder. "\
					"Would you like to choose another name?"),
        				i18n("%1 Already Exists").arg(name),
        				KStdGuiItem::yes(),
        				KStdGuiItem::cancel());
        				
			switch(result){
				case KMessageBox::Yes:
       				done = false;
       				break;
       			case KMessageBox::No:
       				return;
			}	
		}
		else
			done = true;
	}
	while( !done );
	
	FakeFolderItem *newItem = new FakeFolderItem(ftf,
									name );
	ensureItemVisible(newItem);
    	//setSelected(newItem, true);
    	
	emit folderClicked(parentForDrop);
	emit modified();
}
//=============================================
bool FakeFoldersListView::remove(){
	FakeFolderItem *item = dynamic_cast<FakeFolderItem *>(currentItem());
	if (!item || item == top)
		return false;
	 if(item->isImmutable()){
		int result = KMessageBox::warningYesNo(this,
					i18n("You cannot remove this folder. "\
					"It was imported from the previous session"),
        				i18n("Cannot Remove %1").arg(item->getName()),
        				i18n("&Skip"),
        				KStdGuiItem::cancel());
        				
		switch(result){
			case KMessageBox::Yes:
       			return true;
       		case KMessageBox::No:
       			return false;
		}
	}
	FakeFolderItem *v = (FakeFolderItem *)item->parent();
	v->subtractFromSize(item->getSize());
	delete item;
	resetSize();
	
	slotSelectFileConst(v);
	emit modified();
	return true;
}
//===========================================================
void FakeFoldersListView::removeAll(){
	clear();
	top = 0;
	updateSettings();
	parentForDrop = top;
	resetSize();	

	emit folderClicked(parentForDrop);
	emit modified();
}
//===========================================================
void FakeFoldersListView::resetSize(){
	estimate->reset();
	
	if(top->getSize() > 0.0)
		estimate->add(top->getSize() /1024);
}
//============================================
bool FakeFoldersListView::moveItemsSlot(){
	if(!dragedItem){
		if(!fakeListView){
			return false;
		}
		fakeListView->moveSelectedTo(parentForDrop);
		//emit folderClicked(parentForDrop);
		return true;
	}
	////////////////////////////////////////////////////////////////////////////////////////////
	if(dragedItem == parentForDrop){
		KMessageBox::sorry(this,
             	i18n("You cannot move the directory into itself"));
		return true;
	}
	if(isParentOf(dragedItem, parentForDrop)){
		KMessageBox::sorry(this,
              	i18n("You cannot move a parent directory into its child."));
       	return false;
	}
	bool cancel;
	if(!checkChildNameClash(dragedItem->getName(), &cancel))
		return !cancel;

	((FakeFolderItem *)dragedItem->parent())->subtractFromSize(dragedItem->getSize());
	dragedItem->parent()->takeItem(dragedItem);
	
	parentForDrop->insertItem(dragedItem);
	parentForDrop->addToSize(dragedItem->getSize());
	//emit folderClicked(parentForDrop);
	emit modified();
	return true;
}
//============================================
bool FakeFoldersListView::copyItemsSlot(){
	if(!dragedItem){
		if(!fakeListView){
			return false;
		}
		fakeListView->copySelectedTo(parentForDrop);
		return true;
	}
	
	if(!canFit(dragedItem->getSize() / 1024 / 1024, dragedItem->getName())){
       	resetSize();
       	return false;
       }
	
	bool cancel;
	if(!checkChildNameClash(dragedItem->getName(), &cancel))
		return !cancel;
	

	
	progress = new QProgressDialog( i18n("Copying %1. Please wait...").arg(dragedItem->getName()), i18n("&Stop"),
							dragedItem->getSize() / 1000,
                                this, "progress", TRUE );

       progress->setCaption( i18n("Please wait..."));
	FakeFolderItem *newFolder = new FakeFolderItem(dragedItem, this, progress);
	FakeFolderItem *newItem;
	for(FakeFolderItem *i=(FakeFolderItem *)dragedItem->firstChild(); ; i=(FakeFolderItem *)i->nextSibling()){
		if(!i)
			break;
		newItem = new FakeFolderItem(i, newFolder, progress);
		if(i->childCount() > 0){
			if(!copyRow(i, newItem)){
				delete newFolder;
				delete progress;
				return false;
			}
		}
	}
	takeItem(newFolder);
	parentForDrop->insertItem(newFolder);
	parentForDrop->addToSize(newFolder->getSize());
	progress->setProgress(dragedItem->getSize() / 1000);
	delete progress;
	emit folderClicked(parentForDrop);
	emit modified();
	resetSize();
	return true;
}
//============================================
bool FakeFoldersListView::copyRow(FakeFolderItem *item, FakeFolderItem *parent){
	FakeFolderItem *newFolder;
	for(FakeFolderItem *i=(FakeFolderItem *)item->firstChild(); ; i=(FakeFolderItem *)i->nextSibling()){
		if(!i)			
			return true;
			
		if ( progress->wasCancelled() )
			return false;
			
		newFolder = new FakeFolderItem(i, parent, progress);
		
		if(i->childCount() > 0){
			if(!copyRow(i, newFolder))
				return false;
		}		
	}
	return true;
}
//============================================
void FakeFoldersListView::compilSettingsSlot(){
	popUpSettings(CdboCompilationView::ImageSettings);
}
///======================================================
///======================================================
///=============== DRAG ============
///======================================================
///======================================================



//===================================
bool FakeFoldersListView::acceptDrag (QDropEvent* event) const{
	if(QTextDrag::canDecode(event)){
		((FakeFoldersListView *)top->listView())->setPointForDrop(mapToGlobal(event->pos()));
		return true;
	}
	else
		return false;
}
//====================================
void FakeFoldersListView::dropOcurred(QDropEvent * e, QListViewItem *){
	doListern = false;
	
	QString path;
	if(QTextDrag::decode(e, path)){
		if(path.find("This package came from your friendly FakeFilesListView") != -1){
			fakeListView =  dynamic_cast<FakeFilesListView *>(e->source());
			dragedItem = 0;
			if(!pointForDrop.isNull()){
				copyMenu->popup(pointForDrop);
				pointForDrop.setX(0);
				pointForDrop.setY(0);
			}
			else
				copyMenu->popup( mapToGlobal(e->pos()));
				
			e->accept();
			return;
		}
		else if(e->source() == this){
			
			if(dragedItem == parentForDrop){
				/*KMessageBox::sorry(this,
              			"You can't drop a directory onto itself");*/
              		e->ignore();
				return;
			 }
			 if(!pointForDrop.isNull()){
				copyMenu->popup(pointForDrop);
				pointForDrop.setX(0);
				pointForDrop.setY(0);
			}
			else
			 	copyMenu->popup( mapToGlobal(e->pos()));
			
			e->accept();
			return;
		}
		else
			dragedItem = 0;	
		
		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 FakeFoldersListView::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;
		}
	}	
	emit folderClicked(parentForDrop);
	emit modified();
	return valid;
}
//================================
bool FakeFoldersListView::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;
		}
	}	
	emit folderClicked(parentForDrop);
	emit modified();
	return valid;
}

//=========================================
bool FakeFoldersListView::addOneItem(QString path){
	bool b = addItem(path);
	emit folderClicked(parentForDrop);
	emit modified();
	return b;
}
//=========================================
bool FakeFoldersListView::addItem(QString path){
	if(!parentForDrop)
		parentForDrop = top;
		
	if(!canAccept(path))
		return false;
	
	return true;
}
//================================
bool FakeFoldersListView::canAccept(QString path) {
	dragedItem = 0;	
	
	QFileInfo d( path );
	if(!d.exists() || !d.isReadable()){
		KMessageBox::error(this,
				i18n("Cannot accept %1: "
				"Not a valid path or you do not "
				"have enough privileges to add this item.").arg(path));
		return false;
	}
	bool cancel;
	if(!checkChildNameClash(d.fileName(), &cancel))
		return !cancel;
	
	if(d.isDir()){
		loadingSession = false;
		FakeFolderItem *newItem = new FakeFolderItem(parentForDrop,
									d.fileName() );

		SourceAndPositionMap *dirAndPosMap = new SourceAndPositionMap();
             dirAndPosMap->insert(path + "/", newItem);
             dicts.insert(path + "/", dirAndPosMap);
		
		//newItem->setOpen(true);
    		ensureItemVisible(newItem);
		emit haveStatus(i18n("Processing directory. Please wait..."));
		emit processStarted();
		
		KURL url(path);
		KIO::ListJob * listJob = listRecursive( url, false);
    		
    		listJob->setName((path + "/").utf8());
    		emit longProcessStarted(listJob);
    		//emit changingSize(true);
    		
    		connect( listJob, SIGNAL(entries( KIO::Job *, const KIO::UDSEntryList& )),
             		SLOT( slotEntries( KIO::Job*, const KIO::UDSEntryList& )));
             		
        	connect(listJob, SIGNAL(result ( KIO::Job *)),
			this, SLOT(slotResult(KIO::Job *) ));
			
		
		
		return true;
	}


	
	///////////////////////////////////////////////////////////////////////////
	int size = (int)d.size();
	if(!canFit(size / 1024, d.fileName())){
       	resetSize();
       	return false;
       }
	parentForDrop->addEntry(path, d.fileName(), size);
	//saved = false;
	//emitGotCaption();
		
	//resetSize();

	return true;	
}
//==========================================
bool FakeFoldersListView::checkChildNameClash(QString fileName, bool *cancel){
	if(parentForDrop->containsEntry(fileName)){
		switch( shouldOverwrite(fileName) ) {
			case KMessageBox::No:{
				*cancel = false;
				return false;
			}
			case KMessageBox::Cancel:{
				*cancel = true;
				return false;
			}
			case KMessageBox::Yes:{
				FakeFolderItem *newItem = parentForDrop->getChild(fileName);
				if(newItem != 0){
					if(newItem == dragedItem){
						*cancel = false;
						return false;
					}
					if(newItem->isImmutable()){
						int result = KMessageBox::warningYesNo(this,
							i18n("You cannot replace '%1'. "
							"It was imported from the previous session.").arg(fileName),
							i18n("Cannot Remove %1.").arg(fileName),
							i18n("&Skip"),
							KStdGuiItem::cancel());

						switch(result){
							case KMessageBox::Yes:
								*cancel = false;
								return false;
							case KMessageBox::No:
								*cancel = true;
								return false;
						}
					}
					if(dragedItem != 0 && isParentOf(newItem, dragedItem)){
      						KMessageBox::sorry(this,
            						i18n("You cannot replace a parent directory with its child."));
						*cancel = false;
      						return false;
      					}
					parentForDrop->subtractFromSize(newItem->getSize());
					emit modified();
					delete newItem;
				}
				else{
					if(!parentForDrop->removeEntry(fileName)){
						int result = KMessageBox::warningYesNo(this,
							i18n("You cannot replace this item. "\
							"It was imported from the previous session."),
							i18n("Cannot Remove %1.").arg(fileName),
							i18n("&Skip"),
							KStdGuiItem::cancel());

						switch(result){
							case KMessageBox::Yes:{
								*cancel = false;
								return false;
							}
							case KMessageBox::No:{
								*cancel = true;
								return false;
							}
						}
					}
					emit modified();
				}
			}
		}
	}
	*cancel = false;
	return true;
}
//==========================================
int FakeFoldersListView::shouldOverwrite(QString name){
	return KMessageBox::warningYesNoCancel(this,
					i18n("An item with the same name already exists in this folder. "\
					"Click 'Yes' if you would like to replace the old item with this new item, "\
					"or 'Cancel' to stop the whole operation."),
        				i18n("%1 is Already in the List").arg(name),
        				KStdGuiItem::yes(),
        				i18n("&Skip"));
}
//==========================================
int FakeFoldersListView::shouldOverwriteDir(QString name){
	return KMessageBox::warningYesNoCancel(this,
					i18n("A directory with the same name is already part of this folder. "
					"Click 'Yes' if you would like to replace the old item with this new item, "
					"or 'Cancel' to stop this whole operation."),
        				i18n("%1 is Already in the List").arg(name),
        				KStdGuiItem::yes(),
        				i18n("&Skip"));
}
//================================
void FakeFoldersListView::importSession(QString pathToDrive) {
	
	loadingSession = true;
	
	SourceAndPositionMap *dirAndPosMap = new SourceAndPositionMap();
       dirAndPosMap->insert(pathToDrive + "/", top);
       dicts.insert(pathToDrive + "/", dirAndPosMap);

	emit haveStatus(i18n("Loading session from CD. Please wait..."));
	emit processStarted();
	
	KURL url(pathToDrive);//.replace(QRegExp("____________"),""));
	KIO::ListJob * listJob = KIO::listRecursive( url, false);
    		
    	listJob->setName((pathToDrive + "/").utf8());
    	emit longProcessStarted(listJob);
    		//emit changingSize(true);
    		
    	connect( listJob, SIGNAL(entries( KIO::Job *, const KIO::UDSEntryList& )),
            		SLOT( slotEntries( KIO::Job*, const KIO::UDSEntryList& )));
            		
       connect(listJob, SIGNAL(result ( KIO::Job *)),
		this, SLOT(slotResult(KIO::Job *) ));
	
}
///=========================================================
void FakeFoldersListView::slotEntries( KIO::Job* job, const KIO::UDSEntryList & list ){
	SourceAndPositionMap *dirAndPosMap = dicts[job->name()];
	KIO::UDSEntryListConstIterator it = list.begin();
	KIO::UDSEntryListConstIterator end = list.end();
	//QString url = "";
	bool noGood = false;
	bool dir = false;
	QString name;
	long size = 0;
	FakeFolderItem* newItem;
	FakeFolderItem* parItem;
	
	for (; it != end; ++it) {
		KIO::UDSEntry::ConstIterator it2 = (*it).begin();
		for( ; it2 != (*it).end(); it2++ ) {
			switch( (*it2).m_uds ) {
            			
              		case KIO::UDS_LINK_DEST:{///FIXME:: handle links
             				noGood = true;
             				break;
              		}
              		case KIO::UDS_FILE_TYPE:{
              			if((*it2).m_long == 16384){
              				dir = true;
              			}
              			else{
              				dir = false;
             			}
              			break;
              		}
              		case KIO::UDS_NAME:{
             				if((*it2).m_str == "." || (*it2).m_str == ".."){
             					noGood = true;
             					break;
             				}
             				name = (*it2).m_str;
					break;
              		}
              		case KIO::UDS_SIZE:{
              			if(!dir){
              				size = (*it2).m_long;
					}
					break;
              		}
              		default:
					break;
			}
			if(noGood)
				break;
		}
		if(!noGood){
			if(!dir){
			////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
				if(!estimate->add(size / 1024)){
					QString id = job->name();
					if(job){	
       					job->kill();
       					//delete job;
       				}
					KMessageBox::sorry(this,
       					i18n("Cannot accept %1: "
       					"It is too big to fit on this CD!").arg(id));
       				emit longProcessDone(job);
       				longProcessCanceled(id);
       				return;
       			}
				////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
				int k = name.findRev("/", -1);
								
				parItem = (* dirAndPosMap)[name.left(k)];
				if(!parItem){
					parItem = (* dirAndPosMap)[job->name()];
				}
				
				parItem->addEntry(job->name() + name, name.right(name.length() - k -1), size, loadingSession);
				
			}
			else{
				int k = name.findRev("/", -1);
			
				parItem = (* dirAndPosMap)[name.left(k)];
				if(!parItem){
					parItem = (* dirAndPosMap)[job->name()];
				}
				newItem = new FakeFolderItem(parItem, name.right(name.length() - k -1), loadingSession);
             		
             		dirAndPosMap->insert(name, newItem);
             	}	
             }
             noGood = false;
        }
}
///=========================================================
void FakeFoldersListView::slotResult( KIO::Job * j){
	dicts.remove(j->name());

	emit folderClicked(parentForDrop);
	emit longProcessDone(j);
    	emit processDone();
	emit haveStatus(i18n("Ready."));
	
	if(loadingSession){
		top->setOpen(true);
		KIO::SimpleJob * job = KIO::unmount(j->name(), false);
		job->setName(j->name());
    		connect(job, SIGNAL(result ( KIO::Job *)),
			this, SLOT(slotUMountResult(KIO::Job *) ));
		
	}
	emit modified();
	resetSize();
}
//=============================================
void FakeFoldersListView::longProcessCanceled(QString id){
	emit processDone();
	emit haveStatus(i18n("Ready."));
	
	if(!loadingSession){
		SourceAndPositionMap *dirAndPosMap = dicts[id];
		FakeFolderItem *item = (* dirAndPosMap)[id];
		parentForDrop->subtractFromSize(item->getSize());
		delete item;
	
		//dirAndPosMap.clear();
		dicts.remove(id);
		emit folderClicked(parentForDrop);
	}
    	else{
    		top->subtractFromSize(top->getSize());
		delete top->firstChild();
		
		//dirAndPosMap.clear();
		dicts.remove(id);
		emit folderClicked(top);
		
		KIO::SimpleJob * job = KIO::unmount(id, false);
		job->setName(id.utf8());
    		connect(job, SIGNAL(result ( KIO::Job *)),
			this, SLOT(slotUMountResult(KIO::Job *) ));
	}
	emit modified();
	resetSize();
}
///=========================================================
void FakeFoldersListView::slotUMountResult( KIO::Job * j){
	//emit longProcessDone(j);
	KIO::NetAccess::del(KURL(j->name()));
}
//=========================================================
void FakeFoldersListView::loadSession(){
	
	DriveInfoDialog *driveInfoDlg =
  		new DriveInfoDialog(this, "propDlg" );	
  	if(!driveInfoDlg->isReady())
  		detectAndTryToLoadSlot();
  	else{
  		connect( driveInfoDlg, SIGNAL( load(QString) ), this , SLOT( loadSession(QString) ) );
  		driveInfoDlg->exec();
  	}
}
//=========================================================
void FakeFoldersListView::detectAndTryToLoadSlot(){
	int result = KMessageBox::warningYesNo(this,
					i18n("No usable devices were detected! Would you like to launch the "
					"'Device Detection' dialog and try to import the session again?"),
        				i18n("No Usable Devices"));
        				
	switch(result){
		case KMessageBox::No:{
       		return;
       	}
       	case KMessageBox::Yes:{
       		popUpSettings(CdboCompilationView::DevicesSettings);
			//loadSession();
			return;
		}
	}
}
//=========================================================
void FakeFoldersListView::loadSession(QString drive){
	
	config->setGroup("Default Settings");		
	QString mountPoint = config->readEntry("Tmp Dir", "/tmp/")  + ".sessionLoad";
	KIO::NetAccess::mkdir(KURL(mountPoint));
	
	emit haveStatus(i18n("Mounting previous session. Please wait..."));
	emit processStarted();
	
	KIO::SimpleJob * job = KIO::mount(true, "iso9660", drive, mountPoint, false);
    		
    	job->setName(mountPoint.utf8());
    	emit longProcessStarted(job);
    	    		
       connect(job, SIGNAL(result ( KIO::Job *)),
		this, SLOT(slotMountResult(KIO::Job *) ));
	
}
///=========================================================
void FakeFoldersListView::slotMountResult( KIO::Job * j){
	emit longProcessDone(j);
	if(j->error()){
		//j->showErrorDialog(this);
		KIO::NetAccess::del(KURL(j->name()));
		KMessageBox::error(this,
				i18n("Failed to mount the previous session! Make sure that the disc is valid "\
				"and you have enough privileges to mount it."));
    		emit processDone();
		emit haveStatus(i18n("Ready."));
	}
	else
		importSession(j->name());
}
//=========================================================
void FakeFoldersListView::contentsDragEnterEvent(QDragEnterEvent *e){
	KListView::contentsDragEnterEvent(e);
	doListern = true;
}
//=========================================================
void FakeFoldersListView::contentsDragLeaveEvent(QDragLeaveEvent *e){
	KListView::contentsDragLeaveEvent(e);
	doListern = false;
}
//=========================================================
QRect FakeFoldersListView::drawDropVisualizer (QPainter *p, QListViewItem *parent, QListViewItem *){
	if(doListern){
		parentForDrop = dynamic_cast<FakeFolderItem *> (parent);
		if(!parentForDrop)
			parentForDrop = top;
		setSelected(parentForDrop, true);
		ensureItemVisible(parentForDrop);
	}
	return KListView::drawDropVisualizer(p, parentForDrop, parentForDrop);
}
//============================================================
void FakeFoldersListView::startDrag(){
	dragedItem = (FakeFolderItem *)currentItem();
	KListView::startDrag();
}
//=============================================
QDragObject *FakeFoldersListView::dragObject(){
	FakeFolderItem *cItem = dynamic_cast<FakeFolderItem *> (currentItem());
	
	if ( !cItem || cItem == top || cItem->isImmutable())
		return 0;
	
	QDragObject *d = new QTextDrag("This package should go from FakeFoldersListView to FakeFoldersListView",
		(QWidget *)this);
		
	const QPixmap *p = cItem->pixmap(0);
	d->setPixmap(*p);
	return d;
}
//============================================================
bool FakeFoldersListView::canFit(int size, QString fname){
	if(!estimate->add(size)){
		KMessageBox::sorry(this,
       		i18n("Cannot accept %1: It is too big to fit on this CD.").arg(fname));
       	return false;
	}
	return true;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//

//===========================================================
void FakeFoldersListView::slotShowHidden(){
	showHidden = !showHidden;
	QListViewItem *item;
	for(item = firstChild(); item; item = item->nextSibling()){
		FakeFolderItem * i = dynamic_cast<FakeFolderItem *>(item);
		if(i){
//	  		i->setShowHidden(showHidden);
//	  		i->reloadList();
			i->setOpen(false);
		}
	}
	config->setGroup("Default Settings");	
	config->writeEntry("Show Hidden Items in Fake Folders List", showHidden);
}
//---------------------------------------------------------------------------------------------
void FakeFoldersListView::keyPressEvent(QKeyEvent *e){
	if(e->key() == Key_Delete){
		remove();
	}
	/*if(e->key() == Key_F5){
		slotReload();
	}*/
}
///======================================================
///======================================================
///=============== PREPARE FOR BURN ============
///======================================================
///======================================================
//========================

//========================
QString* FakeFoldersListView::generateMappingsString(){
	
	progress = new QProgressDialog(i18n( "Generating file mappings, please wait..."), i18n("&Cancel"),
							(int)(top->getSize()/1000),
                                this, "progress", TRUE );

       progress->setCaption( i18n("Please wait..."));
       progress->setProgress(1 / 1000);
       //qApp->processEvents();
        //progress->setMinimumDuration(0);
	
	fileList.clear();
	FakeFolderItem *item = top;
	mappingsString = "";
	top->generateMappings(progress, &fileList);
	FakeFolderItem *i;
	for(i=(FakeFolderItem *)item->firstChild(); ; i=(FakeFolderItem *)i->nextSibling()){
		if(!i)
			break;
		if(i->childCount() > 0){
			if(!readRow(i)){
				delete progress;
				return 0;
			}
		}
		
		i->generateMappings(progress, &fileList);
	}
	
	mappingsString = fileList.join(" ");
	progress->setProgress( (int)(top->getSize()/1000));
	delete progress;
	return &mappingsString;
}
//============================================
bool FakeFoldersListView::readRow(FakeFolderItem *item){
	FakeFolderItem *i;
	for(i=(FakeFolderItem *)item->firstChild(); ; i=(FakeFolderItem *)i->nextSibling()){
		if(!i){
			
			return true;
		}
		if ( progress->wasCancelled() )
			return false;

		if(i->childCount() > 0){
			if(!readRow(i))
				return false;

		}
		i->generateMappings(progress, &fileList);
	}
	return true;
}
///======================================================
///======================================================
///=============== FILE ============
///======================================================
///======================================================
//========================

//========================
bool FakeFoldersListView::persist(KConfig *file){
	
	progress = new QProgressDialog( i18n("Saving file mappings, please wait..."), i18n("&Cancel"),
							(int)(top->getSize()/1000),
                                this, "progress", TRUE );

	progress->setCaption( i18n("Please wait..."));
	progress->setProgress(1 / 1000);

	top->persist(progress, file);
	FakeFolderItem *i;
	for(i=(FakeFolderItem *)top->firstChild(); ; i=(FakeFolderItem *)i->nextSibling()){
		if(!i)
			break;
		if(i->childCount() > 0){
			if(!persistRow(i, file)){
				delete progress;
				return false;
			}
		}

		i->persist(progress, file);
	}
	
	progress->setProgress( (int)(top->getSize()/1000));
	
	delete progress;
	return true;
}
//============================================
bool FakeFoldersListView::persistRow(FakeFolderItem *item, KConfig *file){
	FakeFolderItem *i;
	for(i=(FakeFolderItem *)item->firstChild(); ; i=(FakeFolderItem *)i->nextSibling()){
		if(!i){
			
			return true;
		}
		if ( progress->wasCancelled() )
			return false;

		if(i->childCount() > 0){
			if(!persistRow(i, file))
				return false;

		}
		i->persist(progress, file);
	}
	return true;
}
//========================
bool FakeFoldersListView::loadFile(KConfig *file){
	file->setGroup("CD Bake Oven - CD File List");	
	top->setText(0, file->readEntry("Name of CD", top->text(0)));
	unsigned long size = file->readUnsignedLongNumEntry("Total Size");
	
	progress = new QProgressDialog( i18n("Loading file mappings, please wait..."),
			i18n("&Cancel"), (int)size / 1000,
			this, "progress", TRUE );

	progress->setCaption( i18n("Please wait..."));
	progress->setProgress(1 / 1000);
	
	file->setGroup("top");
	QStringList list = file->readListEntry("Entries", ';');
	
	top->load(progress, &list);
	
	list = file->readListEntry("Children", ';');
	if(list.count() > 0){
		bool immutable = false;
		QString buff = "";
		FakeFolderItem *item;
		QStringList list2;
		for(int i = 0; i < (int)list.count() ; i++){
			file->setGroup(list[i]);
			buff = file->readEntry("Name", "");
			if(file->readEntry("Immutable", "false") == "true")
				immutable = true;
			else
				immutable = false;
			item = new FakeFolderItem(top, buff, immutable);
			list2 = file->readListEntry("Entries", ';');
			item->load(progress, &list2);
			
			list2 = file->readListEntry("Children", ';');
			if(list2.count() > 0){
				if(!loadRow(item, file, &list2)){
					delete progress;
					return false;
				}
			}
		}
	}
	progress->setProgress( (int)(top->getSize()/1000));
	slotSelectFile(top);
	resetSize();
	delete progress;
	return true;
}
//============================================
bool FakeFoldersListView::loadRow(FakeFolderItem *item, KConfig *file, QStringList *list){
	bool immutable = false;
	QString buff = "";
	FakeFolderItem *newItem;
	QStringList list2;
	for(int i = 0; i < (int)list->count() ; i++){
		if ( progress->wasCancelled() )
			return false;
			
		file->setGroup((*list)[i]);
		buff = file->readEntry("Name", "");
		if(file->readEntry("Immutable", "false") == "true")
			immutable = true;
		else
			immutable = false;
		newItem = new FakeFolderItem(item, buff, immutable);
		list2 = file->readListEntry("Entries", ';');
		newItem->load(progress, &list2);
		
		list2 = file->readListEntry("Children", ';');
		if(list2.count() > 0){
			if(!loadRow(newItem, file, &list2)){
				return false;
			}
		}
	}
	return true;
}
