// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fxcrt/include/fx_basic.h"
#include "core/fxcrt/include/fx_ext.h"

#if _FXM_PLATFORM_ != _FXM_PLATFORM_WINDOWS_
#include <dirent.h>
#include <sys/types.h>
#else
#include <direct.h>
#endif

#include <algorithm>
#include <cctype>
#include <memory>

void FX_atonum(const CFX_ByteStringC& strc, FX_BOOL& bInteger, void* pData) {
  if (strc.Find('.') == -1) {
    bInteger = TRUE;
    int cc = 0;
    pdfium::base::CheckedNumeric<int> integer = 0;
    FX_STRSIZE len = strc.GetLength();
    bool bNegative = false;
    if (strc[0] == '+') {
      cc++;
    } else if (strc[0] == '-') {
      bNegative = true;
      cc++;
    }
    while (cc < len && std::isdigit(strc[cc])) {
      integer = integer * 10 + FXSYS_toDecimalDigit(strc.CharAt(cc));
      if (!integer.IsValid())
        break;
      cc++;
    }
    if (bNegative) {
      integer = -integer;
    }
    *(int*)pData = integer.ValueOrDefault(0);
  } else {
    bInteger = FALSE;
    *(FX_FLOAT*)pData = FX_atof(strc);
  }
}

FX_FLOAT FX_atof(const CFX_ByteStringC& strc) {
  if (strc.IsEmpty())
    return 0.0;

  int cc = 0;
  bool bNegative = false;
  int len = strc.GetLength();
  if (strc[0] == '+') {
    cc++;
  } else if (strc[0] == '-') {
    bNegative = TRUE;
    cc++;
  }
  while (cc < len) {
    if (strc[cc] != '+' && strc[cc] != '-') {
      break;
    }
    cc++;
  }
  FX_FLOAT value = 0;
  while (cc < len) {
    if (strc[cc] == '.') {
      break;
    }
    value = value * 10 + FXSYS_toDecimalDigit(strc.CharAt(cc));
    cc++;
  }
  static const FX_FLOAT fraction_scales[] = {
      0.1f,         0.01f,         0.001f,        0.0001f,
      0.00001f,     0.000001f,     0.0000001f,    0.00000001f,
      0.000000001f, 0.0000000001f, 0.00000000001f};
  int scale = 0;
  if (cc < len && strc[cc] == '.') {
    cc++;
    while (cc < len) {
      value += fraction_scales[scale] * FXSYS_toDecimalDigit(strc.CharAt(cc));
      scale++;
      if (scale == FX_ArraySize(fraction_scales))
        break;
      cc++;
    }
  }
  return bNegative ? -value : value;
}

#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_ && _MSC_VER < 1900
void FXSYS_snprintf(char* str,
                    size_t size,
                    _Printf_format_string_ const char* fmt,
                    ...) {
  va_list ap;
  va_start(ap, fmt);
  FXSYS_vsnprintf(str, size, fmt, ap);
  va_end(ap);
}
void FXSYS_vsnprintf(char* str, size_t size, const char* fmt, va_list ap) {
  (void)_vsnprintf(str, size, fmt, ap);
  if (size) {
    str[size - 1] = 0;
  }
}
#endif  // _FXM_PLATFORM_WINDOWS_ && _MSC_VER < 1900

#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
class CFindFileData {
 public:
  virtual ~CFindFileData() {}
  HANDLE m_Handle;
  FX_BOOL m_bEnd;
};
class CFindFileDataA : public CFindFileData {
 public:
  virtual ~CFindFileDataA() {}
  WIN32_FIND_DATAA m_FindData;
};
class CFindFileDataW : public CFindFileData {
 public:
  virtual ~CFindFileDataW() {}
  WIN32_FIND_DATAW m_FindData;
};
#endif

void* FX_OpenFolder(const FX_CHAR* path) {
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  std::unique_ptr<CFindFileDataA> pData(new CFindFileDataA);
  pData->m_Handle = FindFirstFileExA((CFX_ByteString(path) + "/*.*").c_str(),
                                     FindExInfoStandard, &pData->m_FindData,
                                     FindExSearchNameMatch, nullptr, 0);
  if (pData->m_Handle == INVALID_HANDLE_VALUE)
    return nullptr;

  pData->m_bEnd = FALSE;
  return pData.release();
#else
  DIR* dir = opendir(path);
  return dir;
#endif
}

