/**
 * Copyright (c) 2000-2004 Charles Samuels <charles@kde.org>
 *               2000-2001 Neil Stevens <neil@qualityassistant.com>
 *
 * Copyright (c) from the patches of:
 *               2001 Klas Kalass <klas.kalass@gmx.de>
 *               2001 Anno v. Heimburg <doktor.dos@gmx.de>
 **/


// Abandon All Hope, Ye Who Enter Here

#include <tqdragobject.h>
#include <tqheader.h>
#include <tqlayout.h>
#include <tqmap.h>
#include <tqregexp.h>
#include <tqtextstream.h>
#include <tqpainter.h>

#include <tdeaction.h>
#include <kdebug.h>
#include <tdefiledialog.h>
#include <tdefileitem.h>
#include <tdeio/job.h>
#include <tdeio/netaccess.h>
#include <tdelocale.h>
#include <tdemenubar.h>
#include <ksimpleconfig.h>
#include <kstandarddirs.h>
#include <kstdaction.h>
#include <kedittoolbar.h>
#include <kurldrag.h>
#include <tdemessagebox.h>

#include <noatun/app.h>
#include <noatun/player.h>
#include <noatun/playlistsaver.h>

#include "playlist.h"
#include "view.h"
#include "find.h"

#define SPL SplitPlaylist::SPL()

SafeListViewItem::SafeListViewItem(TQListView *parent, TQListViewItem *after, const KURL &text)
	: TQCheckListItem(parent,0, TQCheckListItem::CheckBox), PlaylistItemData(), removed(false)
{
	addRef();
	setUrl(text);

	static_cast<TDEListView*>(TQT_TQWIDGET(parent))->moveItem(this, 0, after);
	setOn(true);

	// is this really needed, it makes the listview too wide for me :(
//	setText(0,text.filename());

	//	if (!isDownloaded()) setText(1, "0%");

//	mProperties.setAutoDelete(true);

	if (!streamable() && enqueue(url()))
		setUrl(KURL(localFilename()));

	PlaylistItemData::added();
}

SafeListViewItem::SafeListViewItem(TQListView *parent, TQListViewItem *after, const TQMap<TQString,TQString> &props)
	: TQCheckListItem(parent, 0, TQCheckListItem::CheckBox), removed(false)
{
	addRef();

	setOn(true);

	// A version of setProperty that assumes a key is unique,
	// and doesn't call modified for every new key.
	// Ugly, but this function is a very hot path on playlist loading
	for (TQMap<TQString,TQString>::ConstIterator i=props.begin(); i!=props.end(); ++i )
	{
		TQString n = i.key();
		TQString val = i.data();

		if (n=="enabled")
		{
			setOn(val!="false" && val!="0");
		}
		else
		{
			Property p={n,val};
			mProperties += p;
		}
	}

	static_cast<TDEListView*>(TQT_TQWIDGET(parent))->moveItem(this, 0, after);
	modified();

	if (!streamable() && enqueue(url()))
	{
		KURL u;
		u.setPath(localFilename());

		setUrl(u);
	}
	PlaylistItemData::added();
}

SafeListViewItem::~SafeListViewItem()
{
	remove();
}

TQString SafeListViewItem::file() const
{
	return localFilename();
}

static void pad(TQString &str)
{
	int len=str.length();
	int at = 0;
	int blocklen=0;

	static const int paddingsize=12;

	// not static for reason
	const TQChar chars[paddingsize] =
	{
		TQChar('0'), TQChar('0'), TQChar('0'), TQChar('0'),
		TQChar('0'), TQChar('0'), TQChar('0'), TQChar('0'),
		TQChar('0'), TQChar('0'), TQChar('0'), TQChar('0')
	};

	for (int i=0; i < len; i++)
	{
		if (str[i].isNumber())
		{
			if (!blocklen)
				at = i;
			blocklen++;
		}
		else if (blocklen)
		{
			int pads=paddingsize;
			pads -= blocklen;
			str.insert(at, chars, pads);
			i += pads;
			blocklen = 0;
		}
	}
	if (blocklen)
	{
		int pads=paddingsize;
		pads -= blocklen;
		str.insert(at, chars, pads);
	}
}

