/*****************************************************************************
 *
 *  video_functions.cpp -- Most common functions for video handling.
 *
 *  Copyright (C) 2010 Starbuck <starbuck@labdv.com>
 *  All rights reserved.
 *
 *  This file is part of the Gui4 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.
 *
 *****************************************************************************/

#include "video_struct.h"
#include "video_constants.h"
#include "video_functions.h"

#include <math.h>
#include <QTime>
#include <QObject>

namespace Video
{
/////////////////////////////////////////////////////////////////////////
// Return constants as QString

QString strPlayer(const int code)
{
	QString str;

	switch (code)
	{
	case Player::MPlayer:
		str = QString("MPlayer");
		break;
	case Player::VLC:
		str = QString("VLC");
		break;
	default:
		str = QObject::tr("Unkown player");
	}

	return str;
}

QString strEncoder(const int code)
{
	QString str;

	switch (code)
	{
	case Encoder::FFmpeg:
		str = QString("FFmpeg");
		break;
	case Encoder::MEncoder:
		str = QString("MEncoder");
		break;
	case Encoder::x264:
		str = QString("x264");
		break;
	case Encoder::MKVmerge:
		str = QString("MKVmerge");
		break;
	default:
		str = QObject::tr("Unkown encoder");
	}

	return str;
}

QString strVideoAccel(const int code)
{
	QString str;

	switch (code)
	{
	case Acceleration::None:
		str = QString("NoAccel");
		break;
	case Acceleration::OpenGL:
		str = QString("OpenGL");
		break;
	case Acceleration::DirectX:
		str = QString("DirectX");
		break;
	default:
		str = QObject::tr("Unkown video accel code");
	}

	return str;
}

QString strMedia(const int code)
{
	QString str;

	switch (code)
	{
	case Media::File:
		str = QObject::tr("File");
		break;
	case Media::DVD:
		str = QString("DVD");
		break;
	case Media::VCD:
		str = QString("VCD");
		break;
	default:
		str = QObject::tr("Unkown media");
	}

	return str;
}

QString strProfile(const int level)
{
	QString str;

	switch (level)
	{
	case Profile::Low:
		str = QObject::tr("low");
		break;
	case Profile::Medium:
		str = QObject::tr("medium");
		break;
	case Profile::High:
		str = QObject::tr("high");
		break;
	case Profile::User:
		str = QObject::tr("user");
		break;
	case Profile::Copy:
		str = QObject::tr("source copy");
		break;
	case Profile::None:
		str = QObject::tr("unset");
		break;
	default:
		str = QObject::tr("unknown");
		break;
	}

	return str;
}

QString strProfileTitle(const int level)
{
	QString str;

	switch (level)
	{
	case Profile::Low:
		str = QObject::tr("Lower quality (smaller file)");
		break;
	case Profile::Medium:
		str = QObject::tr("Fair quality");
		break;
	case Profile::High:
		str = QObject::tr("Higher quality (larger file)");
		break;
	case Profile::User:
		str = QObject::tr("User settings");
		break;
	case Profile::Copy:
		str = QObject::tr("Copy source stream");
		break;
	case Profile::None:
		str = QObject::tr("No profile constraint");
		break;
	default:
		str = QObject::tr("Unknown profile");
		break;
	}

	return str;
}

/////////////////////////////////////////////////////////////////////////
// Return DVD values as QString

QString strDvdAspect(const int aspect)
{
	QString str;

	switch (aspect)
	{
		case 1:
			str = "1:1";
			break;
		case 2:
			str = "4:3";
			break;
		case 3:
			str = "16:9";
			break;
		case 4:
			str = "2.21:1";  // not used in DVD
			break;
		case 5:
			str = "1.85:1";  // not used in DVD (added for DVDx4)
			break;
		case 6:
			str = "2.35:1";  // not used in DVD (added for DVDx4)
			break;
		default:
			str.append(QString("undefined (%1)").arg(aspect));
	}

	return str;
}

QString strDvdLength(const double seconds)
{
	QTime time;

	time = time.addSecs(seconds);

	return time.toString("hh:mm:ss");
}

QString strDvdFps(const int fps)
{
	QString str;

	switch (fps)
	{
		case 1:
			str = "23.976";
			break;
		case 2:
			str = "24";
			break;
		case 3:
			str = "25";
			break;
		case 4:
			str = "29.97"; 
			break;
		case 5:
			str = "30";
			break;
		case 6:
			str = "50";
			break;
		case 7:
			str = "59.94";
			break;
		case 8:
			str = "60";
			break;
		default:
			str.append(QString("undefined (%1)").arg(fps));
	}

	return str;
}

QString strDvdKbps(const double kbps)
{
	QString str;

	return str.sprintf( "%.1f", kbps );
}

/////////////////////////////////////////////////////////////////////////
// Return movie values as QString

QString strMovieAspect(const double aspect)
{
	return QString::number(aspect, 'f', 2);
}

QString strMovieLength(const double seconds)
{
	QTime time;

	time = time.addSecs(seconds);

	return time.toString("hh:mm:ss");
}

QString strMovieFps(const double fps)
{
	QString str;
	double delta(0.005);  // < 0.006 to differentiate 23.976 from 24
	
	if ( (fps > 24.0 - delta && fps < 24.0 + delta)
		|| (fps > 25.0 - delta && fps < 25.0 + delta)
		|| (fps > 30.0 - delta && fps < 30.0 + delta)
		|| (fps > 50.0 - delta && fps < 50.0 + delta)
		|| (fps > 60.0 - delta && fps < 60.0 + delta) )
	{
		str = QString::number(fps, 'f', 0);
	}
	else if ( fps > 23.976 - delta && fps < 23.976 + delta )
	{
		str = QString::number(fps, 'f', 3);
	}
	else
	{
		str = QString::number(fps, 'f', 2);
	}

	return str;
}

QString strMovieKbps(const double kbps)
{
	QString str;

	return str.sprintf( "%.1f", kbps );
}

QString strMovieSampling(const int hz)
{
	double freq = (double)hz / 1000.0;

	int precision(1);
	double restdiv = fmod( (double)hz, 100.0 );

	if (restdiv) precision = 3;

	return QString::number(freq, 'f', precision);
}


/////////////////////////////////////////////////////////////////////////
// Return DVD values as integer

int intDvdAspect(const QString &aspect)
{
	QString str(aspect.trimmed());

	int code(0);

	if ( str == "1:1" )
		code = 1;
	else if ( str == "1.33:1" )
		code = 2; // 4:3
	else if ( str == "1.77:1" )
		code = 3; // 16:9
	else if ( str == "2.21:1" )
		code = 4; // not used in DVD
	else if ( str == "1.85:1" )
		code = 5; // not used in DVD (added for DVDx4)
	else if ( str == "2.35:1" )
		code = 6; // not used in DVD (added for DVDx4)

	return code;
}

int intDvdAspect(const double aspect)
{
	int code(0);

	if ( qAbs(aspect - 1.0) < 0.1 )
		code = 1;
	else if ( qAbs(aspect - 1.33) < 0.1 )
		code = 2; // 4:3
	else if ( qAbs(aspect - 1.77) < 0.1 )
		code = 3; // 16:9
	else if ( qAbs(aspect - 2.21) < 0.1 )
		code = 4; // not used in DVD
	else if ( qAbs(aspect - 1.85) < 0.1 )
		code = 5; // not used in DVD (added for DVDx4)
	else if ( qAbs(aspect - 2.35) < 0.1 )
		code =  6; // not used in DVD (added for DVDx4)

	return code;
}

int intDvdFps(const double fps)
{
	int mpeg_fps(0);  // forbidden in DVD

	if ( fps == 23.976 )
		mpeg_fps = 1;
	else if ( fps == 24.0 )
		mpeg_fps = 2;
	else if ( fps == 25.0 )
		mpeg_fps = 3;
	else if ( fps == 29.97 )
		mpeg_fps = 4;
	else if ( fps == 30.0 )
		mpeg_fps = 5;
	else if ( fps == 50.0 )
		mpeg_fps = 6;
	else if ( fps == 59.94 )
		mpeg_fps = 7;
	else if ( fps == 60.0 )
		mpeg_fps = 8;

	return mpeg_fps;
}

double valDvdAspect(const int code)
{
	double val;

	switch (code)
	{
		case 1:
			val = 1.0;
			break;
		case 2:
			val = 4.0 / 3.0;
			break;
		case 3:
			val = 16.0 / 9.0;
			break;
		case 4:
			val = 2.21;
			break;
		case 5:
			val = 1.85;
			break;
		case 6:
			val = 2.35;
			break;
		case 7:
			val = 21.0 / 9.0;
			break;
		default:
			val = 16.0 / 9.0;
	}

	return val;
}

double valDvdFps(const int code)
{
	double val;

	switch (code)
	{
		case 1:
			val = 23.976;
			break;
		case 2:
			val = 24.0;
			break;
		case 3:
			val = 25.0;
			break;
		case 4:
			val = 29.97;
			break;
		case 5:
			val = 30.0;
			break;
		case 6:
			val = 50.0;
			break;
		case 7:
			val = 59.94;
			break;
		case 8:
			val = 60.0;
			break;
		default:
			val = 24.0;
	}

	return val;
}

/////////////////////////////////////////////////////////////////////////
// Return language from DVD language code

QString strDvdLang(const QString &code)
{
	QString str;

	if (code == "und")
		str = "Misc.";				// undefined
	else if (code == "mis")
		str = "Misc.";			// miscaelaneous
	else if (code == "ar")
		str = "Arabic";
	else if (code == "en" || code == "eng")
		str = "English";
	else if (code == "de")
		str = "German";
	else if (code == "es" || code == "sp" || code == "spa")
		str = "Spanish";
	else if (code == "fr" || code == "fre" || code == "fra")
		str = "French";
	else if (code == "jp" || code == "jpn")
		str = "Japanese";
	else if (code == "nl")
		str = "Dutch";
	else
	{
		str = code;
		str[0] = str[0].toUpper();
	}

	return str;
}
/*
LCIDNameList[] = {
	{0x0000, "Default"},
	{0x0436, "Afrikaans"},
	{0x041c, "Albanian"},
	{0x0401, "Arabic (Saudi Arabia)"},
	{0x0801, "Arabic (Iraq)"},
	{0x0c01, "Arabic (Egypt)"},
	{0x1001, "Arabic (Libya)"},
	{0x1401, "Arabic (Algeria)"},
	{0x1801, "Arabic (Morocco)"},
	{0x1c01, "Arabic (Tunisia)"},
	{0x2001, "Arabic (Oman)"},
	{0x2401, "Arabic (Yemen)"},
	{0x2801, "Arabic (Syria)"},
	{0x2c01, "Arabic (Jordan)"},
	{0x3001, "Arabic (Lebanon)"},
	{0x3401, "Arabic (Kuwait)"},
	{0x3801, "Arabic (U.A.E.)"},
	{0x3c01, "Arabic (Bahrain)"},
	{0x4001, "Arabic (Qatar)"},
	{0x042b, "Armenian"},
	{0x042c, "Azeri (Latin)"},
	{0x082c, "Azeri (Cyrillic)"},
	{0x042d, "Basque"},
	{0x0423, "Belarusian"},
	{0x0402, "Bulgarian"},
	{0x0455, "Burmese"},
	{0x0403, "Catalan"},
	{0x0404, "Chinese (Taiwan)"},
	{0x0804, "Chinese (PRC)"},
	{0x0c04, "Chinese (Hong Kong SAR, PRC)"},
	{0x1004, "Chinese (Singapore)"},
	{0x1404, "Chinese (Macau SAR)"},
	{0x041a, "Croatian"},
	{0x0405, "Czech"},
	{0x0406, "Danish"},
	{0x0465, "Divehi"},
	{0x0413, "Dutch (Netherlands)"},
	{0x0813, "Dutch (Belgium)"},
	{0x0409, "English (United States)"},
	{0x0809, "English (United Kingdom)"},
	{0x0c09, "English (Australian)"},
	{0x1009, "English (Canadian)"},
	{0x1409, "English (New Zealand)"},
	{0x1809, "English (Ireland)"},
	{0x1c09, "English (South Africa)"},
	{0x2009, "English (Jamaica)"},
	{0x2409, "English (Caribbean)"},
	{0x2809, "English (Belize)"},
	{0x2c09, "English (Trinidad)"},
	{0x3009, "English (Zimbabwe)"},
	{0x3409, "English (Philippines)"},
	{0x0425, "Estonian"},
	{0x0438, "Faeroese"},
	{0x0429, "Farsi"},
	{0x040b, "Finnish"},
	{0x040c, "French (Standard)"},
	{0x080c, "French (Belgian)"},
	{0x0c0c, "French (Canadian)"},
	{0x100c, "French (Switzerland)"},
	{0x140c, "French (Luxembourg)"},
	{0x180c, "French (Monaco)"},
	{0x0456, "Galician"},
	{0x0437, "Georgian"},
	{0x0407, "German (Standard)"},
	{0x0807, "German (Switzerland)"},
	{0x0c07, "German (Austria)"},
	{0x1007, "German (Luxembourg)"},
	{0x1407, "German (Liechtenstein)"},
	{0x0408, "Greek"},
	{0x0447, "Gujarati"},
	{0x040d, "Hebrew"},
	{0x0439, "Hindi"},
	{0x040e, "Hungarian"},
	{0x040f, "Icelandic"},
	{0x0421, "Indonesian"},
	{0x0410, "Italian (Standard)"},
	{0x0810, "Italian (Switzerland)"},
	{0x0411, "Japanese"},
	{0x044b, "Kannada"},
	{0x0457, "Konkani"},
	{0x0412, "Korean"},
	{0x0812, "Korean (Johab)"},
	{0x0440, "Kyrgyz"},
	{0x0426, "Latvian"},
	{0x0427, "Lithuanian"},
	{0x0827, "Lithuanian (Classic)"},
	{0x042f, "FYRO Macedonian"},
	{0x043e, "Malay (Malaysian)"},
	{0x083e, "Malay (Brunei Darussalam)"},
	{0x044e, "Marathi"},
	{0x0450, "Mongolian"},
	{0x0414, "Norwegian (Bokmal)"},
	{0x0814, "Norwegian (Nynorsk)"},
	{0x0415, "Polish"},
	{0x0416, "Portuguese (Brazil)"},
	{0x0816, "Portuguese (Portugal)"},
	{0x0446, "Punjabi"},
	{0x0418, "Romanian"},
	{0x0419, "Russian"},
	{0x044f, "Sanskrit"},
	{0x0c1a, "Serbian (Cyrillic)"},
	{0x081a, "Serbian (Latin)"},
	{0x041b, "Slovak"},
	{0x0424, "Slovenian"},
	{0x040a, "Spanish (Spain, Traditional Sort)"},
	{0x080a, "Spanish (Mexican)"},
	{0x0c0a, "Spanish (Spain, International Sort)"},
	{0x100a, "Spanish (Guatemala)"},
	{0x140a, "Spanish (Costa Rica)"},
	{0x180a, "Spanish (Panama)"},
	{0x1c0a, "Spanish (Dominican Republic)"},
	{0x200a, "Spanish (Venezuela)"},
	{0x240a, "Spanish (Colombia)"},
	{0x280a, "Spanish (Peru)"},
	{0x2c0a, "Spanish (Argentina)"},
	{0x300a, "Spanish (Ecuador)"},
	{0x340a, "Spanish (Chile)"},
	{0x380a, "Spanish (Uruguay)"},
	{0x3c0a, "Spanish (Paraguay)"},
	{0x400a, "Spanish (Bolivia)"},
	{0x440a, "Spanish (El Salvador)"},
	{0x480a, "Spanish (Honduras)"},
	{0x4c0a, "Spanish (Nicaragua)"},
	{0x500a, "Spanish (Puerto Rico)"},
	{0x0430, "Sutu"},
	{0x0441, "Swahili (Kenya)"},
	{0x041d, "Swedish"},
	{0x081d, "Swedish (Finland)"},
	{0x045a, "Syriac"},
	{0x0449, "Tamil"},
	{0x0444, "Tatar (Tatarstan)"},
	{0x044a, "Telugu"},
	{0x041e, "Thai"},
	{0x041f, "Turkish"},
	{0x0422, "Ukrainian"},
	{0x0420, "Urdu (Pakistan)"},
	{0x0820, "Urdu (India)"},
	{0x0443, "Uzbek (Latin)"},
	{0x0843, "Uzbek (Cyrillic)"},
	{0x042a, "Vietnamese"}
};*/
}  // namespace Video
