class FILENAME			// To avoid malloc and memory leaks
{
      private:
	char *m_name[4];
	void createThreeNames (char *filename);
	char *createName (char *folder, char *file);
      public:
	  FILE * Open (char *name, char *flags);
	FILE *Create (char *name, char *flags);
	i32 Rename (char *oldname, char *newname);
	i32 Unlink (char *name);
	  FILENAME (void);
	 ~FILENAME (void);
};

FILENAME::FILENAME (void)
{
	m_name[0] = NULL;
	m_name[1] = NULL;
	m_name[2] = NULL;
	m_name[3] = NULL;
}

FILENAME::~FILENAME (void)
{
	int i;
	for (i = 0; i < 4; i++)
	{
		if (m_name[i] != NULL)
			free (m_name[i]);
		m_name[i] = NULL;
	};
}

char *
FILENAME::createName (char *folder, char *file)
{
	char *result;
	if (file == NULL)
		return NULL;
	if (strlen (file) == 0)
		return NULL;
	if (folder == NULL || *folder == '\0')
	{
		result = (char *) malloc (strlen (file) + 1);
		if (result != NULL)
			strcpy (result, file);
	}
	else
	{
		result = (char *) malloc (strlen (folder) + strlen (file) + 2);
		if (result != NULL)
		{
			strcpy (result, folder);
			/* If file is used, then folder better be a real folder and not another filename. */
			if(file) {strcat (result,"/"); strcat (result, file);}
		};
	};
	return result;
}


void
FILENAME::createThreeNames (char *filename)
{
	if (m_name[0] != NULL)
	{
		free (m_name[0]);
		m_name[0] = NULL;
	};
	if (folderSavedGame != NULL)
		m_name[0] = createName (folderSavedGame, filename);
//	g_warning ("Ick, ick, ick --gamsav: %s", folderSavedGame);
	if (m_name[1] != NULL)
	{
		free (m_name[1]);
		m_name[1] = NULL;
	};
	if (folderParentName != NULL)
		m_name[1] = createName (folderParentName, filename);
//	g_warning ("Ick, ick, ick --directory: %s", folderParentName);
	if (m_name[2] != NULL)
	{
		free (m_name[2]);
		m_name[2] = NULL;
	};
	if (folderName != NULL)
		m_name[2] = createName (folderName, filename);
//	g_warning ("Ick, ick, ick --module: %s", folderName);
	if (m_name[3] != NULL)
	{
		free (m_name[3]);
		m_name[3] = NULL;
	};
	m_name[3] = createName (root, filename);
}

FILE *
FILENAME::Open (char *name, char *flags)
{
	FILE *result = NULL;
	int i;
	createThreeNames (name);
	for (i = 0; i < 4; i++)
	{
		if (m_name[i] == NULL)
			continue;
		result = UI_fopen (m_name[i], flags);
//		g_warning ("Ick, ick, ick: %s\n", m_name[i]);
		if (result != NULL)
		{
			if (TimerTraceActive)
				fprintf (GETFILE (TraceFile), "Opened %s\n",
					 m_name[i]);
			return result;
		};
	};
	return NULL;
}


FILE *
FILENAME::Create (char *name, char *flags)
{
	int i;
	createThreeNames (name);
	for (i = 0; i < 4; i++)
	{
		if (m_name[i] == NULL)
			continue;
		return UI_fopen (m_name[i], flags);
	};
	return NULL;
}

i32
FILENAME::Rename (char *oldname, char *newname)
{
	FILENAME newfile;
	int i;
	createThreeNames (oldname);
	newfile.createThreeNames (newname);
	for (i = 0; i < 4; i++)
	{
		if (m_name[i] == NULL)
			continue;
		return rename (m_name[i], newfile.m_name[i]);
	};
	return -1;
}

i32
FILENAME::Unlink (char *name)
{
	int i;
	createThreeNames (name);
	for (i = 0; i < 4; i++)
	{
		if (m_name[i] == NULL)
			continue;
		return UI_DeleteFile (m_name[i]);
	};
	return 0;
}