int SafeListViewItem::compare(TQListViewItem * i, int col, bool) const
{
	TQString text1 = text(col);
	TQString text2 = i->text(col);

	pad(text1);
	pad(text2);
	return text1.compare(text2);
}

TQString SafeListViewItem::property(const TQString &n, const TQString &def) const
{
	for (TQValueList<Property>::ConstIterator i=mProperties.begin(); i != mProperties.end(); ++i)
	{
		if ((*i).key==n)
			return (*i).value;
	}
	if (n=="enabled")
	{
		if (isOn()) return "true";
		else return "false";
	}
	return def;
}

void SafeListViewItem::setProperty(const TQString &n, const TQString &val)
{
	if (n=="enabled")
	{
		setOn(val!="false" && val!="0");
	}
	else
	{
		if ( property(n,"") == val )
		{
//			kdDebug(66666) << "SafeListViewItem::setProperty(), property unchanged!" << endl;
			return;
		}

		clearProperty(n);
		Property p={n,val};
		mProperties += p;
	}
	modified();
}

void SafeListViewItem::clearProperty(const TQString &n)
{
	if (n=="enabled")
	{
		setOn(true);
		modified();
		return;
	}

	for (TQValueList<Property>::Iterator i=mProperties.begin(); i != mProperties.end(); ++i)
	{
		if ((*i).key==n)
		{
			mProperties.remove(i);
			modified();
			break;
		}
	}
}

TQStringList SafeListViewItem::properties() const
{
	TQStringList list;
	for (TQValueList<Property>::ConstIterator i=mProperties.begin(); i != mProperties.end(); ++i)
		list += (*i).key;
	list += "enabled";
	return list;
}

bool SafeListViewItem::isProperty(const TQString &n) const
{
	for (TQValueList<Property>::ConstIterator i=mProperties.begin(); i != mProperties.end(); ++i)
	{
		if ((*i).key==n)
			return true;
	}
	return n=="enabled";
}

void SafeListViewItem::downloaded(int percent)
{
	if (!removed)
		setText(1, TQString::number(percent)+'%');
}

void SafeListViewItem::downloadTimeout()
{
	if (!removed)
		setText(1, "-");
}

void SafeListViewItem::downloadFinished()
{
	if (!removed)
		setText(1, "");
}

void SafeListViewItem::modified()
{
	bool widthChangeNeeded = false;

	if (text(0)!=title())
	{
		setText(0, title());
		widthChangeNeeded = true;
	}

	if (isDownloaded() && length()!=-1 && text(1)!=lengthString())
	{
		setText(1, lengthString());
		widthChangeNeeded = true;
	}

	if (widthChangeNeeded)
		widthChanged(-1);

	PlaylistItemData::modified();
}

void SafeListViewItem::stateChange(bool s)
{
	// if you uncheck this, uncheck thet others that
	// are selected too

	TQPtrList<TQListViewItem> list=SPL->view->listView()->selectedItems();

	// but not if I'm not selected
	if (list.containsRef(this))
		for (TQListViewItem *i=list.first(); i != 0; i=list.next())
			static_cast<TQCheckListItem*>(i)->setOn(s);
	else
		TQCheckListItem::stateChange(s);
}

void SafeListViewItem::paintCell(TQPainter *p, const TQColorGroup &cg, int column, int width, int align)
{
	TQCheckListItem::paintCell(p, cg, column, width, align);

	if (SPL->current() == this)
	{
		p->save();
		p->setRasterOp(XorROP);
		p->fillRect(0, 0, width, height(), TQColor(255,255,255));

		p->restore();
	}
}