void* FX_OpenFolder(const FX_WCHAR* path) {
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  std::unique_ptr<CFindFileDataW> pData(new CFindFileDataW);
  pData->m_Handle = FindFirstFileExW((CFX_WideString(path) + L"/*.*").c_str(),
                                     FindExInfoStandard, &pData->m_FindData,
                                     FindExSearchNameMatch, nullptr, 0);
  if (pData->m_Handle == INVALID_HANDLE_VALUE)
    return nullptr;

  pData->m_bEnd = FALSE;
  return pData.release();
#else
  DIR* dir = opendir(CFX_ByteString::FromUnicode(path).c_str());
  return dir;
#endif
}
FX_BOOL FX_GetNextFile(void* handle,
                       CFX_ByteString& filename,
                       FX_BOOL& bFolder) {
  if (!handle) {
    return FALSE;
  }
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  CFindFileDataA* pData = (CFindFileDataA*)handle;
  if (pData->m_bEnd)
    return FALSE;

  filename = pData->m_FindData.cFileName;
  bFolder = pData->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
  if (!FindNextFileA(pData->m_Handle, &pData->m_FindData))
    pData->m_bEnd = TRUE;
  return TRUE;
#elif defined(__native_client__)
  abort();
  return FALSE;
#else
  struct dirent* de = readdir((DIR*)handle);
  if (!de) {
    return FALSE;
  }
  filename = de->d_name;
  bFolder = de->d_type == DT_DIR;
  return TRUE;
#endif
}
FX_BOOL FX_GetNextFile(void* handle,
                       CFX_WideString& filename,
                       FX_BOOL& bFolder) {
  if (!handle) {
    return FALSE;
  }
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  CFindFileDataW* pData = (CFindFileDataW*)handle;
  if (pData->m_bEnd) {
    return FALSE;
  }
  filename = pData->m_FindData.cFileName;
  bFolder = pData->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
  if (!FindNextFileW(pData->m_Handle, &pData->m_FindData)) {
    pData->m_bEnd = TRUE;
  }
  return TRUE;
#elif defined(__native_client__)
  abort();
  return FALSE;
#else
  struct dirent* de = readdir((DIR*)handle);
  if (!de) {
    return FALSE;
  }
  filename = CFX_WideString::FromLocal(de->d_name);
  bFolder = de->d_type == DT_DIR;
  return TRUE;
#endif
}
void FX_CloseFolder(void* handle) {
  if (!handle) {
    return;
  }
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  CFindFileData* pData = (CFindFileData*)handle;
  FindClose(pData->m_Handle);
  delete pData;
#else
  closedir((DIR*)handle);
#endif
}
FX_WCHAR FX_GetFolderSeparator() {
#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  return '\\';
#else
  return '/';
#endif
}

CFX_Matrix_3by3 CFX_Matrix_3by3::Inverse() {
  FX_FLOAT det =
      a * (e * i - f * h) - b * (i * d - f * g) + c * (d * h - e * g);
  if (FXSYS_fabs(det) < 0.0000001)
    return CFX_Matrix_3by3();

  return CFX_Matrix_3by3(
      (e * i - f * h) / det, -(b * i - c * h) / det, (b * f - c * e) / det,
      -(d * i - f * g) / det, (a * i - c * g) / det, -(a * f - c * d) / det,
      (d * h - e * g) / det, -(a * h - b * g) / det, (a * e - b * d) / det);
}

CFX_Matrix_3by3 CFX_Matrix_3by3::Multiply(const CFX_Matrix_3by3& m) {
  return CFX_Matrix_3by3(
      a * m.a + b * m.d + c * m.g, a * m.b + b * m.e + c * m.h,
      a * m.c + b * m.f + c * m.i, d * m.a + e * m.d + f * m.g,
      d * m.b + e * m.e + f * m.h, d * m.c + e * m.f + f * m.i,
      g * m.a + h * m.d + i * m.g, g * m.b + h * m.e + i * m.h,
      g * m.c + h * m.f + i * m.i);
}

CFX_Vector_3by1 CFX_Matrix_3by3::TransformVector(const CFX_Vector_3by1& v) {
  return CFX_Vector_3by1(a * v.a + b * v.b + c * v.c,
                         d * v.a + e * v.b + f * v.c,
                         g * v.a + h * v.b + i * v.c);
}

uint32_t GetBits32(const uint8_t* pData, int bitpos, int nbits) {
  ASSERT(0 < nbits && nbits <= 32);
  const uint8_t* dataPtr = &pData[bitpos / 8];
  int bitShift;
  int bitMask;
  int dstShift;
  int bitCount = bitpos & 0x07;
  if (nbits < 8 && nbits + bitCount <= 8) {
    bitShift = 8 - nbits - bitCount;
    bitMask = (1 << nbits) - 1;
    dstShift = 0;
  } else {
    bitShift = 0;
    int bitOffset = 8 - bitCount;
    bitMask = (1 << std::min(bitOffset, nbits)) - 1;
    dstShift = nbits - bitOffset;
  }
  uint32_t result = (uint32_t)(*dataPtr++ >> bitShift & bitMask) << dstShift;
  while (dstShift >= 8) {
    dstShift -= 8;
    result |= *dataPtr++ << dstShift;
  }
  if (dstShift > 0) {
    bitShift = 8 - dstShift;
    bitMask = (1 << dstShift) - 1;
    result |= *dataPtr++ >> bitShift & bitMask;
  }
  return result;
}
