/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 *           (C) 2001 Dirk Mueller (mueller@kde.org)
 *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights
 * reserved.
 * Copyright (C) 2008 Torch Mobile Inc. All rights reserved.
 * (http://www.torchmobile.com/)
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
 * Copyright (C) 2012-2013 Intel Corporation. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#include "core/dom/ViewportDescription.h"

#include "core/dom/Document.h"
#include "core/frame/FrameHost.h"
#include "core/frame/FrameView.h"
#include "core/frame/LocalFrame.h"
#include "core/frame/Settings.h"
#include "core/frame/VisualViewport.h"
#include "platform/Histogram.h"
#include "platform/weborigin/KURL.h"

namespace blink {

static const float& compareIgnoringAuto(const float& value1,
                                        const float& value2,
                                        const float& (*compare)(const float&,
                                                                const float&)) {
  if (value1 == ViewportDescription::ValueAuto)
    return value2;

  if (value2 == ViewportDescription::ValueAuto)
    return value1;

  return compare(value1, value2);
}

float ViewportDescription::resolveViewportLength(
    const Length& length,
    const FloatSize& initialViewportSize,
    Direction direction) {
  if (length.isAuto())
    return ViewportDescription::ValueAuto;

  if (length.isFixed())
    return length.getFloatValue();

  if (length.type() == ExtendToZoom)
    return ViewportDescription::ValueExtendToZoom;

  if (length.type() == Percent && direction == Horizontal)
    return initialViewportSize.width() * length.getFloatValue() / 100.0f;

  if (length.type() == Percent && direction == Vertical)
    return initialViewportSize.height() * length.getFloatValue() / 100.0f;

  if (length.type() == DeviceWidth)
    return initialViewportSize.width();

  if (length.type() == DeviceHeight)
    return initialViewportSize.height();

  NOTREACHED();
  return ViewportDescription::ValueAuto;
}

PageScaleConstraints ViewportDescription::resolve(
    const FloatSize& initialViewportSize,
    Length legacyFallbackWidth) const {
  float resultWidth = ValueAuto;

  Length copyMaxWidth = maxWidth;
  Length copyMinWidth = minWidth;
  // In case the width (used for min- and max-width) is undefined.
  if (isLegacyViewportType() && maxWidth.isAuto()) {
    // The width viewport META property is translated into 'width' descriptors,
    // setting the 'min' value to 'extend-to-zoom' and the 'max' value to the
    // intended length.  In case the UA-defines a min-width, use that as length.
    if (zoom == ViewportDescription::ValueAuto) {
      copyMinWidth = Length(ExtendToZoom);
      copyMaxWidth = legacyFallbackWidth;
    } else if (maxHeight.isAuto()) {
      copyMinWidth = Length(ExtendToZoom);
      copyMaxWidth = Length(ExtendToZoom);
    }
  }

  float resultMaxWidth =
      resolveViewportLength(copyMaxWidth, initialViewportSize, Horizontal);
  float resultMinWidth =
      resolveViewportLength(copyMinWidth, initialViewportSize, Horizontal);

  float resultHeight = ValueAuto;
  float resultMaxHeight =
      resolveViewportLength(maxHeight, initialViewportSize, Vertical);
  float resultMinHeight =
      resolveViewportLength(minHeight, initialViewportSize, Vertical);

  float resultZoom = zoom;
  float resultMinZoom = minZoom;
  float resultMaxZoom = maxZoom;
  bool resultUserZoom = userZoom;

  // Resolve min-zoom and max-zoom values.
  if (resultMinZoom != ViewportDescription::ValueAuto &&
      resultMaxZoom != ViewportDescription::ValueAuto)
    resultMaxZoom = std::max(resultMinZoom, resultMaxZoom);

  // Constrain zoom value to the [min-zoom, max-zoom] range.
  if (resultZoom != ViewportDescription::ValueAuto)
    resultZoom = compareIgnoringAuto(
        resultMinZoom, compareIgnoringAuto(resultMaxZoom, resultZoom, std::min),
        std::max);

  float extendZoom = compareIgnoringAuto(resultZoom, resultMaxZoom, std::min);

  // Resolve non-"auto" lengths to pixel lengths.
  if (extendZoom == ViewportDescription::ValueAuto) {
    if (resultMaxWidth == ViewportDescription::ValueExtendToZoom)
      resultMaxWidth = ViewportDescription::ValueAuto;

    if (resultMaxHeight == ViewportDescription::ValueExtendToZoom)
      resultMaxHeight = ViewportDescription::ValueAuto;

    if (resultMinWidth == ViewportDescription::ValueExtendToZoom)
      resultMinWidth = resultMaxWidth;

    if (resultMinHeight == ViewportDescription::ValueExtendToZoom)
      resultMinHeight = resultMaxHeight;
  } else {
    float extendWidth = initialViewportSize.width() / extendZoom;
    float extendHeight = initialViewportSize.height() / extendZoom;

    if (resultMaxWidth == ViewportDescription::ValueExtendToZoom)
      resultMaxWidth = extendWidth;

    if (resultMaxHeight == ViewportDescription::ValueExtendToZoom)
      resultMaxHeight = extendHeight;

    if (resultMinWidth == ViewportDescription::ValueExtendToZoom)
      resultMinWidth =
          compareIgnoringAuto(extendWidth, resultMaxWidth, std::max);

    if (resultMinHeight == ViewportDescription::ValueExtendToZoom)
      resultMinHeight =
          compareIgnoringAuto(extendHeight, resultMaxHeight, std::max);
  }

  // Resolve initial width from min/max descriptors.
  if (resultMinWidth != ViewportDescription::ValueAuto ||
      resultMaxWidth != ViewportDescription::ValueAuto)
    resultWidth = compareIgnoringAuto(
        resultMinWidth,
        compareIgnoringAuto(resultMaxWidth, initialViewportSize.width(),
                            std::min),
        std::max);

  // Resolve initial height from min/max descriptors.
  if (resultMinHeight != ViewportDescription::ValueAuto ||
      resultMaxHeight != ViewportDescription::ValueAuto)
    resultHeight = compareIgnoringAuto(
        resultMinHeight,
        compareIgnoringAuto(resultMaxHeight, initialViewportSize.height(),
                            std::min),
        std::max);

  // Resolve width value.
  if (resultWidth == ViewportDescription::ValueAuto) {
    if (resultHeight == ViewportDescription::ValueAuto ||
        !initialViewportSize.height())
      resultWidth = initialViewportSize.width();
    else
      resultWidth = resultHeight * (initialViewportSize.width() /
                                    initialViewportSize.height());
  }

  // Resolve height value.
  if (resultHeight == ViewportDescription::ValueAuto) {
    if (!initialViewportSize.width())
      resultHeight = initialViewportSize.height();
    else
      resultHeight = resultWidth * initialViewportSize.height() /
                     initialViewportSize.width();
  }

  // Resolve initial-scale value.
  if (resultZoom == ViewportDescription::ValueAuto) {
    if (resultWidth != ViewportDescription::ValueAuto && resultWidth > 0)
      resultZoom = initialViewportSize.width() / resultWidth;
    if (resultHeight != ViewportDescription::ValueAuto && resultHeight > 0) {
      // if 'auto', the initial-scale will be negative here and thus ignored.
      resultZoom = std::max<float>(resultZoom,
                                   initialViewportSize.height() / resultHeight);
    }

    // Reconstrain zoom value to the [min-zoom, max-zoom] range.
    resultZoom = compareIgnoringAuto(
        resultMinZoom, compareIgnoringAuto(resultMaxZoom, resultZoom, std::min),
        std::max);
  }

  // If user-scalable = no, lock the min/max scale to the computed initial
  // scale.
  if (!resultUserZoom)
    resultMinZoom = resultMaxZoom = resultZoom;

  // Only set initialScale to a value if it was explicitly set.
  if (zoom == ViewportDescription::ValueAuto)
    resultZoom = ViewportDescription::ValueAuto;

  PageScaleConstraints result;
  result.minimumScale = resultMinZoom;
  result.maximumScale = resultMaxZoom;
  result.initialScale = resultZoom;
  result.layoutSize.setWidth(resultWidth);
  result.layoutSize.setHeight(resultHeight);
  return result;
}

void ViewportDescription::reportMobilePageStats(
    const LocalFrame* mainFrame) const {
#if OS(ANDROID)
  enum ViewportUMAType {
    NoViewportTag,
    DeviceWidth,
    ConstantWidth,
    MetaWidthOther,
    MetaHandheldFriendly,
    MetaMobileOptimized,
    XhtmlMobileProfile,
    TypeCount
  };

  if (!mainFrame || !mainFrame->host() || !mainFrame->view() ||
      !mainFrame->document())
    return;

  // Avoid chrome:// pages like the new-tab page (on Android new tab is
  // non-http).
  if (!mainFrame->document()->url().protocolIsInHTTPFamily())
    return;

  DEFINE_STATIC_LOCAL(EnumerationHistogram, metaTagTypeHistogram,
                      ("Viewport.MetaTagType", TypeCount));
  if (!isSpecifiedByAuthor()) {
    metaTagTypeHistogram.count(mainFrame->document()->isMobileDocument()
                                   ? XhtmlMobileProfile
                                   : NoViewportTag);
    return;
  }

  if (isMetaViewportType()) {
    if (maxWidth.type() == blink::Fixed) {
      metaTagTypeHistogram.count(ConstantWidth);

      if (mainFrame->view()) {
        // To get an idea of how "far" the viewport is from the device's ideal
        // width, we report the zoom level that we'd need to be at for the
        // entire page to be visible.
        int viewportWidth = maxWidth.intValue();
        int windowWidth = mainFrame->host()->visualViewport().size().width();
        int overviewZoomPercent =
            100 * windowWidth / static_cast<float>(viewportWidth);
        DEFINE_STATIC_LOCAL(SparseHistogram, overviewZoomHistogram,
                            ("Viewport.OverviewZoom"));
        overviewZoomHistogram.sample(overviewZoomPercent);
      }

    } else if (maxWidth.type() == blink::DeviceWidth ||
               maxWidth.type() == blink::ExtendToZoom) {
      metaTagTypeHistogram.count(DeviceWidth);
    } else {
      // Overflow bucket for cases we may be unaware of.
      metaTagTypeHistogram.count(MetaWidthOther);
    }
  } else if (type == ViewportDescription::HandheldFriendlyMeta) {
    metaTagTypeHistogram.count(MetaHandheldFriendly);
  } else if (type == ViewportDescription::MobileOptimizedMeta) {
    metaTagTypeHistogram.count(MetaMobileOptimized);
  }
#endif
}

bool ViewportDescription::matchesHeuristicsForGpuRasterization() const {
  return isSpecifiedByAuthor();
}

}  // namespace blink
