/*****************************************************************************
 *
 *  player.h -- Audio/Video player class.
 *
 *  Copyright (C) 2010 Starbuck <starbuck@labdv.com>
 *  All rights reserved.
 *
 *  This file is part of the Encoder module of the DVDx 4 application.
 *
 *  GNU Lesser General Public License Usage
 *  This file may be used under the terms of the GNU Lesser General
 *  Public License version 2.1 as published by the Free Software
 *  Foundation and appearing in the file LICENSE.LGPL included in the
 *  packaging of this file.  Please review the following information to
 *  ensure the GNU Lesser General Public License version 2.1 requirements
 *  will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
 *
 *  GNU General Public License Usage
 *  Alternatively, this file may be used under the terms of the GNU
 *  General Public License version 3.0 as published by the Free Software
 *  Foundation and appearing in the file LICENSE.GPL included in the
 *  packaging of this file.  Please review the following information to
 *  ensure the GNU General Public License version 3.0 requirements will be
 *  met: http://www.gnu.org/copyleft/gpl.html.
 *
 *****************************************************************************/

#ifndef PLAYER_H
#define PLAYER_H

// should be for libdvd.lib
#ifdef WIN32
//#include "config.h"
//#include "dvdnav/dvdnav.h"
#endif

#include "../main/macrosdev.h"
#include "../video/video_struct.h"
#include "../video/video_constants.h"
#include "interfacemediainfo.h"
#include "interfaceffprobe.h"
#include "interfacemplayer.h"
#include <QString>
#include <QStringList>
#include <QTextEdit>
#include <QObject>

class Player : public QObject
{
	Q_OBJECT

public:
	Player(const int select,  const QString &binaryPath, const QString &, const QString &,
				QTextEdit *stdIn, QTextEdit *stdOut, QTextEdit *stdErr,
				QTextEdit *defLog, const int verbose,
				const int latencyStart = 0, const int latencyFinished = 0, const int latencyKill = 0);
	//~Player();

	void authenticateDvd(const QString &);

	void setConsole(QTextEdit *);	// set output console for messages
	inline int interfaceType() const { return backend; };
	void setLatency(const int start, const int finished, const int kill);
	void setExternalRenderer(const int, const int, const int);
	void setVerbosity(const int);

	void cliCmdPlay(QString *, QStringList *, 
		int=0, int=0, int=0, int=0);					// command to play movie
	void cliCmdIdentify(QString *, QStringList *);		// command to identify movie
	void cliCmdUpdateFontCache(QString *, QStringList *);
	void cliCmdGetStatus(QString *, QStringList *);		// command to test player backend
	QString cliStop();					// command to stop playback (and end player process)
	QString cliSelectTitle(const int);		// command to select title
	QString cliSelectAudio(const int);		// command to select audio track
	QString cliSelectSubtitle(const int);	// command to select subtitle
	QString cliAvert(const QString &, const int );		// command to display OSD message
	QString cliShowProgress();			// command to display the progression bar
	QString cliVideoResolution();		// command to get video resolution
	QString cliTimeLength();			// command to get movie length
	QString cliTimePosition();			// command to get playback position
	QString cliChapter();				// command to get current chapter
	QString cliDeinterlace();			// command to get playback deinterlace property
	QString cliSpeed();					// command to get playback speed
	QString cliSeekChapter(const int);	// command to seek to the start of a chapter
	QString cliSeekPrev(const int=0);	// command to seek to previous seconds or chapter
	QString cliSeekNext(const int=0);	// command to seek to next seconds or chapter
	QString cliSeekRelative(const int);	// command to seek to a relative +/- seconds
	QString cliSeekPercent(const int);	// command to seek to a % in the movie
	QString cliSeek(const int);			// command to seek to some place (seconds) in the movie
	QString cliSetSpeedFaster();		// command to faster playback speed (x2)
	QString cliSetSpeedSlower();		// command to slow down playback speed (:2)
	QString cliSetSpeedNormal();		// command to set speed to x1
	QString cliSwitchAspectRatio(const double);	// command to switch to change aspect ratio
												// at runtime. [value] is the new aspect ratio 
												// expressed as a float (e.g. 1.77778 for 16/9).
												// There might be problems with some video filters.
	QString cliSwitchAngle(const int);	// command to switch to the angle with the ID. Cycle through the
										//         available angles if value is omitted or negative.
	QString cliSwitchPause();			// command to pause/unpause the playback

