// Copyright (c) 2012 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 "content/renderer/disambiguation_popup_helper.h"

#include "third_party/WebKit/public/platform/WebRect.h"
#include "ui/gfx/size_conversions.h"

using WebKit::WebRect;
using WebKit::WebVector;

namespace {

// The amount of padding to add to the disambiguation popup to show
// content around the possible elements, adding some context.
const int kDisambiguationPopupPadding = 8;

// Constants used for fitting the disambiguation popup inside the bounds of
// the view. Note that there are mirror constants in PopupZoomer.java.
const int kDisambiguationPopupBoundsMargin = 25;

// The smallest allowable touch target used for disambiguation popup.
// This value is used to determine the minimum amount we need to scale to
// make all targets touchable.
const int kDisambiguationPopupMinimumTouchSize = 40;
const float kDisambiguationPopupMaxScale = 5.0;
const float kDisambiguationPopupMinScale = 2.0;

// Compute the scaling factor to ensure the smallest touch candidate reaches
// a certain clickable size after zooming
float FindOptimalScaleFactor(const WebVector<WebRect>& target_rects,
                             float total_scale) {
  using std::min;
  using std::max;
  if (!target_rects.size())  // shall never reach
    return kDisambiguationPopupMinScale;
  float smallest_target = min(target_rects[0].width * total_scale,
                              target_rects[0].height * total_scale);
  for (size_t i = 1; i < target_rects.size(); i++) {
    smallest_target = min(smallest_target, target_rects[i].width * total_scale);
    smallest_target = min(smallest_target,
        target_rects[i].height * total_scale);
  }
  smallest_target = max(smallest_target, 1.0f);
  return min(kDisambiguationPopupMaxScale, max(kDisambiguationPopupMinScale,
      kDisambiguationPopupMinimumTouchSize / smallest_target)) * total_scale;
}

void TrimEdges(int *e1, int *e2, int max_combined) {
  if (*e1 + *e2 <= max_combined)
    return;

  if (std::min(*e1, *e2) * 2 >= max_combined)
    *e1 = *e2 = max_combined / 2;
  else if (*e1 > *e2)
    *e1 = max_combined - *e2;
  else
    *e2 = max_combined - *e1;
}

// Ensure the disambiguation popup fits inside the screen,
// clip the edges farthest to the touch point if needed.
gfx::Rect CropZoomArea(const gfx::Rect& zoom_rect,
                       const gfx::Size& viewport_size,
                       const gfx::Point& touch_point,
                       float scale) {
  gfx::Size max_size = viewport_size;
  max_size.Enlarge(-2 * kDisambiguationPopupBoundsMargin,
                   -2 * kDisambiguationPopupBoundsMargin);
  max_size = ToCeiledSize(ScaleSize(max_size, 1.0 / scale));

  int left = touch_point.x() - zoom_rect.x();
  int right = zoom_rect.right() - touch_point.x();
  int top = touch_point.y() - zoom_rect.y();
  int bottom = zoom_rect.bottom() - touch_point.y();
  TrimEdges(&left, &right, max_size.width());
  TrimEdges(&top, &bottom, max_size.height());

  return gfx::Rect(touch_point.x() - left,
                   touch_point.y() - top,
                   left + right,
                   top + bottom);
}

}  // namespace

namespace content {

float DisambiguationPopupHelper::ComputeZoomAreaAndScaleFactor(
    const gfx::Rect& tap_rect,
    const WebVector<WebRect>& target_rects,
    const gfx::Size& screen_size,
    const gfx::Size& visible_content_size,
    float total_scale,
    gfx::Rect* zoom_rect) {
  *zoom_rect = tap_rect;
  for (size_t i = 0; i < target_rects.size(); i++)
    zoom_rect->Union(gfx::Rect(target_rects[i]));
  zoom_rect->Inset(-kDisambiguationPopupPadding, -kDisambiguationPopupPadding);

  zoom_rect->Intersect(gfx::Rect(visible_content_size));

  float new_total_scale =
      FindOptimalScaleFactor(target_rects, total_scale);
  *zoom_rect = CropZoomArea(
      *zoom_rect, screen_size, tap_rect.CenterPoint(), new_total_scale);

  return new_total_scale;
}

}  // namespace content
