// Copyright (c) 2003 Charles Samuels <charles@kde.org>
// See the file COPYING for redistribution terms.

#include "oblique.h"
#include "base.h"
#include "view.h"
#include "file.h"
#include "selector.h"
#include "cmodule.h"

#include <noatun/player.h>

#include <kconfig.h>
#include <kstandarddirs.h>

#include <qtimer.h>

extern "C" Plugin *create_plugin()
{
	return new Oblique();
}



Oblique::Oblique()
	: Playlist(0, 0), mSchemaCollection("oblique/schemas")
{
	mView = 0;
	KConfigGroup g(KGlobal::config(), "oblique");

	mBase = new Base(::locate("data", "noatun/")+"/oblique-list");

	mView = new View(this);
	connect(napp->player(), SIGNAL(loopTypeChange(int)), SLOT(loopTypeChange(int)));

	mSelector = new SequentialSelector(mView->tree());

	new Configure(this);

	// psst, window's gone, pass it on!
	connect(mView, SIGNAL(listHidden()), SIGNAL(listHidden()));
	connect(mView, SIGNAL(listShown()), SIGNAL(listShown()));

	loopTypeChange(napp->player()->loopStyle());
}


Oblique::~Oblique()
{
	delete mView;
	delete mBase;
}

void Oblique::loopTypeChange(int i)
{
	PlaylistItem now = current();

	if (i == Player::Random)
	{
		if (!dynamic_cast<RandomSelector*>(mSelector))
		{
			delete mSelector;
			mSelector = new RandomSelector(mView->tree());
		}
	}
	else
	{
		delete mSelector;
		mSelector = new SequentialSelector(mView->tree());
	}
}


void Oblique::reset()
{
	mView->tree()->setCurrent(0);
	loopTypeChange(0);
}

void Oblique::clear()
{
	mBase->clear();
}

void Oblique::addFile(const KURL &url, bool play)
{
	File f = mBase->add(url.path());
	PlaylistItem p=new Item(f);
	p.data()->added();
	if (play) setCurrent(p);
}


PlaylistItem Oblique::next()
{
	return mSelector->next();
}

PlaylistItem Oblique::previous()
{
	return mSelector->previous();
}


PlaylistItem Oblique::current()
{
	return mSelector->current();
}

void Oblique::setCurrent(const PlaylistItem &item)
{
	if (!item) return;
	mSelector->setCurrent(*static_cast<Item*>(const_cast<PlaylistItemData*>(item.data())));
	emit playCurrent();
}



PlaylistItem Oblique::getFirst() const
{
	FileId first=1;
	File item = mBase->first(first);

	if (!item) return 0;

	return new Item(item);
}


PlaylistItem Oblique::getAfter(const PlaylistItem &item) const
{
	File after = mBase->first(static_cast<const Item*>(item.data())->itemFile().id()+1);
	if (!after) return 0;
	return new Item(after);
}

bool Oblique::listVisible() const
{
	return mView->isVisible();
}

void Oblique::showList()
{
	mView->show();
}

void Oblique::hideList()
{
	mView->hide();
}


void Oblique::selected(TreeItem *cur)
{
	Item *item = new Item(cur->file());
	PlaylistItem pli = item;
	setCurrent(pli);
}




Loader::Loader(Tree *tree)
	: QObject(tree)
{
	mTree = tree;
	mBase = mTree->oblique()->base();
	mDeferredLoaderAt=1;

	QTimer::singleShot(0, this, SLOT(loadItemsDeferred()));
}

void Loader::loadItemsDeferred()
{
	// do/try 16 at a time
	for (int xx=0; xx < 16; xx++)
	{
		if (mDeferredLoaderAt > mBase->high())
		{
			// finished
			mBase->resetFormatVersion();
			emit finished();
			return;
		}

		File f = mBase->find(mDeferredLoaderAt);

		if (f)
		{
			if (mBase->formatVersion() <= 0x00010001)
				f.makeCache();

			if (f.isIn(mTree->slice()))
				mTree->insert(f);
		}
		mDeferredLoaderAt++;
	}

	QTimer::singleShot(0, this, SLOT(loadItemsDeferred()));
}


#include "oblique.moc"

