/*
 * Copyright (C) 2013 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "third_party/blink/renderer/core/frame/page_scale_constraints_set.h"

#include <algorithm>
#include "third_party/blink/renderer/core/frame/settings.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/platform/geometry/length.h"
#include "third_party/blink/renderer/platform/wtf/assertions.h"

namespace blink {

PageScaleConstraintsSet::PageScaleConstraintsSet(Page* page)
    : default_constraints_(-1, 1, 1),
      final_constraints_(ComputeConstraintsStack()),
      page_(page),
      last_contents_width_(0),
      last_vertical_scrollbar_width_(0),
      needs_reset_(false),
      constraints_dirty_(false) {}

void PageScaleConstraintsSet::Trace(Visitor* visitor) const {
  visitor->Trace(page_);
}

void PageScaleConstraintsSet::SetDefaultConstraints(
    const PageScaleConstraints& default_constraints) {
  default_constraints_ = default_constraints;
  constraints_dirty_ = true;
}

const PageScaleConstraints& PageScaleConstraintsSet::DefaultConstraints()
    const {
  return default_constraints_;
}

void PageScaleConstraintsSet::UpdatePageDefinedConstraints(
    const ViewportDescription& description,
    const Length& legacy_fallback_width) {
  page_defined_constraints_ =
      description.Resolve(FloatSize(icb_size_), legacy_fallback_width);

  constraints_dirty_ = true;
}

void PageScaleConstraintsSet::ClearPageDefinedConstraints() {
  page_defined_constraints_ = PageScaleConstraints();
  constraints_dirty_ = true;
}

void PageScaleConstraintsSet::SetUserAgentConstraints(
    const PageScaleConstraints& user_agent_constraints) {
  user_agent_constraints_ = user_agent_constraints;
  constraints_dirty_ = true;
}

void PageScaleConstraintsSet::SetFullscreenConstraints(
    const PageScaleConstraints& fullscreen_constraints) {
  fullscreen_constraints_ = fullscreen_constraints;
  constraints_dirty_ = true;
}

PageScaleConstraints PageScaleConstraintsSet::ComputeConstraintsStack() const {
  PageScaleConstraints constraints = DefaultConstraints();
  constraints.OverrideWith(page_defined_constraints_);
  constraints.OverrideWith(user_agent_constraints_);
  constraints.OverrideWith(fullscreen_constraints_);
  return constraints;
}

void PageScaleConstraintsSet::ComputeFinalConstraints() {
  final_constraints_ = ComputeConstraintsStack();
  AdjustFinalConstraintsToContentsSize();
  constraints_dirty_ = false;
}

void PageScaleConstraintsSet::AdjustFinalConstraintsToContentsSize() {
  if (page_->GetSettings().GetShrinksViewportContentToFit()) {
    final_constraints_.FitToContentsWidth(
        last_contents_width_,
        icb_size_.Width() - last_vertical_scrollbar_width_);
  }

  final_constraints_.ResolveAutoInitialScale();
}

void PageScaleConstraintsSet::SetNeedsReset(bool needs_reset) {
  needs_reset_ = needs_reset;
  if (needs_reset)
    constraints_dirty_ = true;
}

void PageScaleConstraintsSet::DidChangeContentsSize(
    IntSize contents_size,
    int vertical_scrollbar_width,
    float page_scale_factor) {
  // If a large fixed-width element expanded the size of the document late in
  // loading and our initial scale is not set (or set to be less than the last
  // minimum scale), reset the page scale factor to the new initial scale.
  if (contents_size.Width() > last_contents_width_ &&
      page_scale_factor == FinalConstraints().minimum_scale &&
      ComputeConstraintsStack().initial_scale <
          FinalConstraints().minimum_scale)
    SetNeedsReset(true);

  constraints_dirty_ = true;
  last_vertical_scrollbar_width_ = vertical_scrollbar_width;
  last_contents_width_ = contents_size.Width();
}

static float ComputeDeprecatedTargetDensityDPIFactor(
    const ViewportDescription& description,
    float device_scale_factor) {
  if (description.deprecated_target_density_dpi ==
      ViewportDescription::kValueDeviceDPI)
    return 1.0f / device_scale_factor;

  float target_dpi = -1.0f;
  if (description.deprecated_target_density_dpi ==
      ViewportDescription::kValueLowDPI)
    target_dpi = 120.0f;
  else if (description.deprecated_target_density_dpi ==
           ViewportDescription::kValueMediumDPI)
    target_dpi = 160.0f;
  else if (description.deprecated_target_density_dpi ==
           ViewportDescription::kValueHighDPI)
    target_dpi = 240.0f;
  else if (description.deprecated_target_density_dpi !=
           ViewportDescription::kValueAuto)
    target_dpi = description.deprecated_target_density_dpi;
  return target_dpi > 0 ? 160.0f / target_dpi : 1.0f;
}

static float GetLayoutWidthForNonWideViewport(const FloatSize& device_size,
                                              float initial_scale) {
  return initial_scale == -1 ? device_size.Width()
                             : device_size.Width() / initial_scale;
}

static float ComputeHeightByAspectRatio(float width,
                                        const FloatSize& device_size) {
  return width * (device_size.Height() / device_size.Width());
}

void PageScaleConstraintsSet::DidChangeInitialContainingBlockSize(
    const IntSize& size) {
  if (icb_size_ == size)
    return;

  icb_size_ = size;
  constraints_dirty_ = true;
}

IntSize PageScaleConstraintsSet::GetLayoutSize() const {
  return FlooredIntSize(ComputeConstraintsStack().layout_size);
}

void PageScaleConstraintsSet::AdjustForAndroidWebViewQuirks(
    const ViewportDescription& description,
    int layout_fallback_width,
    float device_scale_factor,
    bool support_target_density_dpi,
    bool wide_viewport_quirk_enabled,
    bool use_wide_viewport,
    bool load_with_overview_mode,
    bool non_user_scalable_quirk_enabled) {
  if (!support_target_density_dpi && !wide_viewport_quirk_enabled &&
      load_with_overview_mode && !non_user_scalable_quirk_enabled)
    return;

  const float old_initial_scale = page_defined_constraints_.initial_scale;
  if (!load_with_overview_mode) {
    bool reset_initial_scale = false;
    if (description.zoom == -1) {
      if (description.max_width.IsAuto() ||
          description.max_width.IsExtendToZoom())
        reset_initial_scale = true;
      if (use_wide_viewport || description.max_width.IsDeviceWidth())
        reset_initial_scale = true;
    }
    if (reset_initial_scale)
      page_defined_constraints_.initial_scale = 1.0f;
  }

  float adjusted_layout_size_width =
      page_defined_constraints_.layout_size.Width();
  float adjusted_layout_size_height =
      page_defined_constraints_.layout_size.Height();
  float target_density_dpi_factor = 1.0f;

  if (support_target_density_dpi) {
    target_density_dpi_factor = ComputeDeprecatedTargetDensityDPIFactor(
        description, device_scale_factor);
    if (page_defined_constraints_.initial_scale != -1)
      page_defined_constraints_.initial_scale *= target_density_dpi_factor;
    if (page_defined_constraints_.minimum_scale != -1)
      page_defined_constraints_.minimum_scale *= target_density_dpi_factor;
    if (page_defined_constraints_.maximum_scale != -1)
      page_defined_constraints_.maximum_scale *= target_density_dpi_factor;
    if (wide_viewport_quirk_enabled &&
        (!use_wide_viewport || description.max_width.IsDeviceWidth())) {
      adjusted_layout_size_width /= target_density_dpi_factor;
      adjusted_layout_size_height /= target_density_dpi_factor;
    }
  }

  if (wide_viewport_quirk_enabled) {
    if (use_wide_viewport &&
        (description.max_width.IsAuto() ||
         description.max_width.IsExtendToZoom()) &&
        description.zoom != 1.0f) {
      if (layout_fallback_width)
        adjusted_layout_size_width = layout_fallback_width;
      adjusted_layout_size_height = ComputeHeightByAspectRatio(
          adjusted_layout_size_width, FloatSize(icb_size_));
    } else if (!use_wide_viewport) {
      const float non_wide_scale =
          description.zoom < 1 && !description.max_width.IsDeviceWidth() &&
                  !description.max_width.IsDeviceHeight()
              ? -1
              : old_initial_scale;
      adjusted_layout_size_width = GetLayoutWidthForNonWideViewport(
                                       FloatSize(icb_size_), non_wide_scale) /
                                   target_density_dpi_factor;
      float new_initial_scale = target_density_dpi_factor;
      if (user_agent_constraints_.initial_scale != -1 &&
          (description.max_width.IsDeviceWidth() ||
           ((description.max_width.IsAuto() ||
             description.max_width.IsExtendToZoom()) &&
            description.zoom == -1))) {
        adjusted_layout_size_width /= user_agent_constraints_.initial_scale;
        new_initial_scale = user_agent_constraints_.initial_scale;
      }
      adjusted_layout_size_height = ComputeHeightByAspectRatio(
          adjusted_layout_size_width, FloatSize(icb_size_));
      if (description.zoom < 1) {
        page_defined_constraints_.initial_scale = new_initial_scale;
        if (page_defined_constraints_.minimum_scale != -1)
          page_defined_constraints_.minimum_scale =
              std::min<float>(page_defined_constraints_.minimum_scale,
                              page_defined_constraints_.initial_scale);
        if (page_defined_constraints_.maximum_scale != -1)
          page_defined_constraints_.maximum_scale =
              std::max<float>(page_defined_constraints_.maximum_scale,
                              page_defined_constraints_.initial_scale);
      }
    }
  }

  if (non_user_scalable_quirk_enabled && !description.user_zoom) {
    page_defined_constraints_.initial_scale = target_density_dpi_factor;
    page_defined_constraints_.minimum_scale =
        page_defined_constraints_.initial_scale;
    page_defined_constraints_.maximum_scale =
        page_defined_constraints_.initial_scale;
    if (description.max_width.IsAuto() ||
        description.max_width.IsExtendToZoom() ||
        description.max_width.IsDeviceWidth()) {
      adjusted_layout_size_width =
          icb_size_.Width() / target_density_dpi_factor;
      adjusted_layout_size_height = ComputeHeightByAspectRatio(
          adjusted_layout_size_width, FloatSize(icb_size_));
    }
  }

  page_defined_constraints_.layout_size.SetWidth(adjusted_layout_size_width);
  page_defined_constraints_.layout_size.SetHeight(adjusted_layout_size_height);
}

}  // namespace blink
