/***************************************************************************
                          FakeFolderItem.cpp  -  description
                             -------------------
    begin                : Sun Dec 2 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 <qapp.h>
#include <qdir.h>
#include <qfile.h>
#include <qfileinfo.h>
#include <qpixmap.h>
#include <qlistview.h>
#include <qdatetime.h>
#include <qfileinfo.h>
#include <qprogressdialog.h>

// KDE includes
#include <kurl.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kmimetype.h>
#include <kconfig.h>
#include <krun.h>

// app includes
#include "FakeFolderItem.h"
#include "FakeFoldersListView.h"
#include "FileItem.h"


//==============================================
FakeFolderItem::FakeFolderItem(QListView * parent, QString name):QListViewItem(parent){
	top = true;
	entries.setAutoDelete(true);
	setText( 0, name );
	size = 0;
	immutable = false;
	initPermFunkArr();
}
//==============================================
FakeFolderItem::FakeFolderItem(FakeFolderItem * parent, QString name, bool immutable):
			QListViewItem(parent){
	top = false;
	entries.setAutoDelete(true);
	setText( 0, name );
	if(immutable)
		setPixmap( 0, SmallIcon("folder_green") );
	else
		setPixmap( 0, SmallIcon("folder_red") );
	size = 0;
	this->immutable = immutable;
	initPermFunkArr();
}
//======================================
FakeFolderItem::FakeFolderItem(FakeFolderItem *fakeFolderItem, FakeFolderItem *parent, QProgressDialog *progress):
				QListViewItem(parent){
	top = false;
	entries.setAutoDelete(true);
	setText( 0, fakeFolderItem->getName() );
	setPixmap( 0, SmallIcon("folder_red") );
	FileEntry *oldEntry = fakeFolderItem->getLastFileEntry();
	FileEntry *newEntry;
	int s = 0;
	while (oldEntry != 0){
		newEntry = new FileEntry;
		newEntry->path = oldEntry->path;
		newEntry->name = oldEntry->name;
		newEntry->size = oldEntry->size;
		newEntry->immutable = false;
		newEntry->visibility = oldEntry->visibility;
	
		entries.append(newEntry);
		s += oldEntry->size;
		
		oldEntry = fakeFolderItem->getPrevFileEntry();
	}
	progress->setProgress(progress->progress() + s);
	
	size = fakeFolderItem->getSize();
	immutable = false;
	initPermFunkArr();
}
//======================================
FakeFolderItem::FakeFolderItem(FakeFolderItem *fakeFolderItem, QListView *parent, QProgressDialog *progress):
				QListViewItem(parent){
	top = false;
	entries.setAutoDelete(true);
	setText( 0, fakeFolderItem->getName() );
	setPixmap( 0, SmallIcon("folder_red") );
	FileEntry *oldEntry = fakeFolderItem->getLastFileEntry();
	
	FileEntry *newEntry;
	int s = 0;
	while (oldEntry != 0){
		newEntry = new FileEntry;
		newEntry->path = oldEntry->path;
		newEntry->name = oldEntry->name;
		newEntry->size = oldEntry->size;
		newEntry->visibility = oldEntry->visibility;
	
		newEntry->immutable = false;
		entries.append(newEntry);
		s += oldEntry->size;
		
		oldEntry = fakeFolderItem->getPrevFileEntry();
	}
	progress->setProgress(progress->progress() + s);
	qApp->processEvents();
	size = fakeFolderItem->getSize();
	immutable = false;
	initPermFunkArr();
}
//====================================
FakeFolderItem::~FakeFolderItem(){
}

//=======================================
void FakeFolderItem::initPermFunkArr(){

	permFunkArr[0] = &FakeFolderItem::None_f;
	permFunkArr[1] = &FakeFolderItem::RR_f;
	permFunkArr[2] = &FakeFolderItem::Joi_f;
	permFunkArr[3] = &FakeFolderItem::RR_Joi_f;
	permFunkArr[4] = &FakeFolderItem::HFS_f;
	permFunkArr[5] = &FakeFolderItem::RR_HFS_f;
	permFunkArr[6] = &FakeFolderItem::Joi_HFS_f;
	permFunkArr[7] = &FakeFolderItem::RR_Joi_HFS_f;

}
//=======================================
void FakeFolderItem::setOpen( bool open ){
	if(!top){
		if(immutable){
			if ( open ){
  				setPixmap( 0, SmallIcon("folder_green_open") );
  			}
  			else{
  				setPixmap( 0, SmallIcon("folder_green") );
  			}
		
		}
		else{
			if ( open ){
  				setPixmap( 0, SmallIcon("folder_red_open") );
  			}
  			else{
  				setPixmap( 0, SmallIcon("folder_red") );
  			}
  		}
  	}
  	QListViewItem::setOpen( open );
  	opened = open;
}
//=======================================
QPixmap FakeFolderItem::getIcon() {
	if(top)
		return DesktopIcon("cdrom_unmount");
		
	if(immutable)
		return DesktopIcon("folder_green");
		
	return DesktopIcon("folder_red");
}
//=======================================
QPixmap FakeFolderItem::getSmallIcon() {
	if(top)
		return SmallIcon("cdrom_unmount");
		
	if(immutable)
		return SmallIcon("folder_green");
		
	return SmallIcon("folder_red");
}
//=======================================
QString FakeFolderItem::getPathToTop(){
	return ((FakeFoldersListView *)listView())->getPathToTop(this);
}
//=======================================
void FakeFolderItem::setup(){
    setExpandable( true );
    QListViewItem::setup();
}

//===========================================================
bool FakeFolderItem::readPath( QString path, bool includeHidden ){
	QDir thisDir( path ); 	
  	QStringList filesList ;
  	
  	thisDir.setSorting( QDir::Name);
		
	if(includeHidden)
		thisDir.setFilter (QDir::Hidden|QDir::Files);
	else
		thisDir.setFilter ( QDir::Files);
	
	filesList = thisDir.entryList();		

	for ( int i = 0; i < (int)filesList.count(); ++i ){
		if(!addEntry(path + "/" + filesList	[i])){
			return false;
		}
	}
	return true;
}
//=======================================
bool FakeFolderItem::addEntry(QString path){
	QFileInfo d( path );
	
	FileEntry *newEntry = new FileEntry;	
	newEntry->path = path;
	newEntry->name = d.fileName();
	newEntry->size = d.size();
	newEntry->immutable = false;
	newEntry->visibility = RR_Visible + Joi_Visible + HFS_Visible;
	
	addToSize((unsigned long)newEntry->size);

	entries.append(newEntry);
	
	return true;
}
//=======================================
void FakeFolderItem::addEntry(QString path, QString name, unsigned long size, bool immutable){
	
	FileEntry *newEntry = new FileEntry;	
	newEntry->path = path;
	newEntry->name = name;
	newEntry->size = (int)size;
	newEntry->immutable = immutable;
	newEntry->visibility = RR_Visible + Joi_Visible + HFS_Visible;
	
	addToSize(newEntry->size);
		
	entries.append(newEntry);
/*	cerr << "sizeof(*this) = " << sizeof(*this) << endl;/////////////////////////////////////////////////////////////////////////////////////////////////////////////
	cerr << "sizeof(*newItem) = " << sizeof(*newEntry) << endl;
	cerr << "sizeof(entries) = " << sizeof(entries) << endl;*/
}
//=======================================
void FakeFolderItem::addEntry(FileEntry *entry){
	
	FileEntry *newEntry = new FileEntry;	
	newEntry->path = entry->path;
	newEntry->name = entry->name;
	newEntry->size = entry->size;
	newEntry->immutable = false;
	newEntry->visibility = entry->visibility;
	
	addToSize((unsigned long)newEntry->size);
	
	
	entries.append(newEntry);
}
//=======================================
bool FakeFolderItem::removeEntry(QString name){
	FileEntry *thisEntry;
	int i;
	for (i = 0, thisEntry=entries.first(); thisEntry != 0; thisEntry=entries.next(), i++ ){
		if(thisEntry->name == name){
			if(thisEntry->immutable == true)
				return false;
			subtractFromSize(thisEntry->size);
			
			entries.remove(i);
			return true;
		}
	}
	return true;
}
//=======================================
bool FakeFolderItem::removeEntry(FileEntry *thisEntry){
	if(thisEntry->immutable == true)
		return false;
	subtractFromSize(thisEntry->size);
	entries.remove(thisEntry);
	return true;
}
//=======================================
bool FakeFolderItem::containsEntry(QString name){
	FileEntry *thisEntry;	
	for (thisEntry=entries.first(); thisEntry != 0; thisEntry=entries.next()){
		if(thisEntry->name == name)
			return true;
	}
	return hasChild(name);
	//return false;
}
//======================================
FileEntry* FakeFolderItem::getEntry(QString name){

	FileEntry *thisEntry;	
	for (thisEntry=entries.first(); thisEntry != 0; thisEntry=entries.next()){
		if(thisEntry->name == name)
			break;
	}
	return thisEntry;
}
//======================================
void FakeFolderItem::generateMappings(QProgressDialog *progress, QStringList *list){
	QString pathToTop = getPathToTop(), buff = "", buff1 = "";
	FileEntry *thisEntry;
	
	int s = 0,
		v = RR_Visible + Joi_Visible + HFS_Visible;
	
	//list->append(" '" + pathToTop + "' ");
	
	for (thisEntry=entries.first(); thisEntry != 0; thisEntry=entries.next()){
		if(!thisEntry->immutable){
			v = RR_Visible + Joi_Visible + HFS_Visible;
			if(thisEntry->visibility >= None_Visible && thisEntry->visibility <= v)
				v = thisEntry->visibility;
				
			list->prepend((*this.*permFunkArr[v])(thisEntry->path));
			buff = pathToTop + thisEntry->name;
			KRun::shellQuote(buff);
			buff1 = thisEntry->path;
			KRun::shellQuote(buff1);
			list->append(" " + buff + "=" + buff1);
		}
		s += thisEntry->size;
	}
	progress->setProgress(progress->progress() + s / 1000);
	/*								-hide-hfs 	-hide-joliet 	-hide
	if(pathToTop.length() > 47){
		int yy = pathToTop.length() - 44;
		pathToTop = pathToTop.replace(0, yy, "...");
	}
	progress->setLabelText("Processing " + pathToTop);*/
	qApp->processEvents();
}
//======================================
void FakeFolderItem::persist(QProgressDialog *progress, KConfig *file){
	QString pathToTop = getPathToTop();
	if(top)
		file->setGroup("top");
	else
		file->setGroup(pathToTop);
	
	file->writeEntry("Name", text(0));
	if(immutable)
			file->writeEntry("Immutable","true");
		else
			file->writeEntry("Immutable","false");
	
	QStringList list;
	for (FakeFolderItem *i = (FakeFolderItem *)firstChild(); ;i=(FakeFolderItem *)i->nextSibling()){
		if(!i)
			break;
		list.append(pathToTop + i->getName() + "/");
	}
	
	file->writeEntry("Children", list.join(";"));
	list.clear();
	
	FileEntry *thisEntry;
	QStringList list2;
	int s = 0;	
	for (thisEntry=entries.first(); thisEntry != 0; thisEntry=entries.next()){
		
		list.append(thisEntry->path);
		list.append(thisEntry->name);
		list.append(QString::number(thisEntry->size));
		if(thisEntry->immutable)
			list.append("true");
		else
			list.append("false");
		list.append(QString::number(thisEntry->visibility));
		list2.append(list.join("|"));
		list.clear();
		s += thisEntry->size;
	}
	file->writeEntry("Entries", list2.join(";"));
	progress->setProgress(progress->progress() + s / 1000);
	
	//progress->setLabelText("Processing " + pathToTop);
	qApp->processEvents();
}
//======================================
void FakeFolderItem::load(QProgressDialog *progress, QStringList *list){
	if(list->count() == 0)
		return;

	QStringList list2;	
	FileEntry *newEntry;
	int s = 0;
	for(int i = 0; i < (int)list->count(); i++){
		list2 = QStringList::split("|", (*list)[i], false);
		newEntry = new FileEntry;	
		newEntry->path = list2[0];
		newEntry->name = list2[1];
		newEntry->size = list2[2].toInt();
		if(list2[3] == "true")
			newEntry->immutable = true;
		else
			newEntry->immutable = false;
		newEntry->visibility = list2[4].toInt();
		
		addToSize(newEntry->size);	
		entries.append(newEntry);
		s += newEntry->size;
	}
	progress->setProgress(progress->progress() + s);
	qApp->processEvents();
}
//============================================
void FakeFolderItem::addToSize(unsigned long size) {
	this->size += size;
	if(!top)
		((FakeFolderItem *)parent())->addToSize(size);
}
//============================================
void FakeFolderItem::subtractFromSize(unsigned long size) {
	this->size -= size;
	if(!top)
		((FakeFolderItem *)parent())->subtractFromSize(size);
}
//=======================================
bool FakeFolderItem::hasChild(QString name){
	if(childCount() == 0)
		return false;
	for (FakeFolderItem *i = (FakeFolderItem *)firstChild(); ; i=(FakeFolderItem *)i->nextSibling()){
		if(!i)
			break;
		if(i->getName() == name)
			return true;
	}
	return false;
}
//=======================================
FakeFolderItem *FakeFolderItem::getChild(QString name){
	if(childCount() == 0)
		return 0;
	for (FakeFolderItem *i = (FakeFolderItem *)firstChild(); ; i=(FakeFolderItem *)i->nextSibling()){
		if(!i)
			break;
		if(i->getName() == name)
			return i;
	}
	return 0;
}
