/*
 * Cantata
 *
 * Copyright (c) 2011-2022 Craig Drummond <craig.p.drummond@gmail.com>
 *
 * ----
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#ifndef DYNAMIC_PLAYLISTS_H
#define DYNAMIC_PLAYLISTS_H

#include "models/actionmodel.h"
#include "rulesplaylists.h"
#include "support/icon.h"
#include <QIcon>
#include <QList>
#include <QMap>
#include <QString>
#include <QStringList>

class QTimer;

class DynamicPlaylists : public RulesPlaylists {
	Q_OBJECT

public:
	enum Command {
		Unknown,
		Ping,
		List,
		Status,
		Save,
		Del,
		SetActive,
		Control
	};

	static Command toCommand(const QString& cmd);
	static QString toString(Command cmd);
	static void enableDebug();

	static DynamicPlaylists* self();

	DynamicPlaylists();
	~DynamicPlaylists() override {}

	QString name() const override;
	QString title() const override;
	QString descr() const override;
	bool isDynamic() const override { return true; }
	QVariant data(const QModelIndex& index, int role) const override;
	bool isRemote() const override { return usingRemote; }
	bool saveRemote(const QString& string, const Entry& e) override;
	void del(const QString& name) override;
	void start(const QString& name);
	void stop(bool sendClear = false) override;
	void toggle(const QString& name);
	bool isRunning();
	void helperMessage(const QString& message)
	{
		Q_UNUSED(message)
		checkHelper();
	}
	Action* startAct() const { return startAction; }
	Action* stopAct() const { return stopAction; }
	void enableRemotePolling(bool e);

Q_SIGNALS:
	void running(bool status);
	void error(const QString& str);

	// These are for communicating with MPD object (which is in its own thread, so need to talk via signal/slots)
	void clear();
	void remoteMessage(const QStringList& args);

	// These are as the result of asynchronous HTTP calls
	void saved(bool s);
	void loadingList();
	void loadedList();

private Q_SLOTS:
	void checkHelper();
	void checkIfRemoteIsRunning();
	void updateRemoteStatus();
	void remoteResponse(QStringList msg);
	void remoteDynamicSupported(bool s);
	void parseStatus(QStringList response);

private:
	void pollRemoteHelper();
	int getPid() const;
	bool controlApp(bool isStart);
	bool sendCommand(Command cmd, const QStringList& args = QStringList());
	void parseRemote(const QStringList& response);

private:
	QTimer* localTimer;
	Action* startAction;
	Action* stopAction;

	// For remote dynamic servers...
	bool usingRemote;
	QTimer* remoteTimer;
	bool remotePollingEnabled;
	int statusTime;
	QString lastState;
	QString dynamicUrl;
	Command currentCommand;
	QString currentDelete;
	Entry currentSave;
};

#endif
