/*
 * Toolbox for image operations (class-independent)
 *
 * $Date$
 * $Revision$
 *
 */

#include "WImage/tools.h"
#include <cfloat>
#include <cmath>
#include <cctype>
#include <cstring>
#include <cstdio>
#include <stdexcept>

#if !(defined __WATCOMC__ && __WATCOMC__ < 1230)
using namespace std;
#endif


pixel
tools_coeff2pixel (coeff c)
{
  c = (c < 0? 0: c);
  return (pixel)(c + 0.5);
}

int
tools_coeff2int ( coeff c)
{
  return (int)(c + 0.5); 
}

bool
tools_equals (double d1, double d2)
{
  return (fabs (d1 - d2) < DBL_EPSILON);
}

bool
tools_epsilons (double d1, double d2, double epsilon)
{
  return !(((d1 > d2) && (d1 - d2 > epsilon)) || (d2 - d1 > epsilon));
}

bool
tools_areaFromString (char a1, char a2, area &result)
{
  char buf[3];
  buf[0] = a1;
  buf[1] = a2;
  buf[2] = '\0';
  return tools_areaFromString (buf, result);
}

bool
tools_areaFromString (char *a, area &result)
{
  if (strlen (a) != 2)
    {
      return false;
    }
  char buf[3];
  
  for (int i = 0; i < (int)strlen (a); i++)
    {
      buf[i] = toupper (a[i]);
    }
  buf[strlen (a)] = '\0';
  if (strcmp (buf, "LL") == 0)
    {
      result = LL;
    }
  else if (strcmp (buf, "HL") == 0)
    {
      result = HL;
    }
  else if (strcmp (buf, "LH") == 0)
    {
      result = LH;
    }
  else if (strcmp (buf, "HH") == 0)
    {
      result = HH;
    }
  else
    {
      return false;
    }
  return true;
}

const char *
tools_areaToString (const area a)
{
  static const char *names[HH + 1] = {"LL", "HL", "LH", "HH"};
  return names[a];
}


bool
tools_powerOfTwo (int value, int &power)
{
  int i;
  
  for (i = 1; i < value; power++, i = MUL2 (i))
    {
    }

  return (i == value);
}

int
tools_startFromCenter (int pos, int length)
{
  return pos - (length + 1) / 2 + 1;
}

#ifndef _WIN32_WCE
int 
tools_fileSize (const char *fname)
{
  FILE *fp = fopen (fname, "rb");
  if (fp == NULL)
    {
      throw std::invalid_argument ("tools_fileSize: Could not open file.");
    }
  rewind (fp);
  long start = ftell (fp);
  fseek (fp, 0, SEEK_END);
  long end = ftell (fp);
  fclose (fp);
  return end - start;
}
#endif

const area areas [areaINVALID] = { LL, HL, LH, HH };
