/*
 * Copyright (C) 2001 Rik Hemsley (rikkus) <rik@kde.org>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.	IN NO EVENT SHALL THE
 * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 */

#include <noatun/scrollinglabel.h>
#include "userinterface.h"
#include <noatun/app.h>
#include <noatun/player.h>
#include <noatun/controls.h>
#include <noatun/effects.h>

#include <tqaccel.h>
#include <tqtoolbutton.h>
#include <tqdragobject.h>
#include <tqlayout.h>
#include <tqtooltip.h>
#include <tqframe.h>
#include <kurldrag.h>
#include <kstatusbar.h>
#include <tdeglobal.h>
#include <tdeconfig.h>
#include <tdelocale.h>
#include <kurldrag.h>
#include <kiconloader.h>
#include <noatun/playlist.h>
#include <noatun/stdaction.h>

#include "configmodule.h"
#include "pixmaps.h"
#include "seeker.h"

Charlatan::Charlatan()
	: TQWidget									(0, "Charlatan"),
		UserInterface						(),
		previousButton_					(0L),
		stopButton_							(0L),
		playButton_							(0L),
		nextButton_							(0L),
		playListToggleButton_		(0L),
		restartButton_					(0L),
		seekSlider_							(0L),
		titleLabel_							(0L),
		positionLabel_					(0L),
		showingVolumeTimer_			(0L),
		title_									("c.h.a.r.l.a.t.a.n")
{
	setAcceptDrops(true);

	showingVolumeTimer_ 	= new TQTimer(this);

	connect
		(
			showingVolumeTimer_,
			TQ_SIGNAL(timeout()),
			TQ_SLOT(slotStopShowingVolume())
		);

	playListToggleButton_	= new TQToolButton(this);
	previousButton_				= new TQToolButton(this);
	nextButton_						= new TQToolButton(this);
	stopButton_						= new TQToolButton(this);
	restartButton_				= new TQToolButton(this);
	playButton_						= new TQToolButton(this);

	seekSlider_						= new Seeker(this);
	positionLabel_				= new TQLabel(this);

	titleLabel_						= new ScrollingLabel(i18n("No File Loaded"), this);

	playListToggleButton_	->setPixmap(TQPixmap((const char **)px_playlist));
	previousButton_				->setPixmap(TQPixmap((const char **)px_previous));
	nextButton_						->setPixmap(TQPixmap((const char **)px_next));
	stopButton_						->setPixmap(TQPixmap((const char **)px_stop));
	restartButton_				->setPixmap(TQPixmap((const char **)px_restart));
	playButton_						->setPixmap(TQPixmap((const char **)px_play1));

	playListToggleButton_	->setToggleButton(true);

	TQVBoxLayout * mainLayout		= new TQVBoxLayout(this);

	mainLayout->addWidget(titleLabel_);

  mainLayout->addSpacing(2);

	TQHBoxLayout * positionLayout = new TQHBoxLayout(mainLayout);

	positionLayout->addWidget(seekSlider_);
  positionLayout->addSpacing(2);
	positionLayout->addWidget(positionLabel_);

  mainLayout->addSpacing(2);

	TQHBoxLayout * buttonLayout	= new TQHBoxLayout(mainLayout);

	buttonLayout->addWidget(playListToggleButton_);
	buttonLayout->addWidget(previousButton_);
	buttonLayout->addWidget(nextButton_);
	buttonLayout->addWidget(stopButton_);
	buttonLayout->addWidget(restartButton_);
	buttonLayout->addWidget(playButton_);

	playListToggleButton_	->installEventFilter(this);
	previousButton_				->installEventFilter(this);
	nextButton_						->installEventFilter(this);
	stopButton_						->installEventFilter(this);
	restartButton_				->installEventFilter(this);
	playButton_						->installEventFilter(this);
	seekSlider_						->installEventFilter(this);
	positionLabel_				->installEventFilter(this);
	titleLabel_						->installEventFilter(this);

	connect
		(
		 playListToggleButton_,
		 TQ_SIGNAL(clicked()),
		 napp->player(),
		 TQ_SLOT(toggleListView())
		);

	connect
		(
		 previousButton_,
		 TQ_SIGNAL(clicked()),
		 napp->player(),
		 TQ_SLOT(back())
		);

	connect
		(
		 nextButton_,
		 TQ_SIGNAL(clicked()),
		 napp->player(),
		 TQ_SLOT(forward())
		);

	connect
		(
		 stopButton_,
		 TQ_SIGNAL(clicked()),
		 napp->player(),
		 TQ_SLOT(stop())
		);

	connect(restartButton_, TQ_SIGNAL(clicked()), TQ_SLOT(slotRestart()));

	connect
		(
		 playButton_,
		 TQ_SIGNAL(clicked()),
		 napp->player(),
		 TQ_SLOT(playpause())
		);

	connect(napp,						TQ_SIGNAL(hideYourself()), 	TQ_SLOT(hide()));
	connect(napp,						TQ_SIGNAL(showYourself()), 	TQ_SLOT(show()));

	connect(napp->player(), TQ_SIGNAL(playlistShown()),	TQ_SLOT(slotPlayListShown()));
	connect(napp->player(), TQ_SIGNAL(playlistHidden()),	TQ_SLOT(slotPlayListHidden()));
	connect(napp->player(), TQ_SIGNAL(playing()),				TQ_SLOT(slotPlaying()));
	connect(napp->player(), TQ_SIGNAL(stopped()),				TQ_SLOT(slotStopped()));
	connect(napp->player(), TQ_SIGNAL(paused()),					TQ_SLOT(slotPaused()));

	connect(napp->player(), TQ_SIGNAL(timeout()),				TQ_SLOT(slotTimeout()));

	connect
		(
		 napp->player(),
		 TQ_SIGNAL(volumeChanged(int)),
		 TQ_SLOT(slotVolumeChanged(int))
		);

	connect
		(
		 new CharlatanConfigModule(this),
		 TQ_SIGNAL(saved()),
		 TQ_SLOT(slotConfigChanged())
		);

	setCaption(i18n("Noatun"));
	setIcon(BarIcon("noatun"));

	napp->player()->handleButtons();

	loadConfig();

	// Using TQAccel, because I don't want any strings associated or
	// configurability.

	TQAccel * a = new TQAccel(this, "Accelerators");

	int accelPlay = a->insertItem(Key_Space);
	int accelNext = a->insertItem(Key_H);
	int accelPrev = a->insertItem(Key_L);
	int accelStop = a->insertItem(Key_Escape);
	int accelRstt = a->insertItem(Key_Return);
	int accelQuit = a->insertItem(Key_Q);

	a->connectItem(accelPlay, napp->player(), TQ_SLOT(playpause()));
	a->connectItem(accelNext, napp->player(), TQ_SLOT(forward()));
	a->connectItem(accelPrev, napp->player(), TQ_SLOT(back()));
	a->connectItem(accelStop, napp->player(), TQ_SLOT(stop()));
	a->connectItem(accelRstt, this, TQ_SLOT(slotRestart()));
	a->connectItem(accelQuit, napp, TQ_SLOT(quit()));

	show();

	setTitleText();
}

