#include "stdaction.h"
#include "app.h"
#include "player.h"
#include "stereobuttonaction.h"
#include "pluginloader.h"

#include <khelpmenu.h>
#include <kiconloader.h>
#include <tdelocale.h>
#include <tdepopupmenu.h>
#include <kstdaction.h>
#include <tqcursor.h>
#include <tqmap.h>
#include <kdebug.h>
#include <kstdguiitem.h>

/**
 * A namespace to have all of noatun's standard actions
 * This is treated like KStdAction
 **/
namespace NoatunStdAction
{
/////////////////////////////////////////////////////
PlayAction::PlayAction(TQObject *parent, const char *name)
	: TDEAction(i18n("Play"), 0, napp->player(), TQ_SLOT(playpause()), parent, name)
{
	connect(napp->player(), TQ_SIGNAL(playing()), TQ_SLOT(playing()));
	connect(napp->player(), TQ_SIGNAL(paused()), TQ_SLOT(notplaying()));
	connect(napp->player(), TQ_SIGNAL(stopped()), TQ_SLOT(notplaying()));
	if (napp->player()->isPlaying())
		playing();
	else if (napp->player()->isPaused() || napp->player()->isStopped())
		notplaying();
}

void PlayAction::playing()
{
	setIconSet(TQIconSet(SmallIcon("media-playback-pause")));
	setText(i18n("Pause"));
}

void PlayAction::notplaying()
{
	setIconSet(TQIconSet(SmallIcon("media-playback-start")));
	setText(i18n("Play"));
}
/////////////////////////////////////////////////////

PlaylistAction::PlaylistAction(TQObject *parent, const char *name)
	: TDEToggleAction(i18n("Show Playlist"), "playlist", 0, napp->player(), TQ_SLOT(toggleListView()), parent, name)
{
        setCheckedState(i18n("Hide Playlist"));
	connect(napp->player(), TQ_SIGNAL(playlistShown()),  TQ_SLOT(shown()));
	connect(napp->player(), TQ_SIGNAL(playlistHidden()), TQ_SLOT(hidden()));
	setChecked(napp->playlist()->listVisible());
}

void PlaylistAction::shown()
{
	setChecked(true);
}

void PlaylistAction::hidden()
{
	setChecked(false);
}

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

PluginActionMenu::PluginActionMenu(TQObject *parent, const char *name)
	: TDEActionMenu(i18n("&Actions"), parent, name)
{
// 	kdDebug(66666) << k_funcinfo << "called" << endl;
	setEnabled(false);
	mCount=0;
}

void PluginActionMenu::insert (TDEAction *action, int index)
{
// 	kdDebug(66666) << k_funcinfo << "called" << endl;
	TDEActionMenu::insert(action,index);
	setEnabled(true);
	mCount++;
}

void PluginActionMenu::remove(TDEAction *action)
{
// 	kdDebug(66666) << k_funcinfo << "called" << endl;
	TDEActionMenu::remove(action);
	mCount--;
	if(mCount==0)
		setEnabled(false);
}

int PluginActionMenu::menuAdd(const TQString &text, const TQObject *receiver, const char *member)
{
// 	kdDebug(66666) << k_funcinfo << "called, mCount is currently at " << mCount << endl;
	setEnabled(true);
	mCount++;
	return popupMenu()->insertItem(text, receiver, member);
}

void PluginActionMenu::menuRemove(int id)
{
// 	kdDebug(66666) << k_funcinfo << "called, mCount is currently at " << mCount << endl;
	popupMenu()->removeItem(id);
	mCount--;
	if(mCount==0)
		setEnabled(false);
}

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

VisActionMenu::VisActionMenu(TQObject *parent, const char *name)
	: TDEActionMenu(i18n("&Visualizations"), parent, name)
{
	connect(popupMenu(), TQ_SIGNAL(aboutToShow()), this, TQ_SLOT(fillPopup()));
	connect(popupMenu(), TQ_SIGNAL(activated(int)), this, TQ_SLOT(toggleVisPlugin(int)));
}

void VisActionMenu::fillPopup()
{
	int id;
	popupMenu()->clear();
	mSpecMap.clear();

	TQValueList<NoatunLibraryInfo> available = napp->libraryLoader()->available();
	TQValueList<NoatunLibraryInfo> loaded = napp->libraryLoader()->loaded();

	for(TQValueList<NoatunLibraryInfo>::Iterator i = available.begin(); i != available.end(); ++i)
	{
		if ((*i).type == "visualization")
		{
			id = popupMenu()->insertItem((*i).name);
			mSpecMap[id] = (*i).specfile;
			popupMenu()->setItemChecked(id, loaded.contains(*i));
		}
	}
}

void VisActionMenu::toggleVisPlugin(int id)
{
	if(!mSpecMap.contains(id))
		return;

	TQString specfile = mSpecMap[id];

	if(popupMenu()->isItemChecked(id))
	{
		napp->libraryLoader()->remove(specfile);
		popupMenu()->setItemChecked(id, false);
	}
	else
	{
		napp->libraryLoader()->add(specfile);
		popupMenu()->setItemChecked(id, true);
	}
}

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

LoopActionMenu::LoopActionMenu(TQObject *parent, const char *name)
	: TDEActionMenu(i18n("&Loop"), parent, name)
{
	mLoopNone = new TDERadioAction(i18n("&None"), TQString::fromLocal8Bit("noatunloopnone"),
		0, this, TQ_SLOT(loopNoneSelected()), this, "loop_none");
	mLoopNone->setExclusiveGroup("loopType");
	insert(mLoopNone);

	mLoopSong = new TDERadioAction(i18n("&Song"), TQString::fromLocal8Bit("noatunloopsong"),
		0, this, TQ_SLOT(loopSongSelected()), this, "loop_song");
	mLoopSong->setExclusiveGroup("loopType");
	insert(mLoopSong);

	mLoopPlaylist = new TDERadioAction(i18n("&Playlist"), TQString::fromLocal8Bit("noatunloopplaylist"),
		0, this, TQ_SLOT(loopPlaylistSelected()), this, "loop_playlist");
	mLoopPlaylist->setExclusiveGroup("loopType");
	insert(mLoopPlaylist);

	mLoopRandom = new TDERadioAction(i18n("&Random"), TQString::fromLocal8Bit("noatunlooprandom"),
		0, this, TQ_SLOT(loopRandomSelected()), this, "loop_random");
	mLoopRandom->setExclusiveGroup("loopType");
	insert(mLoopRandom);

	connect(napp->player(), TQ_SIGNAL(loopTypeChange(int)), this, TQ_SLOT(updateLooping(int)));

	updateLooping(static_cast<int>(napp->player()->loopStyle()));
}

void LoopActionMenu::updateLooping(int loopType)
{
	switch(loopType)
	{
		case Player::None:
			mLoopNone->setChecked(true);
			setIcon("noatunloopnone");
			break;
		case Player::Song:
			mLoopSong->setChecked(true);
			setIcon("noatunloopsong");
			break;
		case Player::Playlist:
			mLoopPlaylist->setChecked(true);
			setIcon("noatunloopplaylist");
			break;
		case Player::Random:
			mLoopRandom->setChecked(true);
			setIcon("noatunlooprandom");
			break;
	}
}

void LoopActionMenu::loopNoneSelected()
{
	napp->player()->loop(Player::None);
}

void LoopActionMenu::loopSongSelected()
{
	napp->player()->loop(Player::Song);
}

void LoopActionMenu::loopPlaylistSelected()
{
	napp->player()->loop(Player::Playlist);
}

void LoopActionMenu::loopRandomSelected()
{
	napp->player()->loop(Player::Random);
}

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

TDEAction *playpause(TQObject *parent, const char *name)
{
	return new PlayAction(parent, name);
}

TDEAction *effects(TQObject *parent, const char *name)
{
	return new TDEAction(i18n("&Effects..."), "effect", 0, napp, TQ_SLOT(effectView()), parent, name);
}

TDEAction *equalizer(TQObject *parent, const char *name)
{
	return new TDEAction(i18n("E&qualizer..."), "equalizer", 0, napp, TQ_SLOT(equalizerView()), parent, name);
}

TDEAction *back(TQObject *parent, const char *name)
{
	return new TDEAction(i18n("&Back"), "media-skip-backward", 0, napp->player(), TQ_SLOT(back()), parent, name);
}

TDEAction *stop(TQObject *parent, const char *name)
{
	StereoButtonAction *action = new StereoButtonAction(i18n("Stop"), "media-playback-stop", 0, napp->player(), TQ_SLOT(stop()), parent, name);
	TQObject::connect(napp->player(), TQ_SIGNAL(playing()), action, TQ_SLOT(enable()));
	TQObject::connect(napp->player(), TQ_SIGNAL(paused()), action, TQ_SLOT(enable()));
	TQObject::connect(napp->player(), TQ_SIGNAL(stopped()), action, TQ_SLOT(disable()));
	if(napp->player()->isStopped())
		action->disable();
	else
		action->enable();
	return action;
}

TDEAction *forward(TQObject *parent, const char *name)
{
	return new TDEAction(i18n("&Forward"), "media-skip-forward", 0, napp->player(), TQ_SLOT(forward()), parent, name);
}

TDEAction *play(TQObject *parent, const char *name)
{
	StereoButtonAction *action = new StereoButtonAction(i18n("&Play"), "media-playback-start", 0, napp->player(), TQ_SLOT(playpause()), parent, name);
	TQObject::connect(napp->player(), TQ_SIGNAL(playing()), action, TQ_SLOT(disable()));
	TQObject::connect(napp->player(), TQ_SIGNAL(paused()), action, TQ_SLOT(enable()));
	TQObject::connect(napp->player(), TQ_SIGNAL(stopped()), action, TQ_SLOT(enable()));
	if(napp->player()->isPlaying())
		action->disable();
	else
		action->enable();
	return action;
}

TDEAction *pause(TQObject *parent, const char *name)
{
	StereoButtonAction *action = new StereoButtonAction(i18n("&Pause"), "media-playback-pause", 0, napp->player(), TQ_SLOT(playpause()), parent, name);
	TQObject::connect(napp->player(), TQ_SIGNAL(playing()), action, TQ_SLOT(enable()));
	TQObject::connect(napp->player(), TQ_SIGNAL(paused()), action, TQ_SLOT(disable()));
	TQObject::connect(napp->player(), TQ_SIGNAL(stopped()), action, TQ_SLOT(disable()));
	if(napp->player()->isPlaying())
		action->enable();
	else
		action->disable();
	return action;
}

LoopActionMenu *loop(TQObject *parent, const char *name)
{
	return new LoopActionMenu(parent, name);
}

PluginActionMenu *actions()
{
	// NoatunApp makes sure that we only have one ActionMenu around
	return napp->pluginActionMenu();
}

VisActionMenu *visualizations(TQObject *parent, const char *name)
{
	return new VisActionMenu(parent, name);
}

TDEToggleAction *playlist(TQObject *parent, const char *name)
{
	return new PlaylistAction(parent, name);
}

TDEPopupMenu *ContextMenu::mContextMenu = 0;

TDEPopupMenu *ContextMenu::contextMenu()
{
	if(!mContextMenu) mContextMenu = createContextMenu(0);

	return mContextMenu;
}

TDEPopupMenu *ContextMenu::createContextMenu(TQWidget *p)
{
	TDEPopupMenu *contextMenu = new TDEPopupMenu(p, "NoatunContextMenu");

	KHelpMenu *helpmenu = new KHelpMenu(contextMenu, kapp->aboutData(), false);
	TDEActionCollection* actions = new TDEActionCollection(helpmenu);

	KStdAction::open(napp, TQ_SLOT(fileOpen()), actions)->plug(contextMenu);
	KStdAction::quit(napp, TQ_SLOT(quit()), actions)->plug(contextMenu);
	contextMenu->insertItem(SmallIcon("help"), KStdGuiItem::help().text(), helpmenu->menu());
	contextMenu->insertSeparator();
	KStdAction::preferences(napp, TQ_SLOT(preferences()), actions)->plug(contextMenu);
	NoatunStdAction::playlist(contextMenu)->plug(contextMenu);
	NoatunStdAction::effects(contextMenu)->plug(contextMenu);
	NoatunStdAction::equalizer(napp)->plug(contextMenu);
	NoatunStdAction::visualizations(napp)->plug(contextMenu);
	napp->pluginActionMenu()->plug(contextMenu);

	return contextMenu;
}

void ContextMenu::showContextMenu(const TQPoint &p)
{
	contextMenu()->exec(p);
}

void ContextMenu::showContextMenu()
{
	showContextMenu(TQCursor::pos());
}

} // END namespace NoatunStdAction

#include "stdaction.moc"
