//---------------------------------------------------------------------------
#include <string.h>
#include <limits.h>
#include <iostream>
#include <string>
#include <vector>
#pragma hdrstop
#include "Error.h"
#include "ImpExp.h"

//---------------------------------------------------------------------------
static int LastProgressPos;

void Progress(int Pos, int Max) {
	int ProgressPos = (Pos * 100) / Max;
	if (ProgressPos != LastProgressPos)
	{
		std::cout << "\r" << Pos << "/" << Max << " " << ProgressPos << "%";
		std::cout.flush();
		LastProgressPos = ProgressPos;
	}
}
//---------------------------------------------------------------------------
#pragma argsused

int main(int argc, char* argv[]) {
	int Arg = 1;
	std::vector<std::string> Input, InputPL, InputAnvil;
	std::vector<int> InputForceCamera;
	char *Output = NULL;
	char *CreateMedia = NULL;
	bool UpdateMedia = false;
	char *Config = NULL, *Meeting = NULL;
	bool UseCameraOffset = false;
	char *OutputPL = NULL;
	std::vector<char*> MediaPath;

	while (Arg < argc)
	{
		if (!strcmp(argv[Arg], "-input"))
		{
			Arg++;
			if (Arg < argc)
			{
				Input.push_back(argv[Arg++]);
				InputForceCamera.push_back(-1);
			}
			else
				break;
		}
		else if (!strcmp(argv[Arg], "-fc"))
		{
			Arg++;
			if (Arg < argc)
			{
				int Camera = atoi(argv[Arg++]);
				if (!InputForceCamera.empty())
				InputForceCamera.back() = Camera;
			}
			else
				break;
		}
		else if (!strcmp(argv[Arg], "-input_prolog"))
		{
			Arg++;
			if (Arg < argc)
			{
				InputPL.push_back(argv[Arg++]);
			}
			else
				break;
		}
		else if (!strcmp(argv[Arg], "-ia"))
		{
			Arg++;
			if (Arg < argc)
			{
				InputAnvil.push_back(argv[Arg++]);
			}
			else
				break;
		}
		else if (!strcmp(argv[Arg], "-output"))
		{
			Arg++;
			if (Arg < argc)
			{
				Output = argv[Arg++];
			}
			else
				break;
		}
		else if (!strcmp(argv[Arg], "-output_prolog"))
		{
			Arg++;
			if (Arg < argc)
			{
				OutputPL = argv[Arg++];
			}
			else
				break;
		}
		else if (!strcmp(argv[Arg], "-cm"))
		{
			Arg++;
			if (Arg < argc)
			{
				CreateMedia = argv[Arg++];
			}
			else
				break;
		}
		else if (!strcmp(argv[Arg], "-update_sources"))
		{
			Arg++;
			UpdateMedia = true;
		}
		else if (!strcmp(argv[Arg], "-c"))
		{
			Arg++;
			if (Arg < argc)
			{
				Config = argv[Arg++];
			}
			else
				break;
			if (Arg < argc)
			{
				Meeting = argv[Arg++];
			}
			else
				break;
		}
		else if (!strcmp(argv[Arg], "-uco"))
		{
			Arg++;
			UseCameraOffset = true;
		}
		else if (!strcmp(argv[Arg], "-media"))
		{
			Arg++;
			if (Arg < argc)
			{
				MediaPath.push_back(argv[Arg++]);
			}
			else
				break;
		}
		else
			break;
	}

	if (Arg != argc ||
		(Input.empty() && InputPL.empty() && InputAnvil.empty() && CreateMedia == NULL) ||
		(Output == NULL && OutputPL == NULL))
	{
		std::cout << "Usage: " << argv[0] << " [options] [-input input.xml] [-input_prolog input.pl] [-output output.xml] [-output_prolog output.pl]" << std::endl << std::endl;
		std::cout << "Available options:" << std::endl;
		std::cout << "-update_sources" << std::endl;
		std::cout << "-media directory" << std::endl;
		return -1;
	}

	try
	{
		LastProgressPos = -1;
		int Max = Input.size() + InputPL.size() + InputAnvil.size(),
			Pos = 0;
		if (Output != NULL)
			Max++;
		if (OutputPL != NULL)
			Max++;
		if (CreateMedia != NULL)
			Max++;
		if (UpdateMedia)
			Max++;
		if (Config && Meeting)
			Max++;
		Progress(Pos, Max);

		TImpExp ImpExp;

		for (unsigned int i = 0; i < MediaPath.size(); i++)
		{
			ImpExp.AddMediaPath(MediaPath[i]);
		}

		if (CreateMedia != NULL)
		{
			ImpExp.CreateMedia(CreateMedia);
			Progress(++Pos, Max);
		}

		for (unsigned int i = 0; i < Input.size(); i++)
		{
			ImpExp.Load(Input[i].c_str(), i > 0 || CreateMedia != NULL, UseCameraOffset, InputForceCamera[i]);
			Progress(++Pos, Max);
		}
		for (unsigned int i = 0; i < InputPL.size(); i++)
		{
			ImpExp.ImportProlog(InputPL[i].c_str());
			Progress(++Pos, Max);
		}
		for (unsigned int i = 0; i < InputAnvil.size(); i++)
		{
			ImpExp.ImportAnvil(InputAnvil[i].c_str());
			Progress(++Pos, Max);
		}

		if (Config && Meeting)
		{
			ImpExp.UpdateConfig(Config, Meeting);
			Progress(++Pos, Max);
		}

		if (UpdateMedia)
		{
			ImpExp.UpdateMedia();
			Progress(++Pos, Max);
		}

		if (Output != NULL)
		{
			ImpExp.Save(Output);
			Progress(++Pos, Max);
		}
		if (OutputPL != NULL)
		{
			ImpExp.ExportProlog(OutputPL);
			Progress(++Pos, Max);
		}
		std::cout << std::endl;
	}
	catch (TError &E)
	{
		std::cerr << "Error: " << E.Message << std::endl;
		return -1;
	}
	catch (...)
	{
		std::cerr << "Unknown Error" << std::endl;
		return -1;
	}

	return 0;
}
//---------------------------------------------------------------------------
