// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "pdf/pdf_transform.h"

#include <algorithm>
#include <utility>

#include "base/logging.h"
#include "ui/gfx/geometry/rect.h"

namespace chrome_pdf {

namespace {

// When a PdfRectangle has top < bottom, or right < left, the values should be
// swapped.
void SwapPdfRectangleValuesIfNeeded(PdfRectangle* rect) {
  if (rect->top < rect->bottom)
    std::swap(rect->top, rect->bottom);
  if (rect->right < rect->left)
    std::swap(rect->right, rect->left);
}

}  // namespace

double CalculateScaleFactor(const gfx::Rect& content_rect,
                            double src_width,
                            double src_height,
                            bool rotated) {
  if (src_width == 0 || src_height == 0)
    return 1.0;

  double actual_source_page_width = rotated ? src_height : src_width;
  double actual_source_page_height = rotated ? src_width : src_height;
  double ratio_x =
      static_cast<double>(content_rect.width()) / actual_source_page_width;
  double ratio_y =
      static_cast<double>(content_rect.height()) / actual_source_page_height;
  return std::min(ratio_x, ratio_y);
}

void SetDefaultClipBox(bool rotated, PdfRectangle* clip_box) {
  constexpr int kDpi = 72;
  constexpr float kPaperWidth = 8.5 * kDpi;
  constexpr float kPaperHeight = 11 * kDpi;
  clip_box->left = 0;
  clip_box->bottom = 0;
  clip_box->right = rotated ? kPaperHeight : kPaperWidth;
  clip_box->top = rotated ? kPaperWidth : kPaperHeight;
}

void CalculateMediaBoxAndCropBox(bool rotated,
                                 bool has_media_box,
                                 bool has_crop_box,
                                 PdfRectangle* media_box,
                                 PdfRectangle* crop_box) {
  if (has_media_box)
    SwapPdfRectangleValuesIfNeeded(media_box);
  if (has_crop_box)
    SwapPdfRectangleValuesIfNeeded(crop_box);

  if (!has_media_box && !has_crop_box) {
    SetDefaultClipBox(rotated, crop_box);
    SetDefaultClipBox(rotated, media_box);
  } else if (has_crop_box && !has_media_box) {
    *media_box = *crop_box;
  } else if (has_media_box && !has_crop_box) {
    *crop_box = *media_box;
  }
}

PdfRectangle CalculateClipBoxBoundary(const PdfRectangle& media_box,
                                      const PdfRectangle& crop_box) {
  PdfRectangle clip_box;

  // Clip |media_box| to the size of |crop_box|, but ignore |crop_box| if it is
  // bigger than |media_box|.
  clip_box.left = std::max(crop_box.left, media_box.left);
  clip_box.bottom = std::max(crop_box.bottom, media_box.bottom);
  clip_box.right = std::min(crop_box.right, media_box.right);
  clip_box.top = std::min(crop_box.top, media_box.top);
  return clip_box;
}

void ScalePdfRectangle(double scale_factor, PdfRectangle* rect) {
  rect->left *= scale_factor;
  rect->bottom *= scale_factor;
  rect->right *= scale_factor;
  rect->top *= scale_factor;
}

void CalculateScaledClipBoxOffset(const gfx::Rect& content_rect,
                                  const PdfRectangle& source_clip_box,
                                  double* offset_x,
                                  double* offset_y) {
  const float clip_box_width = source_clip_box.right - source_clip_box.left;
  const float clip_box_height = source_clip_box.top - source_clip_box.bottom;

  // Center the intended clip region to real clip region.
  *offset_x = (content_rect.width() - clip_box_width) / 2 + content_rect.x() -
              source_clip_box.left;
  *offset_y = (content_rect.height() - clip_box_height) / 2 + content_rect.y() -
              source_clip_box.bottom;
}

void CalculateNonScaledClipBoxOffset(const gfx::Rect& content_rect,
                                     int rotation,
                                     int page_width,
                                     int page_height,
                                     const PdfRectangle& source_clip_box,
                                     double* offset_x,
                                     double* offset_y) {
  // Align the intended clip region to left-top corner of real clip region.
  switch (rotation) {
    case 0:
      *offset_x = -1 * source_clip_box.left;
      *offset_y = page_height - source_clip_box.top;
      break;
    case 1:
      *offset_x = 0;
      *offset_y = -1 * source_clip_box.bottom;
      break;
    case 2:
      *offset_x = page_width - source_clip_box.right;
      *offset_y = 0;
      break;
    case 3:
      *offset_x = page_height - source_clip_box.right;
      *offset_y = page_width - source_clip_box.top;
      break;
    default:
      NOTREACHED();
      break;
  }
}

}  // namespace chrome_pdf
