/*
 * Implementation of class FileName
 *
 * $Date$
 * $Revision$
 *
 */

#include "WImage/debug.h"
#include "WImage/FileName.hh"
#include <cstring>
#include <cctype>
#ifndef _WIN32_WCE
#include <iostream>
#endif
#include <stdexcept>
#include <cassert>
#include "WImage/miscdefs.h"

#if !(defined __WATCOMC__ && __WATCOMC__ < 1230)
using namespace std;
#else
#include <string>
#endif

FileName::FileName (char const *name)
{
  m_isdos = false;

  if (name == NULL)
    {
      throw invalid_argument ("FileName: NULL reference to filename.");
    }
  char const *dos = strrchr (name, '\\');
  char const *unx = strrchr (name, '/');
  char const  *extn = name;
  char const *base = name;
  int size;

  size = strlen (name) + 1;
  m_fname = NEW (char[size]);
  strcpy (m_fname, name);

  if (dos != NULL)
    {
      m_isdos = true;
    }

  if (dos != NULL || unx != NULL)
    {
      base = dos > unx? dos: unx;
    }

  base++;
  size -= strlen (base);
  m_dirname = NEW (char[size]);
  strncpy (m_dirname, name, size);
  m_dirname[size-1] = '\0';


  extn = strrchr (base, '.');

  if (extn == NULL)
    {
      m_extension = NEW (char[1]);
      m_extension[0] = '\0';
      m_basename=NEW (char[strlen(base)+1]);
      strcpy(m_basename, base);
    }
  else
    {
      m_extension = NEW (char[strlen (extn) + 1]);
      strcpy (m_extension, extn);

      size = extn - base + 1;
      assert(extn + 1 > base);
      m_basename = NEW (char[size]);
      strncpy (m_basename, base, size);
      m_basename[size-1] = '\0';
    }

  guessext ();
}

FileName::~FileName (void)
{
  DELETEAR (m_fname);
  DELETEAR (m_dirname);
  DELETEAR (m_basename);
  DELETEAR (m_extension);
}

void
FileName::guessext (void)
{
  if (isext (".pgm"))
    {
      m_ftype = fn_pgm;
    }
  else if (isext (".raw"))
    {
      m_ftype = fn_raw;
    }
#ifdef PFI
  else if (isext (".pfi"))
    {
      m_ftype = fn_pfi;
    }
#endif
  else if (isext (".ppm"))
    {
      m_ftype = fn_ppm;
    }
#ifdef JPEG
  else if (isext (".jpg") || isext (".jpeg"))
    {
      m_ftype = fn_jpg;
    }
#endif
  else if (isext (".vid"))
    {
      m_ftype = fn_vid;
    }
  else if (isext (".avi"))
    {
      m_ftype = fn_avi;
    }
  else if (isext (".png"))
    {
      m_ftype = fn_png;
    }
  else if (isext (".gif"))
    {
      m_ftype = fn_png;
    }
  else
    {
      m_ftype = fn_unknown;
    }
}

bool
FileName::isext (const char *ext) const
{
  int i;
  for (i = 0; ext[i] != '\0' && m_extension[i] != '\0'; i++)
    {
      if (tolower ((unsigned char)ext[i])
          != (tolower ((unsigned char)m_extension[i])))
        {
          return false;
        }
    }
  return ext[i] == '\0' && m_extension[i] == '\0';
}

void
FileName::toext (const char *ext)
{
  DELETEAR (m_extension);
  m_extension = NEW (char[strlen (ext) + 1]);
  strcpy (m_extension, ext);
  guessext ();
}

const char *
FileName::guessedMimeType (void) const
{
  switch (m_ftype)
    {
    case fn_pgm:
      return "image/x-portable-graymap";
    case fn_ppm:
      return "image/x-portable-pixmap";
    case fn_jpg:
      return "image/jpeg";
    case fn_png:
      return "image/png";
    case fn_gif:
      return "image/gif";
    case fn_avi:
      return "video/x-msvideo";
    default:
      return "";
    }
}