void SafeListViewItem::remove()
{
	removed=true;
	if (napp->player()->current()==this && !itemAbove() && !itemBelow())
	{
		napp->player()->stop();
		SPL->setCurrent(0);
	}
	else if (napp->player()->current()==this)
	{
//		SPL->setCurrent(0);
//		napp->player()->playCurrent();

		if (napp->player()->isPlaying() && !SPL->exiting())
			napp->player()->forward();
		else
			SPL->setCurrent(0);
	}

	if (listView())
	{
		if (SPL->currentItem==this) // just optimizing for least unreadably
			SPL->setCurrent(static_cast<SafeListViewItem*>(itemBelow()));

		listView()->takeItem(this);
	}
	else if (SPL->currentItem==this)
	{
		SPL->setCurrent(0);
	}

	dequeue();
	PlaylistItemData::removed();
}

List::List(View *parent)
	: TDEListView(parent), recursiveAddAfter(0), listJob(0)
{
	addColumn(i18n("File"));
	addColumn(i18n("Time"));
	setAcceptDrops(true);
	setSorting(-1);
	setDropVisualizer(true);
	setDragEnabled(true);
	setItemsMovable(true);
	setSelectionMode(TQListView::Extended);
	connect(TQT_TQOBJECT(this), TQT_SIGNAL(dropped(TQDropEvent*, TQListViewItem*)), TQT_SLOT(dropEvent(TQDropEvent*, TQListViewItem*)));
	connect(TQT_TQOBJECT(this), TQT_SIGNAL(moved()), TQT_SLOT(move()));
	connect(TQT_TQOBJECT(this), TQT_SIGNAL(aboutToMove()), parent, TQT_SLOT(setNoSorting()));
	connect(TQT_TQOBJECT(this), TQT_SIGNAL(deleteCurrentItem()), parent, TQT_SLOT(deleteSelected()));
}

List::~List()
{
}

void List::move()
{
	emit modified();
}

bool List::acceptDrag(TQDropEvent *event) const
{
	return KURLDrag::canDecode(event) || TDEListView::acceptDrag(event);
}

void List::dropEvent(TQDropEvent *event, TQListViewItem *after)
{
	static_cast<View*>(TQT_TQWIDGET(parent()))->setNoSorting();
	KURL::List textlist;
	if (!KURLDrag::decode(event, textlist)) return;
	event->acceptAction();

	for (KURL::List::Iterator i=textlist.begin(); i != textlist.end(); ++i)
	{
		after= addFile(*i, false, after);
	}

	emit modified();
}

void List::keyPressEvent(TQKeyEvent *e)
{
	if (e->key()==Key_Enter || e->key()==Key_Return)
	{
		if (currentItem())
		{
			emit TDEListView::executed(currentItem());
		}

		return;
	}

	if (e->key()==Key_Delete)
	{
		if (currentItem())
		{
			emit deleteCurrentItem();
		}

		return;
	}

	TDEListView::keyPressEvent(e);


}

/**
 * use this only once!!!
 **/
class NoatunSaver : public PlaylistSaver
{
	List *mList;
	SafeListViewItem *after, *mFirst;
public:
	NoatunSaver(List *l, TQListViewItem *after=0)
		: mList(l)
	{
		this->after = static_cast<SafeListViewItem*>(after);
		mFirst = 0;
	}

	TQListViewItem *getAfter() { return after; }
	TQListViewItem *getFirst() { return mFirst; }

protected:
	virtual void readItem(const TQMap<TQString,TQString> &properties)
	{
		after = new SafeListViewItem(mList, after, properties);
		if (mFirst==0)
			mFirst = after;
	}

	virtual PlaylistItem writeItem()
	{
		if (!after)
		{
			after=static_cast<SafeListViewItem*>(mList->firstChild());
		}
		else
		{
			after=static_cast<SafeListViewItem*>(static_cast<SafeListViewItem*>(after)->nextSibling());
		}
		return PlaylistItem(after);
	}
};


bool View::saveToURL(const KURL &url)
{
	NoatunSaver saver(list);
	if(saver.save(url))
	{
		return true;
	}
	else
	{
		KMessageBox::error( this, i18n("Could not write to %1.").arg(url.prettyURL()) );
		return false;
	}
}

