// 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 2013 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/BC_ResultPoint.h"
#include "xfa/fxbarcode/common/BC_CommonBitMatrix.h"
#include "xfa/fxbarcode/pdf417/BC_PDF417BoundingBox.h"
#include "xfa/fxbarcode/utils.h"

CBC_BoundingBox::CBC_BoundingBox(CBC_CommonBitMatrix* image,
                                 CBC_ResultPoint* topLeft,
                                 CBC_ResultPoint* bottomLeft,
                                 CBC_ResultPoint* topRight,
                                 CBC_ResultPoint* bottomRight,
                                 int32_t& e) {
  if ((!topLeft && !topRight) || (!bottomLeft && !bottomRight) ||
      (topLeft && !bottomLeft) || (topRight && !bottomRight)) {
    e = BCExceptionNotFoundInstance;
  }
  init(image, topLeft, bottomLeft, topRight, bottomRight);
}
CBC_BoundingBox::CBC_BoundingBox(CBC_BoundingBox* boundingBox) {
  init(boundingBox->m_image, boundingBox->m_topLeft, boundingBox->m_bottomLeft,
       boundingBox->m_topRight, boundingBox->m_bottomRight);
}

CBC_BoundingBox::~CBC_BoundingBox() {
  delete m_topLeft;
  delete m_bottomLeft;
  delete m_topRight;
  delete m_bottomRight;
}