Charlatan::~Charlatan()
{
	// Empty.
}

void Charlatan::closeEvent(TQCloseEvent *)
{
	unload();
}

void Charlatan::dragEnterEvent(TQDragEnterEvent *event)
{
	event->accept(KURLDrag::canDecode(event));
}

void Charlatan::dropEvent(TQDropEvent *event)
{
	KURL::List uri;
	if (KURLDrag::decode(event, uri))
	{
		for (KURL::List::Iterator i = uri.begin(); i != uri.end(); ++i)
			napp->player()->openFile(*i, false);
	}

}

void Charlatan::setTitleText(const TQString & s)
{
	TQString titleText;

	if (!s.isNull())
	{
		titleText = s;
	}
	else
	{
		Player * player = napp->player();

		if (0 == player)
		{
			tqWarning("Noatun's player is null. WTF ?");
			return;
		}
		else
		{
			PlaylistItem currentItem = player->current();

			if (!!currentItem)
			{
				titleText = currentItem.title();
			}
		}
	}

	if (title_ != titleText)
	{
		showingVolumeTimer_->stop();
		title_ = titleText;

		if (!showingVolumeTimer_->isActive())
			titleLabel_->setText(title_);
	}
}

void Charlatan::slotPlaying()
{
	setTitleText();

	playButton_->setOn(true);
	stopButton_->setEnabled(true);
	playButton_->setPixmap(TQPixmap((const char **)px_pause));
}

void Charlatan::slotStopped()
{
	setTitleText(i18n("No File Loaded"));

	stopButton_->setEnabled(false);
	playButton_->setOn(false);
	playButton_->setPixmap(TQPixmap((const char **)px_play1));
}

void Charlatan::slotPaused()
{
	setTitleText();

	stopButton_->setEnabled(true);
	playButton_->setOn(false);
	playButton_->setPixmap(TQPixmap((const char **)px_play1));
}

bool Charlatan::eventFilter(TQObject *o, TQEvent *e)
{
	switch (e->type())
	{
		case TQEvent::Wheel:
			wheelEvent(static_cast<TQWheelEvent*>(e));
			return true;
			break;

		default:
			break;
	}

  return TQWidget::eventFilter(o, e);
}

void Charlatan::slotPlayListShown()
{
	playListToggleButton_->setOn(true);
}

void Charlatan::slotPlayListHidden()
{
	playListToggleButton_->setOn(false);
}

void Charlatan::mousePressEvent(TQMouseEvent * e)
{
	if (e->button() == TQt::RightButton)
	{
		NoatunStdAction::ContextMenu::showContextMenu();
		return;
	}

	return TQWidget::mousePressEvent(e);
}

void Charlatan::wheelEvent(TQWheelEvent * e)
{
	int newVolume = napp->player()->volume() + (e->delta() / 120) * 4;
	napp->player()->setVolume(newVolume);
}

void Charlatan::slotConfigChanged()
{
	loadConfig();
}

void Charlatan::slotVolumeChanged(int i)
{
	TQString message(i18n("Volume: %1").arg(i));

	showingVolumeTimer_->start(2000, true);
	titleLabel_->setText(message);
}

void Charlatan::slotStopShowingVolume()
{
	titleLabel_->setText(title_);
}

void Charlatan::slotTimeout()
{
	// noatun bug: napp->player()->lengthString() will crash if there's
	// no 'current track'.
	if (!napp->player()->current())
		return;

	setTitleText();

	TQString lengthText(napp->player()->lengthString());

	if (positionLabel_->text() != lengthText)
		positionLabel_->setText(lengthText);
}

void Charlatan::loadConfig()
{
	TDEConfig * c(TDEGlobal::config());
	c->setGroup("CharlatanInterface");
	titleLabel_->setScroll(c->readBoolEntry("ScrollTitle", true));
}

void Charlatan::slotRestart()
{
	napp->player()->skipTo(0);
}

#include "userinterface.moc"