void View::exportTo(const KURL &url)
{
	TQString local(napp->tempSaveName(url.path()));
	TQFile saver(local);
	saver.open(IO_ReadWrite | IO_Truncate);
	TQTextStream t(&saver);
	// navigate the list
	for (SafeListViewItem *i=static_cast<SafeListViewItem*>(listView()->firstChild());
	     i != 0; i=static_cast<SafeListViewItem*>(i->itemBelow()))
	{
		KURL u=i->url();
		if (u.isLocalFile())
			t<< u.path() << '\n';
		else
			t << u.url() << '\n';
	}
	saver.close();

	TDEIO::NetAccess::upload(local, url, this);

	saver.remove();
}

TQListViewItem *List::openGlobal(const KURL &u, TQListViewItem *after)
{
	clear();
	NoatunSaver saver(this, after);
	saver.metalist(u);

	return saver.getAfter();
}

// for m3u files
TQListViewItem *List::importGlobal(const KURL &u, TQListViewItem *after)
{
	NoatunSaver saver(this, after);
	if (!saver.metalist(u))
	{
		after=new SafeListViewItem(this, after, u);
//		SPL->listItemSelected(after);
		return after;
	}

	// return the first item added from this playlist
	// that way noatun can start playing the first item
	if (saver.getFirst())
		return saver.getFirst();

	// failsafe in case nothing was added, getFirst() may return 0
	return saver.getAfter();
}

TQListViewItem *List::addFile(const KURL& url, bool play, TQListViewItem *after)
{
	// when a new item is added, we don't want to sort anymore
	SPL->view->setNoSorting();

	if (
			url.path().right(4).lower()==".m3u"
			|| url.path().right(4).lower()==".pls"
			|| url.protocol().lower()=="http"
		)
	{
		// a playlist is requested
		TQListViewItem *i = importGlobal(url, after);
		if (play)
			SPL->listItemSelected(i);
		return i;
	}
	else
	{
		if (!after) after=lastItem();
		KFileItem fileItem(KFileItem::Unknown,KFileItem::Unknown,url);
		if (fileItem.isDir())
		{
			addDirectoryRecursive(url, after);
			return after; // don't (and can't) know better!?
		}
		else
		{
			TQListViewItem *i = new SafeListViewItem(this, after, url);
			if (play)
				SPL->listItemSelected(i);
			return i;
		}
	}
}

// starts a new listJob if there is no active but work to do
void List::addNextPendingDirectory()
{
	KURL::List::Iterator pendingIt= pendingAddDirectories.begin();
	if (!listJob &&	(pendingIt!= pendingAddDirectories.end()))
	{
		currentJobURL= *pendingIt;
		listJob= TDEIO::listRecursive(currentJobURL, false,false);
		connect(
				listJob, TQT_SIGNAL(entries(TDEIO::Job*, const TDEIO::UDSEntryList&)),
				TQT_SLOT(slotEntries(TDEIO::Job*, const TDEIO::UDSEntryList&))
			);
		connect(
				listJob, TQT_SIGNAL(result(TDEIO::Job *)),
				TQT_SLOT(slotResult(TDEIO::Job *))
			);
		connect(
				listJob, TQT_SIGNAL(redirection(TDEIO::Job *, const KURL &)),
				TQT_SLOT(slotRedirection(TDEIO::Job *, const KURL &))
			);
		pendingAddDirectories.remove(pendingIt);
	}
}

void List::addDirectoryRecursive(const KURL &dir, TQListViewItem *after)
{
	if (!after) after=lastItem();
	recursiveAddAfter= after;
	pendingAddDirectories.append(dir);
	addNextPendingDirectory();
}

void List::slotResult(TDEIO::Job *job)
{
	listJob= 0;
	if (job && job->error())
		job->showErrorDialog();
	addNextPendingDirectory();
}

