/*
 * Copyright (C) 2017 Apple 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:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. 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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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/platform/fonts/font_selection_algorithm.h"

namespace blink {

auto FontSelectionAlgorithm::StretchDistance(
    FontSelectionCapabilities capabilities) const -> DistanceResult {
  auto width = capabilities.width;
  DCHECK(width.IsValid());
  if (width.Includes(request_.width))
    return {FontSelectionValue(), request_.width};

  if (request_.width > NormalWidthValue()) {
    if (width.minimum > request_.width)
      return {width.minimum - request_.width, width.minimum};
    DCHECK(width.maximum < request_.width);
    auto threshold =
        std::max(request_.width, capabilities_bounds_.width.maximum);
    return {threshold - width.maximum, width.maximum};
  }

  if (width.maximum < request_.width)
    return {request_.width - width.maximum, width.maximum};
  DCHECK(width.minimum > request_.width);
  auto threshold = std::min(request_.width, capabilities_bounds_.width.minimum);
  return {width.minimum - threshold, width.minimum};
}

auto FontSelectionAlgorithm::StyleDistance(
    FontSelectionCapabilities capabilities) const -> DistanceResult {
  auto slope = capabilities.slope;
  DCHECK(slope.IsValid());
  if (slope.Includes(request_.slope))
    return {FontSelectionValue(), request_.slope};

  if (request_.slope >= ItalicThreshold()) {
    if (slope.minimum > request_.slope)
      return {slope.minimum - request_.slope, slope.minimum};
    DCHECK(request_.slope > slope.maximum);
    auto threshold =
        std::max(request_.slope, capabilities_bounds_.slope.maximum);
    return {threshold - slope.maximum, slope.maximum};
  }

  if (request_.slope >= FontSelectionValue()) {
    if (slope.maximum >= FontSelectionValue() && slope.maximum < request_.slope)
      return {request_.slope - slope.maximum, slope.maximum};
    if (slope.minimum > request_.slope)
      return {slope.minimum, slope.minimum};
    DCHECK(slope.maximum < FontSelectionValue());
    auto threshold =
        std::max(request_.slope, capabilities_bounds_.slope.maximum);
    return {threshold - slope.maximum, slope.maximum};
  }

  if (request_.slope > -ItalicThreshold()) {
    if (slope.minimum > request_.slope && slope.minimum <= FontSelectionValue())
      return {slope.minimum - request_.slope, slope.minimum};
    if (slope.maximum < request_.slope)
      return {-slope.maximum, slope.maximum};
    DCHECK(slope.minimum > FontSelectionValue());
    auto threshold =
        std::min(request_.slope, capabilities_bounds_.slope.minimum);
    return {slope.minimum - threshold, slope.minimum};
  }

  if (slope.maximum < request_.slope)
    return {request_.slope - slope.maximum, slope.maximum};
  DCHECK(slope.minimum > request_.slope);
  auto threshold = std::min(request_.slope, capabilities_bounds_.slope.minimum);
  return {slope.minimum - threshold, slope.minimum};
}

auto FontSelectionAlgorithm::WeightDistance(
    FontSelectionCapabilities capabilities) const -> DistanceResult {
  auto weight = capabilities.weight;
  DCHECK(weight.IsValid());
  if (weight.Includes(request_.weight))
    return {FontSelectionValue(), request_.weight};

  if (request_.weight >= LowerWeightSearchThreshold() &&
      request_.weight <= UpperWeightSearchThreshold()) {
    if (weight.minimum > request_.weight &&
        weight.minimum <= UpperWeightSearchThreshold())
      return {weight.minimum - request_.weight, weight.minimum};
    if (weight.maximum < request_.weight)
      return {UpperWeightSearchThreshold() - weight.maximum, weight.maximum};
    DCHECK(weight.minimum > UpperWeightSearchThreshold());
    auto threshold =
        std::min(request_.weight, capabilities_bounds_.weight.minimum);
    return {weight.minimum - threshold, weight.minimum};
  }

  if (request_.weight < LowerWeightSearchThreshold()) {
    if (weight.maximum < request_.weight)
      return {request_.weight - weight.maximum, weight.maximum};
    DCHECK(weight.minimum > request_.weight);
    auto threshold =
        std::min(request_.weight, capabilities_bounds_.weight.minimum);
    return {weight.minimum - threshold, weight.minimum};
  }

  DCHECK(request_.weight >= UpperWeightSearchThreshold());
  if (weight.minimum > request_.weight)
    return {weight.minimum - request_.weight, weight.minimum};
  DCHECK(weight.maximum < request_.weight);
  auto threshold =
      std::max(request_.weight, capabilities_bounds_.weight.maximum);
  return {threshold - weight.maximum, weight.maximum};
}

bool FontSelectionAlgorithm::IsBetterMatchForRequest(
    const FontSelectionCapabilities& firstCapabilities,
    const FontSelectionCapabilities& secondCapabilities) {
  auto stretchDistanceFirst = StretchDistance(firstCapabilities).distance;
  auto stretchDistanceSecond = StretchDistance(secondCapabilities).distance;
  if (stretchDistanceFirst < stretchDistanceSecond)
    return true;
  if (stretchDistanceFirst > stretchDistanceSecond)
    return false;

  auto styleDistanceFirst = StyleDistance(firstCapabilities).distance;
  auto styleDistanceSecond = StyleDistance(secondCapabilities).distance;
  if (styleDistanceFirst < styleDistanceSecond)
    return true;
  if (styleDistanceFirst > styleDistanceSecond)
    return false;

  auto weightDistanceFirst = WeightDistance(firstCapabilities).distance;
  auto weightDistanceSecond = WeightDistance(secondCapabilities).distance;
  if (weightDistanceFirst < weightDistanceSecond)
    return true;
  return false;
}

}  // namespace blink
