#include "player.h"

#include <noatunplaylist.h>
#include "engine.h"
#include "noatunapp.h"
#include <klibloader.h>
#include <knotifyclient.h>
#include <klocale.h>
#include <qfile.h>

enum ArtsPOS { posIdle=0, posPlaying, posPaused };

Player::Player(QObject *parent) : QObject(parent),
	position(0), mLoopStyle(None), firstTimeout(true), mCurrent(0), mDeleteMe(false)
{
	mEngine=new Engine;
	connect(&filePos, SIGNAL(timeout()), SLOT(posTimeout()));
	handleButtons();
	showingInterfaces = true;
}

Player::~Player()
{
	delete mEngine;
}

bool Player::isPlaying()
{
	return mEngine->state()==posPlaying;
}

bool Player::isPaused()
{
	return mEngine->state()==posPaused;
}

bool Player::isStopped()
{
	return mEngine->state()==posIdle;
}

void Player::toggleListView()
{
	napp->playlist()->toggleList();
}

void Player::handleButtons()
{
	switch (mEngine->state())
	{
	case (posPlaying):
		emit playing();
		break;
	case (posPaused):
		emit paused();
		break;
	case (posIdle):
		emit stopped();
	}
}

void Player::back()
{
	if (napp->playlist()->previous())
		play();
}

void Player::stop()
{
	filePos.stop();
	position=0;
	mEngine->stop();
	emit stopped();
	if (mDeleteMe)
	{
		delete mCurrent;
		mDeleteMe=false;
	}
	mCurrent=0;
}

void Player::play()
{
	bool work=false;
	firstTimeout=true;
	
	if (mEngine->state()==posPaused)
		work=mEngine->play();
	else
	{
		stop();
		if (!napp->playlist()->current())
			napp->playlist()->reset();
	
		PlayListItem *current=napp->playlist()->current();
		if (!current || (current->isDownloaded()
			 && !QFile::exists(current->file())))
			work=false;
		else
			work=mEngine->play(current);
	}
	
	if (!work)
	{
		mCurrent=0;
		removeCurrent();
		fastForward();	
	}	
	else
	{
		filePos.start(500);
		mCurrent=napp->playlist()->current();
	}
	
	handleButtons();
}

void Player::playpause()
{
	if (mEngine->state()==posPlaying)
	{
		filePos.stop();
		mEngine->pause();
		emit paused();
		handleButtons();
	}
	else
		play();
}


void Player::fastForward()
{
	stop();
	if (napp->playlist()->next())
		play();
	else if (napp->loopList())
		if (napp->playlist()->reset(), napp->playlist()->current())
			play();
}

void Player::skipTo(int mille)
{
	if (current())
		mEngine->seek(current()->fromMille(mille));
}

void Player::posTimeout()
{
	if (mEngine->state()==posIdle)
	{
		stop();
		handleButtons();
		// If you're supposed to loop the song, don't go next
		// otherwise, do go next
		if (loopStyle()==Song || napp->playlist()->next())
			play();
		else if (loopStyle()==Playlist)
		{
			napp->playlist()->reset();
			play();
		}
		else if (napp->loopList())
			napp->playlist()->reset();
		
		return;
	}
	position=mEngine->position();
	current()->setLength(mEngine->length());
	
	if (position<0)
		stop();
	position=current()->length()?position*1000/current()->length():0;
	
	if (current()->length() && firstTimeout)
	{
		int minutes=(int)(current()->length()/60);
		int seconds=current()->length()-minutes*60;
		emit newSongLen(minutes, seconds);
		firstTimeout=false;
		emit newSong();
	}
	
	emit timeout();
}

QString Player::lengthString(int _position)
{
	QString str;
	if (_position<0)
		_position=position*current()->length()/1000;
	
	{ // get the position
		int minutes=(int)(_position/60);
		int secs=_position-minutes*60;
	
		// the string has to look like '00:00/00:00'
		str.sprintf("%.2d:%.2d/", minutes, secs);
	}
	
	{ // get the length
		int minutes=(int)(current()->length()/60);
		int secs=current()->length()-minutes*60;
	
		// the string has to look like '00:00/00:00'
		QString string;
		string.sprintf("%.2d:%.2d", minutes, secs);
		str+=string;
	}

	return str;
}

void Player::openFile(const KURL &f, bool purge, bool autoplay)
{
	if (purge)
		napp->playlist()->clear();
	napp->playlist()->addFile(f, autoplay);
}

void Player::loop()
{
	mLoopStyle++;
	if (mLoopStyle>Playlist)
		mLoopStyle=None;
	emit loopTypeChange(mLoopStyle);
}
void Player::loop(int i)
{
	mLoopStyle=i;
	emit loopTypeChange(mLoopStyle);
}

void Player::removeCurrent()
{
	if (napp->playlist()->current())
		napp->playlist()->remove(napp->playlist()->current());
}

void Player::playCurrent()
{
	stop();
	play();

}

void Player::newCurrent()
{
	if (!napp->playlist())
		return; // no playlist yet
	if ((mEngine->state()!=posPlaying) && napp->autoPlay())
		playCurrent();
	
}

void Player::setVolume(int v)
{
	if (v<0) v=0;
	if (v>100) v=100;
	mEngine->setVolume(v);
	emit timeout();
}

int Player::volume() const
{
	return mEngine->volume();
}

void Player::toggleInterfaces()
{
	showingInterfaces ^= true;

	if(showingInterfaces)
		emit showYourself();
	else
		emit hideYourself();
}

void Player::showInterfaces()
{
	showingInterfaces = true;
	emit showYourself();
}

void Player::hideInterfaces()
{
	showingInterfaces = false;
	emit hideYourself();
}

#include "player.moc"

