// 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
// Original code is licensed as follows:
/*
 * Copyright 2008 ZXing authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "xfa/src/fxbarcode/common/BC_CommonByteMatrix.h"
#include "xfa/src/fxbarcode/qrcode/BC_QRCoder.h"
#include "xfa/src/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
#include "xfa/src/fxbarcode/qrcode/BC_QRCoderMaskUtil.h"
#include "xfa/src/fxbarcode/utils.h"

CBC_QRCoderMaskUtil::CBC_QRCoderMaskUtil() {}
CBC_QRCoderMaskUtil::~CBC_QRCoderMaskUtil() {}
int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1(
    CBC_CommonByteMatrix* matrix) {
  return ApplyMaskPenaltyRule1Internal(matrix, TRUE) +
         ApplyMaskPenaltyRule1Internal(matrix, FALSE);
}

int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule2(
    CBC_CommonByteMatrix* matrix) {
  int32_t penalty = 0;
  uint8_t* array = matrix->GetArray();
  int32_t width = matrix->GetWidth();
  int32_t height = matrix->GetHeight();
  for (int32_t y = 0; y < height - 1; y++) {
    for (int32_t x = 0; x < width - 1; x++) {
      int32_t value = array[y * width + x];
      if (value == array[y * width + x + 1] &&
          value == array[(y + 1) * width + x] &&
          value == array[(y + 1) * width + x + 1]) {
        penalty++;
      }
    }
  }
  return 3 * penalty;
}

int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule3(
    CBC_CommonByteMatrix* matrix) {
  int32_t penalty = 0;
  uint8_t* array = matrix->GetArray();
  int32_t width = matrix->GetWidth();
  int32_t height = matrix->GetHeight();
  for (int32_t y = 0; y < height; ++y) {
    for (int32_t x = 0; x < width; ++x) {
      if (x == 0 &&
          ((y >= 0 && y <= 6) || (y >= height - 7 && y <= height - 1))) {
        continue;
      }
      if (x == width - 7 && (y >= 0 && y <= 6)) {
        continue;
      }
      if (y == 0 &&
          ((x >= 0 && x <= 6) || (x >= width - 7 && x <= width - 1))) {
        continue;
      }
      if (y == height - 7 && (x >= 0 && x <= 6)) {
        continue;
      }
      if (x + 6 < width && array[y * width + x] == 1 &&
          array[y * width + x + 1] == 0 && array[y * width + x + 2] == 1 &&
          array[y * width + x + 3] == 1 && array[y * width + x + 4] == 1 &&
          array[y * width + x + 5] == 0 && array[y * width + x + 6] == 1 &&
          ((x + 10 < width && array[y * width + x + 7] == 0 &&
            array[y * width + x + 8] == 0 && array[y * width + x + 9] == 0 &&
            array[y * width + x + 10] == 0) ||
           (x - 4 >= 0 && array[y * width + x - 1] == 0 &&
            array[y * width + x - 2] == 0 && array[y * width + x - 3] == 0 &&
            array[y * width + x - 4] == 0))) {
        penalty += 40;
      }
      if (y + 6 < height && array[y * width + x] == 1 &&
          array[(y + 1) * width + x] == 0 && array[(y + 2) * width + x] == 1 &&
          array[(y + 3) * width + x] == 1 && array[(y + 4) * width + x] == 1 &&
          array[(y + 5) * width + x] == 0 && array[(y + 6) * width + x] == 1 &&
          ((y + 10 < height && array[(y + 7) * width + x] == 0 &&
            array[(y + 8) * width + x] == 0 &&
            array[(y + 9) * width + x] == 0 &&
            array[(y + 10) * width + x] == 0) ||
           (y - 4 >= 0 && array[(y - 1) * width + x] == 0 &&
            array[(y - 2) * width + x] == 0 &&
            array[(y - 3) * width + x] == 0 &&
            array[(y - 4) * width + x] == 0))) {
        penalty += 40;
      }
    }
  }
  return penalty;
}
int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule4(
    CBC_CommonByteMatrix* matrix) {
  int32_t numDarkCells = 0;
  uint8_t* array = matrix->GetArray();
  int32_t width = matrix->GetWidth();
  int32_t height = matrix->GetHeight();
  for (int32_t y = 0; y < height; ++y) {
    for (int32_t x = 0; x < width; ++x) {
      if (array[y * width + x] == 1) {
        numDarkCells += 1;
      }
    }
  }
  int32_t numTotalCells = matrix->GetHeight() * matrix->GetWidth();
  double darkRatio = (double)numDarkCells / numTotalCells;
  return abs((int32_t)(darkRatio * 100 - 50) / 5) * 5 * 10;
}
FX_BOOL CBC_QRCoderMaskUtil::GetDataMaskBit(int32_t maskPattern,
                                            int32_t x,
                                            int32_t y,
                                            int32_t& e) {
  if (!CBC_QRCoder::IsValidMaskPattern(maskPattern)) {
    e = (BCExceptionInvalidateMaskPattern);
    BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
  }
  int32_t intermediate = 0, temp = 0;
  switch (maskPattern) {
    case 0:
      intermediate = (y + x) & 0x1;
      break;
    case 1:
      intermediate = y & 0x1;
      break;
    case 2:
      intermediate = x % 3;
      break;
    case 3:
      intermediate = (y + x) % 3;
      break;
    case 4:
      intermediate = ((y >> 1) + (x / 3)) & 0x1;
      break;
    case 5:
      temp = y * x;
      intermediate = (temp & 0x1) + (temp % 3);
      break;
    case 6:
      temp = y * x;
      intermediate = (((temp & 0x1) + (temp % 3)) & 0x1);
      break;
    case 7:
      temp = y * x;
      intermediate = (((temp % 3) + ((y + x) & 0x1)) & 0x1);
      break;
    default: {
      e = BCExceptionInvalidateMaskPattern;
      BC_EXCEPTION_CHECK_ReturnValue(e, FALSE);
    }
  }
  return intermediate == 0;
}
int32_t CBC_QRCoderMaskUtil::ApplyMaskPenaltyRule1Internal(
    CBC_CommonByteMatrix* matrix,
    FX_BOOL isHorizontal) {
  int32_t penalty = 0;
  int32_t numSameBitCells = 0;
  int32_t prevBit = -1;
  int32_t width = matrix->GetWidth();
  int32_t height = matrix->GetHeight();
  int32_t iLimit = isHorizontal ? height : width;
  int32_t jLimit = isHorizontal ? width : height;
  uint8_t* array = matrix->GetArray();
  for (int32_t i = 0; i < iLimit; ++i) {
    for (int32_t j = 0; j < jLimit; ++j) {
      int32_t bit = isHorizontal ? array[i * width + j] : array[j * width + i];
      if (bit == prevBit) {
        numSameBitCells += 1;
        if (numSameBitCells == 5) {
          penalty += 3;
        } else if (numSameBitCells > 5) {
          penalty += 1;
        }
      } else {
        numSameBitCells = 1;
        prevBit = bit;
      }
    }
    numSameBitCells = 0;
  }
  return penalty;
}
