// 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/fx_basic.h"
#include "core/fxcrt/fx_ext.h"

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

namespace {

const int kDefaultIntValue = 0;

}  // namespace

bool FX_atonum(const CFX_ByteStringC& strc, void* pData) {
  if (strc.Find('.') != -1) {
    FX_FLOAT* pFloat = static_cast<FX_FLOAT*>(pData);
    *pFloat = FX_atof(strc);
    return false;
  }

  // Note, numbers in PDF are typically of the form 123, -123, etc. But,
  // for things like the Permissions on the encryption hash the number is
  // actually an unsigned value. We use a uint32_t so we can deal with the
  // unsigned and then check for overflow if the user actually signed the value.
  // The Permissions flag is listed in Table 3.20 PDF 1.7 spec.
  pdfium::base::CheckedNumeric<uint32_t> integer = 0;
  bool bNegative = false;
  bool bSigned = false;
  int cc = 0;
  if (strc[0] == '+') {
    cc++;
    bSigned = true;
  } else if (strc[0] == '-') {
    bNegative = true;
    bSigned = true;
    cc++;
  }

  while (cc < strc.GetLength() && std::isdigit(strc[cc])) {
    integer = integer * 10 + FXSYS_toDecimalDigit(strc.CharAt(cc));
    if (!integer.IsValid())
      break;
    cc++;
  }

  // We have a sign, and the value was greater then a regular integer
  // we've overflowed, reset to the default value.
  if (bSigned) {
    if (bNegative) {
      if (integer.ValueOrDefault(kDefaultIntValue) >
          static_cast<uint32_t>(std::numeric_limits<int>::max()) + 1) {
        integer = kDefaultIntValue;
      }
    } else if (integer.ValueOrDefault(kDefaultIntValue) >
               static_cast<uint32_t>(std::numeric_limits<int>::max())) {
      integer = kDefaultIntValue;
    }
  }

  // Switch back to the int space so we can flip to a negative if we need.
  int value = static_cast<int>(integer.ValueOrDefault(kDefaultIntValue));
  if (bNegative)
    value = -value;

  int* pInt = static_cast<int*>(pData);
  *pInt = value;
  return true;
}

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 FXSYS_FractionalScaleCount() {
  return FX_ArraySize(fraction_scales);
}

FX_FLOAT FXSYS_FractionalScale(size_t scale_factor, int value) {
  return fraction_scales[scale_factor] * value;
}

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++;
  }
  int scale = 0;
  if (cc < len && strc[cc] == '.') {
    cc++;
    while (cc < len) {
      value +=
          FXSYS_FractionalScale(scale, FXSYS_toDecimalDigit(strc.CharAt(cc)));
      scale++;
      if (scale == FXSYS_FractionalScaleCount())
        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

FX_FileHandle* 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
  return opendir(path);
#endif
}

bool FX_GetNextFile(FX_FileHandle* handle,
                    CFX_ByteString* filename,
                    bool* bFolder) {
  if (!handle)
    return false;

#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  if (handle->m_bEnd)
    return false;

  *filename = handle->m_FindData.cFileName;
  *bFolder =
      (handle->m_FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
  if (!FindNextFileA(handle->m_Handle, &handle->m_FindData))
    handle->m_bEnd = true;
  return true;
#elif defined(__native_client__)
  abort();
  return false;
#else
  struct dirent* de = readdir(handle);
  if (!de)
    return false;
  *filename = de->d_name;
  *bFolder = de->d_type == DT_DIR;
  return true;
#endif
}

void FX_CloseFolder(FX_FileHandle* handle) {
  if (!handle)
    return;

#if _FXM_PLATFORM_ == _FXM_PLATFORM_WINDOWS_
  FindClose(handle->m_Handle);
  delete handle;
#else
  closedir(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 =
      static_cast<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;
}
