//---------------------------------------------------------------------------
//	Video editor
//	2004 - 2007 Stanislav Sumec <sumec@fit.vutbr.cz>
//	Brno University of Technology
//	Faculty of Information Technology
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <iostream>
#include <time.h>
#include <deque>
#pragma hdrstop
#include "Editor.h"
#include "Error.h"
#include "avfile.h"
#include "Tools.h"
#include "Img.h"
#ifdef __BORLANDC__
#include "WindowsMM.h"
#endif

//---------------------------------------------------------------------------
static int LastProgressPos;
static clock_t LastProgressTime;

typedef struct
{
	int Pos;
	clock_t Time;
}
TPosTime;

static std::deque<TPosTime> PosTimeQueue;

void Progress(int Pos, int Max)
{
	TPosTime pt;
	pt.Pos = Pos;
	pt.Time = clock();
	PosTimeQueue.push_back(pt);

	float Speed = 0;
	if (PosTimeQueue.size() > 10)
	{
		if (PosTimeQueue.back().Pos > PosTimeQueue.front().Pos)
		{
			Speed = (1000.0 * float(PosTimeQueue.back().Time - PosTimeQueue.front().Time) / CLK_TCK) / float(PosTimeQueue.back().Pos - PosTimeQueue.front().Pos);
		}
		PosTimeQueue.pop_front();
	}

	int PorgressPos = (Pos * 100) / Max;
	std::cout << "\r" << Pos << "/" << Max << "ms " << PorgressPos << "% " << Speed << "					";
	std::cout.flush();
/*
	int PorgressPos = (Pos * 100) / Max;
	if (PorgressPos != LastProgressPos)
	{
		std::cout << "\r" << Pos << "/" << Max << "ms " << PorgressPos << "%";
		std::cout.flush();
		LastProgressPos = PorgressPos;
	}
*/
}

//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
	int Arg = 1;

	int Quality = 0;
	char *Input, *Output, *Media;
	Input = Output = Media = NULL;
	TEditor::TSaveOptions SaveOptions;

	while (Arg < argc)
	{
		if (!strcmp(argv[Arg], "-start"))
		{
			Arg++;
			if (Arg < argc)
			{
				SaveOptions.Start = atoi(argv[Arg++]);
			}
			else
			{
				break;
			}
		}
		else if (!strcmp(argv[Arg], "-length"))
		{
			Arg++;
			if (Arg < argc)
			{
				SaveOptions.MaxLength = atoi(argv[Arg++]);
			}
			else
			{
				break;
			}
		}
		else if (!strcmp(argv[Arg], "-t"))
		{
			Arg++;
			if (Arg < argc)
			{
				SaveOptions.Type = atoi(argv[Arg++]);
			}
			else
			{
				break;
			}
		}
		else if (!strcmp(argv[Arg], "-downsample"))
		{
			Arg++;
			if (Arg < argc)
			{
				SaveOptions.ResampleSources = atoi(argv[Arg++]);
			}
			else
			{
				break;
			}
		}
		else if (!strcmp(argv[Arg], "-quality"))
		{
			Arg++;
			if (Arg < argc)
			{
				SaveOptions.Quality = atoi(argv[Arg++]);
			}
			else
			{
				break;
			}
		}
		else if (!strcmp(argv[Arg], "-disable_audio"))
		{
			Arg++;
			SaveOptions.Audio = false;
		}
		else if (!strcmp(argv[Arg], "-disable_video"))
		{
			Arg++;
			SaveOptions.Video = false;
		}
		else if (!strcmp(argv[Arg], "-input"))
		{
			Arg++;
			if (Arg < argc)
			{
				Input = argv[Arg++];
			}
			else
			{
				break;
			}
		}
		else if (!strcmp(argv[Arg], "-output"))
		{
			Arg++;
			if (Arg < argc)
			{
				Output = argv[Arg++];
			}
			else
			{
				break;
			}
		}
		else if (!strcmp(argv[Arg], "-media"))
		{
			Arg++;
			if (Arg < argc)
			{
				Media = argv[Arg++];
			}
			else
			{
				break;
			}
		}
		else if (!strcmp(argv[Arg], "-size"))
		{
			Arg++;
			if (Arg < argc)
			{
				char *Size = argv[Arg++];
				sscanf(Size, "%dx%d", &SaveOptions.Width, &SaveOptions.Height);
			}
			else
			{
				break;
			}
		}
		else if (!strcmp(argv[Arg], "-audio_bitrate"))
		{
			Arg++;
			if (Arg < argc)
			{
				SaveOptions.AudioBitRate = atoi(argv[Arg++]);
			}
			else
			{
				break;
			}
		}
		else if (!strcmp(argv[Arg], "-video_bitrate"))
		{
			Arg++;
			if (Arg < argc)
			{
				SaveOptions.VideoBitRate = atoi(argv[Arg++]);
			}
			else
			{
				break;
			}
		}
		else if (!strcmp(argv[Arg], "-audio_codec"))
		{
			Arg++;
			if (Arg < argc)
			{
				SaveOptions.AudioCodec = argv[Arg++];
			}
			else
			{
				break;
			}
		}
		else if (!strcmp(argv[Arg], "-video_codec"))
		{
			Arg++;
			if (Arg < argc)
			{
				SaveOptions.VideoCodec = argv[Arg++];
			}
			else
			{
				break;
			}
		}
		else
		{
			break;
		}
	}

	if (Arg != argc || Input == NULL || Output == NULL)
	{
		std::cout << "Usage: " << argv[0] << " [options] -input script_file -output video_file" << std::endl << std::endl;
		std::cout << "Available options:" << std::endl;

		std::cout << "-start time" << std::endl;
		std::cout << "-length duration" << std::endl;

		std::cout << "-quality 0 (standard) | -1 (low) | 1 (high)" << std::endl;
		std::cout << "-downsample 0|1|2" << std::endl;
		std::cout << "-size widthxheight" << std::endl;
		std::cout << "-media directory" << std::endl;

		std::cout << "-disable_audio" << std::endl;
		std::cout << "-disable_video" << std::endl;

		std::cout << "-audio_bitrate bitrate" << std::endl;
		std::cout << "-video_bitrate bitrate" << std::endl;

		std::cout << "-audio_codec name" << std::endl;
		std::cout << "-video_codec name" << std::endl;
		return -1;
	}
#ifdef __BORLANDC__
	TImg::MemoryManager = new TWindowsMM();
#endif
	try
	{
		try
		{
			LastProgressPos = -1;
			LastProgressTime = -1;
			TEditor Editor;
			Editor.Load(Input, Media);
			Editor.Save(Output, SaveOptions, Progress);
			std::cout << std::endl;
		}

		catch (TError &E)
		{
			std::cerr << "Error: " << E.Message << std::endl;
			return -1;
		}
		catch (TAVFile::AVFileError &E)
		{
			std::cerr << "AVFileError: " << E.Message << std::endl;
			return -1;
		}
		catch (...)
		{
			std::cerr << "Unknown Error" << std::endl;
			return -1;
		}

		if (TImg::MemoryManager)
		{
			delete TImg::MemoryManager;
		}
	}
	catch (...)
	{
#ifdef __BORLANDC__  
		if (TImg::MemoryManager)
		{
			delete TImg::MemoryManager;
		}
#endif			
	}
	return 0;
}
//---------------------------------------------------------------------------