void List::slotEntries(TDEIO::Job *, const TDEIO::UDSEntryList &entries)
{
	TQMap<TQString,KURL> __list; // temp list to sort entries

	TDEIO::UDSEntryListConstIterator it = entries.begin();
	TDEIO::UDSEntryListConstIterator end = entries.end();

	for (; it != end; ++it)
	{
		KFileItem file(*it, currentJobURL, false /* no mimetype detection */, true);
		// "prudhomm:
		// insert the path + url in the map to sort automatically by path
		// note also that you use audiocd to rip your CDs then it will be sorted the right way
		// now it is an easy fix to have a nice sort BUT it is not the best
		// we should sort based on the tracknumber"
		// - copied over from old kdirlister hack <hans_meine@gmx.de>
		if (!file.isDir())
			__list.insert(file.url().path(), file.url());
	}
	TQMap<TQString,KURL>::Iterator __it;
	for( __it = __list.begin(); __it != __list.end(); ++__it )
	{
		recursiveAddAfter= addFile(__it.data(), false, recursiveAddAfter);
	}
}

void List::slotRedirection(TDEIO::Job *, const KURL & url)
{
	currentJobURL= url;
}

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

View::View(SplitPlaylist *)
	: TDEMainWindow(0, "NoatunSplitplaylistView")
{
	list=new List(this);
	setCentralWidget(list);
	connect(list, TQT_SIGNAL(modified(void)), TQT_TQOBJECT(this), TQT_SLOT(setModified(void)) );
	// connect the click on the header with sorting
	connect(list->header(),TQT_SIGNAL(clicked(int)),this,TQT_SLOT(headerClicked(int)) );

	mOpen=new TDEAction(i18n("Add &Files..."), "queue", 0, TQT_TQOBJECT(this), TQT_SLOT(addFiles()), actionCollection(), "add_files");
	(void) new TDEAction(i18n("Add Fol&ders..."), "folder", 0, TQT_TQOBJECT(this), TQT_SLOT(addDirectory()),  actionCollection(), "add_dir");
	mDelete=new TDEAction(i18n("Delete"), "edit-delete", Key_Delete, TQT_TQOBJECT(this), TQT_SLOT(deleteSelected()),  actionCollection(), "delete");

	mClose=KStdAction::close(TQT_TQOBJECT(this), TQT_SLOT(close()), actionCollection());
	mFind=KStdAction::find(TQT_TQOBJECT(this), TQT_SLOT(find()), actionCollection());

	(void) KStdAction::configureToolbars(TQT_TQOBJECT(this), TQT_SLOT(configureToolBars()), actionCollection());
	mOpenNew=KStdAction::openNew(TQT_TQOBJECT(this), TQT_SLOT(openNew()), actionCollection());
	mOpenpl=KStdAction::open(TQT_TQOBJECT(this), TQT_SLOT(open()), actionCollection());
	mSave=KStdAction::save(TQT_TQOBJECT(this), TQT_SLOT(save()), actionCollection());
	mSaveAs=KStdAction::saveAs(TQT_TQOBJECT(this), TQT_SLOT(saveAs()), actionCollection());

	(void) new TDEAction(i18n("Shuffle"), "misc", 0, TQT_TQOBJECT(SPL), TQT_SLOT( randomize() ), actionCollection(), "shuffle");
	(void) new TDEAction(i18n("Clear"), "edit-clear", 0, TQT_TQOBJECT(list), TQT_SLOT( clear() ), actionCollection(), "clear");

	createGUI("splui.rc");

	mFinder = new Finder(this);

	applyMainWindowSettings(TDEGlobal::config(), "SPL Window");
	list->setFocus();
}

void View::find()
{
	mFinder->show();
	connect(mFinder, TQT_SIGNAL(search(Finder*)), TQT_SLOT(findIt(Finder*)));
}

static bool testWord(TQListViewItem *i, const TQString &finder)
{
	PlaylistItemData *item=static_cast<SafeListViewItem*>(i);
	if (item->title().find(finder, 0, false) >=0)
		return true;
	if (item->file().find(finder, 0, false) >=0)
		return true;
	if (item->url().path().find(finder.local8Bit().data(), 0, false) >=0)
		return true;
	if (item->lengthString().find(finder, 0, false) >=0)
		return true;
	if (item->mimetype().find(finder.local8Bit().data(), 0, false) >=0)
		return true;
	return false;
}

