class FILENAME // To avoid malloc and memory leaks
{
private:
  char *m_name[3];
  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;
}

FILENAME::~FILENAME(void)
{
  i32 i;
  for (i=0; i<3; i++)
  {
    if (m_name[i] != NULL) UI_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)
  {
    result = (char *)UI_malloc(strlen(file) + 1, MALLOC045);
    if (result != NULL) strcpy(result, file);
  }
  else
  {
    result = (char *)UI_malloc(strlen(folder) + strlen(file) +1, MALLOC046);
    if (result != NULL)
    {
      strcpy(result,folder);
      strcat(result,file);
    };
  };
#ifdef _MSVC_INTEL
  return strlwr(result);
#endif
#ifdef _LINUX
  return result;
#endif
}


void FILENAME::createThreeNames(char *filename)
{
  if (m_name[0] != NULL)
  {
    UI_free(m_name[0]);
    m_name[0] = NULL;
  };
  if (folderName!=NULL) m_name[0] = createName(folderName, filename);
  if (m_name[1] != NULL) 
  {
    UI_free(m_name[1]);
    m_name[1] = NULL;
  };
  if (folderParentName != NULL) m_name[1] = createName(folderParentName, filename);
  if (m_name[2] != NULL) 
  {
    UI_free(m_name[2]);
    m_name[2] = NULL;
  };
  if (root != NULL) m_name[2] = createName(root, filename);
}

FILE *FILENAME::Open(char *name, char *flags)
{
  FILE *result = NULL;
  i32 i;
  createThreeNames(name);
  for (i=0; i<3; i++)
  {
    if (m_name[i] == NULL) continue;
    result = UI_fopen(m_name[i], flags);
    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)
{
  i32 i;
  createThreeNames(name);
  for (i=0; i<3; 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;
  i32 i;
  createThreeNames(oldname);
  newfile.createThreeNames(newname);
  for (i=0; i<3; i++)
  {
    if (m_name[i] == NULL) continue;
    return rename(m_name[i], newfile.m_name[i]);
  };
  return -1;
}

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

