// 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/fxbarcode/common/BC_CommonByteMatrix.h"
#include "xfa/fxbarcode/qrcode/BC_QRCoder.h"
#include "xfa/fxbarcode/qrcode/BC_QRCoderErrorCorrectionLevel.h"
#include "xfa/fxbarcode/qrcode/BC_QRCoderMaskUtil.h"
#include "xfa/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;
}