static bool testWord(TQListViewItem *i, const TQRegExp &finder)
{
	PlaylistItemData *item=static_cast<SafeListViewItem*>(i);
	if (item->title().find(finder) >=0)
		return true;
	if (item->file().find(finder) >=0)
		return true;
	if (item->url().path().find(finder) >=0)
		return true;
	if (item->lengthString().find(finder) >=0)
		return true;
	if (item->mimetype().find(finder) >=0)
		return true;
	return false;
}

void View::findIt(Finder *f)
{
	TQListViewItem *search=list->currentItem();

	if (list->currentItem())
	{
		if (f->isForward())
			search=list->currentItem()->itemBelow();
		else
			search=list->currentItem()->itemAbove();
	}
	else
	{
		if (f->isForward())
			search=list->firstChild();
		else
			search=list->lastChild();
	}


	while (search)
	{
		if (f->regexp())
		{
			if (testWord(search, TQRegExp(f->string(), false)))
				break;
		}
		else
		{
			if (testWord(search, f->string()))
				break;
		}

		if (f->isForward())
			search=search->itemBelow();
		else
			search=search->itemAbove();

		if (!search)
		{
			if (f->isForward())
			{
				if (KMessageBox::questionYesNo(this, i18n("End of playlist reached. Continue searching from beginning?"),TQString(),KStdGuiItem::cont(),KStdGuiItem::cancel()) == KMessageBox::Yes)
					search=list->firstChild();
			}
			else
			{
				if (KMessageBox::questionYesNo(this, i18n("Beginning of playlist reached. Continue searching from end?"),TQString(),KStdGuiItem::cont(),KStdGuiItem::cancel()) == KMessageBox::Yes)
					search=list->lastChild();
			}
		}
	}

	if (search)
	{
		{ // select none
			TQPtrList<TQListViewItem> sel=list->selectedItems();
			for (TQListViewItem *i=sel.first(); i!=0; i=sel.next())
				list->setSelected(i, false);
		}
		list->setSelected(search, true);
		list->setCurrentItem(search);
		list->ensureItemVisible(search);
	}
}

View::~View()
{
	napp->player()->stop();
	hide();
	saveState();
	delete list;
}

void View::init()
{
	// see if we are importing an old-style list
	bool importing= ! TQFile(napp->dirs()->saveLocation("data", "noatun/") + "splitplaylist.xml").exists();

	if (importing)
	{
		KURL internalURL;
		internalURL.setPath(napp->dirs()->saveLocation("data", "noatun/") + "splitplaylistdata");
		NoatunSaver saver(list, 0);
		saver.load(internalURL, PlaylistSaver::M3U);
	}
	else
	{
		KURL internalURL;
		internalURL.setPath(napp->dirs()->saveLocation("data", "noatun/") + "splitplaylist.xml");
		list->openGlobal(internalURL);
	}

	TDEConfig &config = *TDEGlobal::config();
	config.setGroup("splitplaylist");

	// this has to come after openGlobal, since openGlobal emits modified()
	setModified(config.readBoolEntry("modified", false));
	TQString path = config.readPathEntry("file");
	// don't call setPath with an empty path, that would make the url "valid"
	if ( !path.isEmpty() )
		mPlaylistFile.setPath(path);

	SPL->reset();
	int saved = config.readNumEntry("current", 0);

	PlaylistItem item=SPL->getFirst();
	for(int i = 0 ; i < saved ; i++)
	{
		item=SPL->getAfter(item);
	}
	if (item)
		SPL->setCurrent(item);
}

void View::save()
{
	if(mPlaylistFile.isEmpty() || !mPlaylistFile.isValid())
	{
		saveAs();
		return;
	}

	if(saveToURL(mPlaylistFile))
		setModified(false);
}

void View::saveAs()
{
	KURL u=KFileDialog::getSaveURL(0, "*.xml splitplaylistdata *.pls *.m3u\n*", this, i18n("Save Playlist"));
	if(!u.isValid())
		return;
	mPlaylistFile = u;
	save();
}

