//---------------------------------------------------------------------------
//	AVFile - library for audio and video files processing
//  2002 - 2007 Stanislav Sumec <sumec@fit.vutbr.cz>
//
//	avfile_utils.cpp
//---------------------------------------------------------------------------

#include <string>
#include <string.h>

#ifdef AVFILE_HAVE_CONFIG
#include "avfile_config.h"
#endif

#include "avfile_utils.h"
#include "avfile.h"

#ifdef AVFILE_USE_DSFILE
#include "dsfile.h"
#endif

#ifdef AVFILE_USE_AVIFILE
#include "avifile.h"
#endif

#ifdef AVFILE_USE_BMPFILE
#include "bmpfile.h"
#endif

#ifdef AVFILE_USE_FFFILE
#include "fffile.h"
#endif

#ifdef AVFILE_USE_DVFILE
#include "dvfile.h"
#endif

//---------------------------------------------------------------------------
#define MAX_DEVICE_COUNT 10

//---------------------------------------------------------------------------
static bool AVFileDefaultPriorities = true;
static int AVFilePriorityTable[MAX_DEVICE_COUNT] = {0};

//---------------------------------------------------------------------------
TAVFile* AVFileNew(int Priority)
{
	switch (Priority)
	{
#ifdef AVFILE_USE_AVIFILE
	case AVFILE_USE_AVIFILE:
		return new TAVIFile();
#endif
#ifdef AVFILE_USE_DSFILE
	case AVFILE_USE_DSFILE:
		return new TDSFile();
#endif
#ifdef AVFILE_USE_BMPFILE
	case AVFILE_USE_BMPFILE:
		return new TBMPFile();
#endif
#ifdef AVFILE_USE_FFFILE
	case AVFILE_USE_FFFILE:
		return new TFFFile();
#endif
#ifdef AVFILE_USE_DVFILE
	case AVFILE_USE_DVFILE:
		return new TDVFile();
#endif
	default:
		return NULL;
	}
}

//---------------------------------------------------------------------------
TAVFile* AVFileOpen(const char *FileName, int Type)
{
	int Priority = 0;
	TAVFile *File = NULL, *Secondary = NULL;
	do
	{
		if (AVFileDefaultPriorities)
		{
			File = AVFileNew(Priority++);
		}
		else
		{
			File = AVFileNew(AVFilePriorityTable[Priority++]);
		}

		if (File)
		{
			File->Open(FileName, TAVFile::omRead, Type, false);
			int OpenType = File->GetOpenType();
			int OpenMode = File->GetOpenMode();

			bool Free = true;
			if (OpenMode == TAVFile::omRead && OpenType != TAVFile::otNone)
			{
				if (Type == TAVFile::otVideoAudio && (OpenType & TAVFile::otVideo) == TAVFile::otNone)
				{
					if (!Secondary)
					{
						Secondary = File;
						File = NULL;
						Free = false;
					}
				}
				else
				{
					Free = false;
				}
			}

			if (Free)
			{
				delete File;
				File = NULL;
			}
		}
	}
	while (!File && Priority < MAX_DEVICE_COUNT);

	if (!File)
	{
		File = Secondary;
	}
	else if (Secondary)
	{
		delete Secondary;
	}

	return File;
}

//---------------------------------------------------------------------------
TAVFile* AVFileCreate(const char *FileName)
{
	std::string Ext;
	int l = strlen(FileName);
	for (int i = l - 1; i >= 0 && FileName[i] != '.'; i--)
	{
		Ext = char(FileName[i]) + Ext;
	}
	int Priority = 0;
	TAVFile *File = NULL;
	do
	{
		File = AVFileNew(Priority++);
		if (!File)
		{
			break;
		}
		if (!File->FileTypeSupported(Ext.c_str()))
		{
			delete File;
			File = NULL;
		}
	}
	while (!File);
	if (!File)
	{
		File = AVFileNew(0);
	}
	return File;
}

//---------------------------------------------------------------------------
TAVFileDeviceList AVFileGetDeviceList()
{
	TAVFileDeviceList List;
	for (int i = 0; i < MAX_DEVICE_COUNT; i++)
	{
		TAVFile *File = AVFileNew(i);
		if (File)
		{
			TAVFileDevice Device;
			Device.Device = i;
			Device.Description = File->GetDescription();
			List.push_back(Device);
			delete File;
		}
	}
	return List;
}

//---------------------------------------------------------------------------
void AVFileInitPriorityTable()
{
	for (int i = 0; i < MAX_DEVICE_COUNT; i++)
	{
		AVFilePriorityTable[i] = i;
	}
	AVFileDefaultPriorities = false;
}

//---------------------------------------------------------------------------
void AVFileSetDevicePriority(int Device, int Priority)
{
	if (AVFileDefaultPriorities)
	{
		AVFileInitPriorityTable();
	}

	int PreviousPriority = 0;
	while (PreviousPriority < MAX_DEVICE_COUNT && AVFilePriorityTable[PreviousPriority] != Device)
	{
		PreviousPriority++;
	}

	if (PreviousPriority < MAX_DEVICE_COUNT)
	{
		AVFilePriorityTable[PreviousPriority] = -1;
	}

	if (Priority >= 0 && Priority < MAX_DEVICE_COUNT)
	{
		AVFilePriorityTable[Priority] = Device;
	}
}

//---------------------------------------------------------------------------
int AVFileGetDevicePriority(int Device)
{
	if (AVFileDefaultPriorities)
	{
		AVFileInitPriorityTable();
	}

	int Priority = 0;
	while (Priority < MAX_DEVICE_COUNT && AVFilePriorityTable[Priority] != Device)
	{
		Priority++;
	}

	if (Priority < MAX_DEVICE_COUNT)
	{
		return Priority;
	}
	else
	{
		return -1;
	}
}