CBC_BoundingBox* CBC_BoundingBox::merge(CBC_BoundingBox* leftBox,
                                        CBC_BoundingBox* rightBox,
                                        int32_t& e) {
  CBC_BoundingBox* boundingBox = nullptr;
  if (!leftBox) {
    boundingBox = new CBC_BoundingBox(rightBox);
    return boundingBox;
  }
  if (!rightBox) {
    boundingBox = new CBC_BoundingBox(leftBox);
    return boundingBox;
  }
  boundingBox = new CBC_BoundingBox(leftBox->m_image, leftBox->m_topLeft,
                                    leftBox->m_bottomLeft, rightBox->m_topRight,
                                    rightBox->m_bottomRight, e);
  BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
  return boundingBox;
}
CBC_BoundingBox* CBC_BoundingBox::addMissingRows(int32_t missingStartRows,
                                                 int32_t missingEndRows,
                                                 FX_BOOL isLeft,
                                                 int32_t& e) {
  CBC_ResultPoint* newTopLeft = m_topLeft;
  CBC_ResultPoint* newBottomLeft = m_bottomLeft;
  CBC_ResultPoint* newTopRight = m_topRight;
  CBC_ResultPoint* newBottomRight = m_bottomRight;
  CBC_ResultPoint* newTop = nullptr;
  CBC_ResultPoint* newBottom = nullptr;
  if (missingStartRows > 0) {
    CBC_ResultPoint* top = isLeft ? m_topLeft : m_topRight;
    int32_t newMinY = (int32_t)top->GetY() - missingStartRows;
    if (newMinY < 0) {
      newMinY = 0;
    }
    newTop = new CBC_ResultPoint((FX_FLOAT)top->GetX(), (FX_FLOAT)newMinY);
    if (isLeft) {
      newTopLeft = newTop;
    } else {
      newTopRight = newTop;
    }
  }
  if (missingEndRows > 0) {
    CBC_ResultPoint* bottom = isLeft ? m_bottomLeft : m_bottomRight;
    int32_t newMaxY = (int32_t)bottom->GetY() + missingEndRows;
    if (newMaxY >= m_image->GetHeight()) {
      newMaxY = m_image->GetHeight() - 1;
    }
    newBottom =
        new CBC_ResultPoint((FX_FLOAT)bottom->GetX(), (FX_FLOAT)newMaxY);
    if (isLeft) {
      newBottomLeft = newBottom;
    } else {
      newBottomRight = newBottom;
    }
  }
  calculateMinMaxValues();
  CBC_BoundingBox* boundingBox = new CBC_BoundingBox(
      m_image, newTopLeft, newBottomLeft, newTopRight, newBottomRight, e);
  delete newTop;
  delete newBottom;
  BC_EXCEPTION_CHECK_ReturnValue(e, nullptr);
  return boundingBox;
}
void CBC_BoundingBox::setTopRight(CBC_ResultPoint topRight) {
  if (m_topRight) {
    delete m_topRight;
  }
  m_topRight = new CBC_ResultPoint(topRight.GetX(), topRight.GetY());
  calculateMinMaxValues();
}
void CBC_BoundingBox::setBottomRight(CBC_ResultPoint bottomRight) {
  if (m_bottomRight) {
    delete m_bottomRight;
  }
  m_bottomRight = new CBC_ResultPoint(bottomRight.GetX(), bottomRight.GetY());
  calculateMinMaxValues();
}
int32_t CBC_BoundingBox::getMinX() {
  return m_minX;
}
int32_t CBC_BoundingBox::getMaxX() {
  return m_maxX;
}
int32_t CBC_BoundingBox::getMinY() {
  return m_minY;
}
int32_t CBC_BoundingBox::getMaxY() {
  return m_maxY;
}
CBC_ResultPoint* CBC_BoundingBox::getTopLeft() {
  return m_topLeft;
}
CBC_ResultPoint* CBC_BoundingBox::getTopRight() {
  return m_topRight;
}
CBC_ResultPoint* CBC_BoundingBox::getBottomLeft() {
  return m_bottomLeft;
}
CBC_ResultPoint* CBC_BoundingBox::getBottomRight() {
  return m_bottomRight;
}
void CBC_BoundingBox::init(CBC_CommonBitMatrix* image,
                           CBC_ResultPoint* topLeft,
                           CBC_ResultPoint* bottomLeft,
                           CBC_ResultPoint* topRight,
                           CBC_ResultPoint* bottomRight) {
  m_topLeft = nullptr;
  m_bottomLeft = nullptr;
  m_topRight = nullptr;
  m_bottomRight = nullptr;
  m_image = image;
  if (topLeft) {
    m_topLeft = new CBC_ResultPoint(topLeft->GetX(), topLeft->GetY());
  }
  if (bottomLeft) {
    m_bottomLeft = new CBC_ResultPoint(bottomLeft->GetX(), bottomLeft->GetY());
  }
  if (topRight) {
    m_topRight = new CBC_ResultPoint(topRight->GetX(), topRight->GetY());
  }
  if (bottomRight) {
    m_bottomRight =
        new CBC_ResultPoint(bottomRight->GetX(), bottomRight->GetY());
  }
  calculateMinMaxValues();
}
void CBC_BoundingBox::calculateMinMaxValues() {
  if (!m_topLeft) {
    m_topLeft = new CBC_ResultPoint(0, m_topRight->GetY());
    m_bottomLeft = new CBC_ResultPoint(0, m_bottomRight->GetY());
  } else if (!m_topRight) {
    m_topRight = new CBC_ResultPoint((FX_FLOAT)m_image->GetWidth() - 1,
                                     (FX_FLOAT)m_topLeft->GetY());
    m_bottomRight = new CBC_ResultPoint((FX_FLOAT)m_image->GetWidth() - 1,
                                        (FX_FLOAT)m_bottomLeft->GetY());
  }
  m_minX = (int32_t)(m_topLeft->GetX() < m_bottomLeft->GetX()
                         ? m_topLeft->GetX()
                         : m_bottomLeft->GetX());
  m_maxX = (int32_t)(m_topRight->GetX() > m_bottomRight->GetX()
                         ? m_topRight->GetX()
                         : m_bottomRight->GetX());
  m_minY =
      (int32_t)(m_topLeft->GetY() < m_topRight->GetY() ? m_topLeft->GetY()
                                                       : m_topRight->GetY());
  m_maxY = (int32_t)(m_bottomLeft->GetY() > m_bottomRight->GetY()
                         ? m_bottomLeft->GetY()
                         : m_bottomRight->GetY());
}