void View::open()
{
	KURL u=KFileDialog::getOpenURL(0, "*.xml splitplaylistdata *.pls *.m3u\n*", this, i18n("Open Playlist"));
	if(!u.isValid())
		return;
	mPlaylistFile = u;
	list->openGlobal(u);
	setModified(false);
}

void View::openNew()
{
	mPlaylistFile = "";
	listView()->clear();
}

void List::clear()
{
	SPL->setCurrent(0);

	TQListView::clear();
}

void View::deleteSelected()
{
	TQPtrList<TQListViewItem> items(list->selectedItems());

	bool stopped=false;
	// noatun shouldn't play files for now
	TQListViewItem *afterLast=0;

	for (TQPtrListIterator<TQListViewItem> it(items); it.current(); ++it)
	{
		SafeListViewItem *i = static_cast<SafeListViewItem*>(*it);
		if (!stopped && SPL->current() == i)
		{
			napp->player()->stop();
			SPL->setCurrent(0);
			stopped = true;
		}
		i->remove();

		afterLast = i->itemBelow();
	}

	if (stopped)
		SPL->setCurrent(static_cast<SafeListViewItem*>(afterLast));

	setModified(true);
}

void View::addFiles()
{
	KURL::List files=KFileDialog::getOpenURLs(":mediadir", napp->mimeTypes(), this, i18n("Select File to Play"));

	TQListViewItem *last = list->lastItem();
	for(KURL::List::Iterator it=files.begin(); it!=files.end(); ++it)
		last = addFile(KURL(*it), false);

	setModified(true);
}

void View::addDirectory()
{
	TQString file=KFileDialog::getExistingDirectory(0, this, i18n("Select Folder"));

	if (!file) return;
	KURL url;
	url.setPath(file);
	list->addDirectoryRecursive(url);

	setModified(true);
}

void View::closeEvent(TQCloseEvent*)
{
	hide();
}

void View::showEvent(TQShowEvent *)
{
	emit shown();
}

void View::hideEvent(TQHideEvent *)
{
	emit hidden();
}

void View::setModified(bool b)
{
	modified = b;
	setCaption(i18n("Playlist"), modified);
}

void View::setModified(void)
{
	setModified(true);
}

void View::saveState(void)
{
	TDEConfig &config = *TDEGlobal::config();
	config.setGroup("splitplaylist");

	config.writeEntry("modified", modified);
	config.writePathEntry("file", mPlaylistFile.path());
	saveToURL(napp->dirs()->saveLocation("data", "noatun/") + "splitplaylist.xml");

	unsigned int i;
	PlaylistItem item=SPL->getFirst();
	for(i = 0; item && item != SPL->current(); )
		item=SPL->getAfter(item), i++;

	config.writeEntry("current", i);
	saveMainWindowSettings(TDEGlobal::config(), "SPL Window");

	config.sync();
}

void View::configureToolBars()
{
	saveMainWindowSettings(TDEGlobal::config(), "SPL Window");
	KEditToolbar dlg(actionCollection(), "splui.rc");
	connect(&dlg, TQT_SIGNAL(newToolbarConfig()), TQT_SLOT(newToolBarConfig()));
	dlg.exec();
}

void View::newToolBarConfig()
{
	createGUI("splui.rc");
	applyMainWindowSettings(TDEGlobal::config(), "SPL Window");
}

// turns the sorting on or off
void View::setSorting(bool on, int column)
{
	if (on)
	{
		list->setSorting(column,true);
		list->setShowSortIndicator(true);
	}
	else
	{
		list->setShowSortIndicator(false);
		list->setSorting(-1);
	}
}

void View::headerClicked(int column)
{
	// this is to avoid that if we already have it sorted,
	// we sort it again ascendingly this way, clicking on
	// the header a second time will correctly toggle
	// ascending/descending sort
	if (list->showSortIndicator())
	{
		return;
	}
	else
	{
		setSorting(true,column);
	}
}

#include "view.moc"

