/*
 * 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 "seeker.h"
#include "userinterface.h"
#include <noatun/app.h>
#include <noatun/player.h>
#include <noatun/controls.h>
#include <noatun/effects.h>
#include <noatun/engine.h>

#include <tqtoolbutton.h>
#include <tqdragobject.h>
#include <tqlayout.h>
#include <tqtooltip.h>
#include <tqframe.h>

#include <kstatusbar.h>
#include <tdepopupmenu.h>
#include <kurldrag.h>
#include <tdeglobal.h>
#include <tdeconfig.h>
#include <tdelocale.h>
#include <kiconloader.h>
#include <kurldrag.h>
#include <noatun/playlist.h>
#include <noatun/stdaction.h>

#include <arts/artsmodules.h>
#include <arts/reference.h>
#include <arts/soundserver.h>
#include <arts/kmedia2.h>

#include "configmodule.h"

AlsaPlayer::AlsaPlayer()
	: APMainWindow	(0, "AlsaPlayer"),
		UserInterface	(),
		speed_				(100)
{
	connect
		(
		 playlistButton,
		 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
		(
		 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(changed()),				TQ_SLOT(slotTrackChanged()));

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

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

	connect
		(
		 volumeSlider,
		 TQ_SIGNAL(valueChanged(int)),
		 napp->player(),
		 TQ_SLOT(setVolume(int))
		);

	connect
		(
		 forwardButton,
		 TQ_SIGNAL(clicked()),
		 TQ_SLOT(slotForward())
		);

	connect
		(
		 pauseButton,
		 TQ_SIGNAL(clicked()),
		 TQ_SLOT(slotPause())
		);

	connect(speedSlider, TQ_SIGNAL(valueChanged(int)), TQ_SLOT(slotSetSpeed(int)));

	menuButton->setPopup(NoatunStdAction::ContextMenu::contextMenu());

	setIcon(BarIcon("noatun"));

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

	loadConfig();

	resize(sizeHint().width(), minimumSizeHint().height());

	show();
}

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

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

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

void AlsaPlayer::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 AlsaPlayer::setTitleText(const TQString & s)
{
	TQString titleText
		(s.isNull() ? napp->player()->current().title() : s);

	if (titleLabel->text() != titleText)
		titleLabel->setText(titleText);
}

void AlsaPlayer::slotPlaying()
{
	setTitleText(TQString());

	playButton->setOn(true);
	stopButton->setEnabled(true);
}

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

	stopButton->setEnabled(false);
	playButton->setOn(false);
}

void AlsaPlayer::slotPaused()
{
	setTitleText(TQString());

	stopButton->setEnabled(true);
	playButton->setOn(false);
}

bool AlsaPlayer::eventFilter(TQObject *o, TQEvent *e)
{
	switch (e->type())
	{
		case TQEvent::MouseButtonPress:
			mousePressEvent(static_cast<TQMouseEvent*>(e));
			break;

		case TQEvent::Wheel:
			wheelEvent(static_cast<TQWheelEvent*>(e));
			return true;
			break;

		default:
			break;
	}

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

void AlsaPlayer::slotPlayListShown()
{
	playlistButton->setOn(true);
}

void AlsaPlayer::slotPlayListHidden()
{
	playlistButton->setOn(false);
}

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

	return TQWidget::mousePressEvent(e);
}

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

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

void AlsaPlayer::slotVolumeChanged(int i)
{
	TQString text("%1%");
	volumeLabel->setText(text.arg(i));
	volumeSlider->setValue(i);
}

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

	setTitleText(TQString());

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

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

void AlsaPlayer::loadConfig()
{
	// Empty.
}

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

void AlsaPlayer::slotTrackChanged()
{
	slotSetSpeed(speed_);
}

void AlsaPlayer::slotSetSpeed(int newSpeed)
{
	speed_ = newSpeed;

	pauseButton->setEnabled(0 != speed_);
	speedLabel->setText(TQString("%1%").arg(speed_));

	Arts::PlayObject playobject(napp->player()->engine()->playObject());
	Arts::PitchablePlayObject pitchable = Arts::DynamicCast(playobject);

	if (!pitchable.isNull())
	{
		float f = (float(speed_) / 100.f);
		pitchable.speed(f);
	}
}

void AlsaPlayer::slotPause()
{
	speedSlider->setValue(0);
	pauseButton->setEnabled(false);
}

void AlsaPlayer::slotForward()
{
	speedSlider->setValue(100);
}

#include "userinterface.moc"
