/*****************************************************************************
 *
 *  interfaceffmpeg.h -- Interface to FFmpeg CLI. 
 *
 *  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 INTERFACEFFMPEG_H
#define INTERFACEFFMPEG_H

#include "../video/video_struct.h"
#include "../video/video_constants.h"
#include <QString>
#include <QStringList>
#include <QMap>
#include <QHash>

class InterfaceFFmpeg
{
public:
	InterfaceFFmpeg();
	//~InterfaceFFmpeg();

	void initialize(const QString &, encoder_engine_capability_t *, encoder_settings_t *, encoder_engine_status_t *);
	inline bool isReady() { return status->state == Video::Status::EngineOk; };

	inline QString getBinPath() { return exec; };
	void setBinPath(const QString &);

	void setPass(const int current, const int N) { NPass = N; currentPass = current; };

	void cliCmdGetStatus(QString *, QStringList *);				// command to test encoder backend
	void cliCmdGetVersion(QString *, QStringList *);
	void cliCmdGetCodecs(QString *, QStringList *);	
	void cliCmdGetMuxers(QString *, QStringList *);

	bool cliCmdSplitFile(QString *cmd, QStringList *args,
		const QString &inputFileName, const qint64 inputFileSize, 
		const int partNumber, const qint64 partSize);

	void cliCmdTargetVcd(QString *, QStringList *, const QString &, const QString &, const QString &);
	void cliCmdTargetSvcd(QString *, QStringList *, const QString &, const QString &, const QString &);

	void cliCmdEncode(QString *, QStringList *, const QString &, int=0, int=0);	// command to encode

	void cliCorrectAspectRatio(QString *, QStringList *, const QString &, const QString &, double);
	void cliExtractAudioFromAvi(QString *, QStringList *, const QString &, const QString &);

	void cliCmdRemux(const QString &, const QString &,
		QString *, QStringList *);	// command to remux a video file

	QStringList profileCommandLine(const encoder_profile_t *, const QString &, int=0, int=0);

	int getEstimatedOutputFileSize(const int);

	void parseVersion();
	void parseCodecs();
	void parseMuxers();
	bool parseCommandCheck( QByteArray *, QByteArray *);
	static bool parseOutput(QString *, QString *, int *, double *, int *, int *, double *, int *);

	bool muxerSupport(const QString &);  // muxer has video/audio/subtitle codec support
	bool muxerSupportVideo(const QString &, const QString &);
	bool muxerSupportAudio(const QString &, const QString &);
	bool muxerSupportSubtitle(const QString &, const QString &);

	bool supportMultiAudio();
	bool supportMultiSubtitle();

	inline QStringList getSupportedMuxers() const { return *muxers; };

protected:
	void setVideoProfiles();
	void setAudioProfiles();

	void setVideoSynonyms();
	void setAudioSynonyms();
	void setSubtitleSynonyms();
	void setMuxerSynonyms();

protected:	
	QString exec;		// full qualified bin path

	encoder_settings_t *settings;
	encoder_engine_capability_t *capability;
	encoder_engine_status_t *status;

	int NPass;
	int currentPass;

	// Supported codecs and muxers
	QStringList *muxers;
	QStringList *videos;
	QStringList *audios;
	QStringList *subtitles;

	// Muxer suppport
	QMap<QString, QStringList> muxerVideos;
	QMap<QString, QStringList> muxerAudios;
	QMap<QString, QStringList> muxerSubtitles;

	// Synonyms
	QHash<QString, QString> muxerSynonyms;
	QHash<QString, QString> videoSynonyms;
	QHash<QString, QString> audioSynonyms;
	QHash<QString, QString> subtitleSynonyms;

	// Convenient constants
	enum Preset { None = 0, VeryHQ, HQ, Fast, VeryFast };
	enum Profile { Free = 0, 
		DivxHandheld, DivxPortableNtsc, DivxPortablePal, DivxHomeTheatreNtsc, DivxHomeTheatrePal, DivxHighDef,
		Simple0, Simple1, Simple2, Simple3,
		AdvancedSimple0, AdvancedSimple1, AdvancedSimple2, 
		AdvancedSimple3, AdvancedSimple4, AdvancedSimple5,
		SmallSmartphones, LargeSmartphones, 
		Apple_iPhone, Apple_iPad, Apple_MacBook13, Apple_MacBook15, Apple_MacBook17, Apple_iMac, 
		Archos7, Archos10,
		BlackBerry, 
		Netbook10, Netbook12, 
		Laptop13, Laptop15, Laptop17, 
		Desktop	};
	enum Quantization { H263 = 0, MPEG };
};

#endif