	bool parseStdoutClip(const QByteArray &, int *, video_clip_t *);
	bool parseStdoutDisk(const QByteArray &, int *, mplayer_video_disk_t *);
	bool parseStdoutRun(const QByteArray &, int *, mplayer_video_running_t *);
	void parseStderr(const QByteArray &, int *, QString *);
	void parseStatus();

	void readMediaInfo(const QString &);
	void readFFprobe(const QString &);

	void cliCmdGetMediaInfoStatus(QString *, QStringList *);
	void cliCmdGetMediaInfoData(const QString &, QString *, QStringList *);
	void parseMediaInfoData(interfacemediainfo_data_t *);

	void cliCmdGetFFprobeStatus(QString *, QStringList *);
	void cliCmdGetFFprobeData(const QString &, QString *, QStringList *);
	void parseFFprobeData(interfaceffprobe_t *, QString *, QString *);

	// Directly access private data thru their pointers
	inline player_engine_capability_t *getCapability() const { return capability; };
	inline player_engine_status_t *getStatus() const { return status; };
	inline utility_status_t *getMediaInfoStatus() const { return mediaInfoStatus; };
	inline interfacemediainfo_data_t *getMediaInfoData() const { return mediaInfoData; };
	inline utility_status_t *getFFprobeStatus() const { return ffprobeStatus; };
	inline interfaceffprobe_t *getFFprobeData() const { return ffprobeData; };

	QString getBinPath(const int);
	QString engineVersion(const int);

	void setBinPath(const QString &);
	void setMediaInfoBinPath(const QString &);
	void setFFprobeBinPath(const QString &);
	void setSource(const QString &, const int=Video::Media::File, const bool=false);	// set video source
	void setSource(const QString &, const int, const int);		// ... for DVD title

	void setSoundOn();
	void setSoundOff();
	void setVideoOn();
	void setVideoOff();
	void setSubtitleOn();
	void setSubtitleOff();

	void setTitle(const int);
	void setAudioId(const int &);
	void setSubtitleId(const int &);

	void setAngle(const int);
	void setSliceCut(QList<slice_t> *);

	void setAspectRatio(const double &);
	void setSize(const QSize);			// set picture size (0x0 to ignore)
	bool setPreferredVideoDriver(const QString &);
	void setWid(const QString &);	// set render widget window system id

	bool soundOn();
	bool videoOn();
	bool subtitleOn();

protected:
	void initialize();
	void resetBackend();
	void resetMediaInfo();
	void resetFFprobe();

	QString name(const int);
	void print(const QString &);

	int verbosity;
	void printLog(const QString &, const int=VERBOSITY_NORMAL);
	void printIn(const QString &, const int=VERBOSITY_NORMAL);
	void printOut(const QString &, const int=VERBOSITY_NORMAL);
	void printErr(const QString &, const int=VERBOSITY_NORMAL);

	void clearLog();
	void clearIn();
	void clearOut();
	void clearErr();

protected:
	QTextEdit *console;	// for optional error display
	QString source;		// path to video source
	player_engine_capability_t *capability;
	player_engine_status_t *status;
	QString binPath;	// path to player binary

	interfacemediainfo_data_t *mediaInfoData;
	utility_status_t *mediaInfoStatus;
	QString mediaInfoBinPath;	// path to MediaInfo CLI binary

	interfaceffprobe_t *ffprobeData;
	utility_status_t *ffprobeStatus;
	QString ffprobeBinPath;	// path to MediaInfo CLI binary

	QMap<QString, QString> videos;
	QMap<QString, QString> audios;

	QTextEdit *log;				// log application errors/warnings
	QTextEdit *standardInput;	// process stdIn
	QTextEdit *standardOutput;	// process stdOut
	QTextEdit *standardError;	// process stdErr

	int backend;  // interface type
	InterfaceMplayer *mplayer;
	//InterfaceVlc *vlcplayer;
	InterfaceMediaInfo *mediainfo;
	InterfaceFFprobe *ffprobe;

	QString targetWid;  // window system identifier of the target widget
		// Portable in principle, but if you use it you are probably about to do something non-portable. 
		// Be careful.
		// Note: We recommend that you do not store this value as it is likely to change during run-time.

	// process latency
	int LatencyStart, LatencyFinished, LatencyKill;
	enum Constants { DefaultLatencyStart = 3000, DefaultLatencyFinished = 3000, DefaultLatencyKill= 5000 };
};

#endif
