// 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 "../barcode.h"
#include "../BC_ResultPoint.h"
#include "../common/BC_CommonBitMatrix.h"
#include "BC_PDF417BoundingBox.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 == NULL && topRight == NULL) ||
      (bottomLeft == NULL && bottomRight == NULL) ||
      (topLeft != NULL && bottomLeft == NULL) ||
      (topRight != NULL && bottomRight == NULL)) {
    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() {
  if (m_topLeft) {
    delete m_topLeft;
  }
  if (m_bottomLeft) {
    delete m_bottomLeft;
  }
  if (m_topRight) {
    delete m_topRight;
  }
  if (m_bottomRight) {
    delete m_bottomRight;
  }
}
CBC_BoundingBox* CBC_BoundingBox::merge(CBC_BoundingBox* leftBox,
                                        CBC_BoundingBox* rightBox,
                                        int32_t& e) {
  CBC_BoundingBox* boundingBox = NULL;
  if (leftBox == NULL) {
    boundingBox = new CBC_BoundingBox(rightBox);
    return boundingBox;
  }
  if (rightBox == NULL) {
    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, NULL);
  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 = NULL;
  CBC_ResultPoint* newBottom = NULL;
  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, NULL);
  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 = NULL;
  m_bottomLeft = NULL;
  m_topRight = NULL;
  m_bottomRight = NULL;
  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 == NULL) {
    m_topLeft = new CBC_ResultPoint(0, m_topRight->GetY());
    m_bottomLeft = new CBC_ResultPoint(0, m_bottomRight->GetY());
  } else if (m_topRight == NULL) {
    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());
}
