/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 2004-2005 Allan Sandfeld Jensen (kde@carewolf.com)
 * Copyright (C) 2006, 2007 Nicholas Shanks (webkit@nickshanks.com)
 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc.
 * All rights reserved.
 * Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
 * Copyright (C) 2007, 2008 Eric Seidel <eric@webkit.org>
 * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved.
 * (http://www.torchmobile.com/)
 * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
 * Copyright (C) Research In Motion Limited 2011. All rights reserved.
 * Copyright (C) 2012 Google Inc. 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 "third_party/blink/renderer/core/css/resolver/filter_operation_resolver.h"

#include "third_party/blink/renderer/core/css/css_function_value.h"
#include "third_party/blink/renderer/core/css/css_primitive_value_mappings.h"
#include "third_party/blink/renderer/core/css/css_uri_value.h"
#include "third_party/blink/renderer/core/css/resolver/style_builder_converter.h"
#include "third_party/blink/renderer/core/css/resolver/style_resolver_state.h"
#include "third_party/blink/renderer/core/frame/use_counter.h"
#include "third_party/blink/renderer/core/style/computed_style.h"

namespace blink {

static const float kOffScreenCanvasEmFontSize = 16.0;
static const float kOffScreenCanvasRemFontSize = 16.0;

FilterOperation::OperationType FilterOperationResolver::FilterOperationForType(
    CSSValueID type) {
  switch (type) {
    case CSSValueID::kGrayscale:
      return FilterOperation::GRAYSCALE;
    case CSSValueID::kSepia:
      return FilterOperation::SEPIA;
    case CSSValueID::kSaturate:
      return FilterOperation::SATURATE;
    case CSSValueID::kHueRotate:
      return FilterOperation::HUE_ROTATE;
    case CSSValueID::kInvert:
      return FilterOperation::INVERT;
    case CSSValueID::kOpacity:
      return FilterOperation::OPACITY;
    case CSSValueID::kBrightness:
      return FilterOperation::BRIGHTNESS;
    case CSSValueID::kContrast:
      return FilterOperation::CONTRAST;
    case CSSValueID::kBlur:
      return FilterOperation::BLUR;
    case CSSValueID::kDropShadow:
      return FilterOperation::DROP_SHADOW;
    default:
      NOTREACHED();
      // FIXME: We shouldn't have a type None since we never create them
      return FilterOperation::NONE;
  }
}

static void CountFilterUse(FilterOperation::OperationType operation_type,
                           const Document& document) {
  // This variable is always reassigned, but MSVC thinks it might be left
  // uninitialized.
  WebFeature feature = WebFeature::kNumberOfFeatures;
  switch (operation_type) {
    case FilterOperation::NONE:
    case FilterOperation::BOX_REFLECT:
      NOTREACHED();
      return;
    case FilterOperation::REFERENCE:
      feature = WebFeature::kCSSFilterReference;
      break;
    case FilterOperation::GRAYSCALE:
      feature = WebFeature::kCSSFilterGrayscale;
      break;
    case FilterOperation::SEPIA:
      feature = WebFeature::kCSSFilterSepia;
      break;
    case FilterOperation::SATURATE:
      feature = WebFeature::kCSSFilterSaturate;
      break;
    case FilterOperation::HUE_ROTATE:
      feature = WebFeature::kCSSFilterHueRotate;
      break;
    case FilterOperation::INVERT:
      feature = WebFeature::kCSSFilterInvert;
      break;
    case FilterOperation::OPACITY:
      feature = WebFeature::kCSSFilterOpacity;
      break;
    case FilterOperation::BRIGHTNESS:
      feature = WebFeature::kCSSFilterBrightness;
      break;
    case FilterOperation::CONTRAST:
      feature = WebFeature::kCSSFilterContrast;
      break;
    case FilterOperation::BLUR:
      feature = WebFeature::kCSSFilterBlur;
      break;
    case FilterOperation::DROP_SHADOW:
      feature = WebFeature::kCSSFilterDropShadow;
      break;
  };
  UseCounter::Count(document, feature);
}

static double ResolveFirstArgumentForFunction(const CSSFunctionValue& filter,
                                              const CSSPrimitiveValue* value) {
  switch (filter.FunctionType()) {
    case CSSValueID::kGrayscale:
    case CSSValueID::kSepia:
    case CSSValueID::kSaturate:
    case CSSValueID::kInvert:
    case CSSValueID::kBrightness:
    case CSSValueID::kContrast:
    case CSSValueID::kOpacity: {
      double amount = (filter.FunctionType() == CSSValueID::kBrightness ||
                       filter.FunctionType() == CSSValueID::kInvert)
                          ? 0
                          : 1;
      if (filter.length() == 1) {
        amount = value->GetDoubleValue();
        if (value->IsPercentage())
          amount /= 100;
      }
      return amount;
    }
    case CSSValueID::kHueRotate: {
      double angle = 0;
      if (filter.length() == 1)
        angle = value->ComputeDegrees();
      return angle;
    }
    default:
      return 0;
  }
}

FilterOperations FilterOperationResolver::CreateFilterOperations(
    StyleResolverState& state,
    const CSSValue& in_value) {
  FilterOperations operations;

  if (auto* in_identifier_value = DynamicTo<CSSIdentifierValue>(in_value)) {
    DCHECK_EQ(in_identifier_value->GetValueID(), CSSValueID::kNone);
    return operations;
  }

  const CSSToLengthConversionData& conversion_data =
      state.CssToLengthConversionData();

  for (auto& curr_value : To<CSSValueList>(in_value)) {
    if (const auto* url_value =
            DynamicTo<cssvalue::CSSURIValue>(curr_value.Get())) {
      CountFilterUse(FilterOperation::REFERENCE, state.GetDocument());

      SVGResource* resource =
          state.GetElementStyleResources().GetSVGResourceFromValue(
              state.GetTreeScope(), *url_value,
              ElementStyleResources::kAllowExternalResource);
      operations.Operations().push_back(
          MakeGarbageCollected<ReferenceFilterOperation>(
              url_value->ValueForSerialization(), resource));
      continue;
    }

    const auto* filter_value = To<CSSFunctionValue>(curr_value.Get());
    FilterOperation::OperationType operation_type =
        FilterOperationForType(filter_value->FunctionType());
    CountFilterUse(operation_type, state.GetDocument());
    DCHECK_LE(filter_value->length(), 1u);

    const CSSPrimitiveValue* first_value = nullptr;
    if (filter_value->length())
      first_value = DynamicTo<CSSPrimitiveValue>(filter_value->Item(0));

    double first_number =
        ResolveFirstArgumentForFunction(*filter_value, first_value);

    switch (filter_value->FunctionType()) {
      case CSSValueID::kGrayscale:
      case CSSValueID::kSepia:
      case CSSValueID::kSaturate:
      case CSSValueID::kHueRotate: {
        operations.Operations().push_back(
            MakeGarbageCollected<BasicColorMatrixFilterOperation>(
                first_number, operation_type));
        break;
      }
      case CSSValueID::kInvert:
      case CSSValueID::kBrightness:
      case CSSValueID::kContrast:
      case CSSValueID::kOpacity: {
        operations.Operations().push_back(
            MakeGarbageCollected<BasicComponentTransferFilterOperation>(
                first_number, operation_type));
        break;
      }
      case CSSValueID::kBlur: {
        Length std_deviation = Length::Fixed(0);
        if (filter_value->length() >= 1) {
          std_deviation = first_value->ConvertToLength(conversion_data);
        }
        operations.Operations().push_back(
            MakeGarbageCollected<BlurFilterOperation>(std_deviation));
        break;
      }
      case CSSValueID::kDropShadow: {
        ShadowData shadow = StyleBuilderConverter::ConvertShadow(
            conversion_data, &state, filter_value->Item(0));
        // TODO(fs): Resolve 'currentcolor' when constructing the filter chain.
        if (shadow.GetColor().IsCurrentColor()) {
          shadow.OverrideColor(state.Style()->GetColor());
        }
        operations.Operations().push_back(
            DropShadowFilterOperation::Create(shadow));
        break;
      }
      default:
        NOTREACHED();
        break;
    }
  }

  return operations;
}

FilterOperations FilterOperationResolver::CreateOffscreenFilterOperations(
    const CSSValue& in_value,
    const Font& font) {
  FilterOperations operations;

  if (auto* in_identifier_value = DynamicTo<CSSIdentifierValue>(in_value)) {
    DCHECK_EQ(in_identifier_value->GetValueID(), CSSValueID::kNone);
    return operations;
  }

  CSSToLengthConversionData::FontSizes font_sizes(
      kOffScreenCanvasEmFontSize, kOffScreenCanvasRemFontSize, &font);
  CSSToLengthConversionData::ViewportSize viewport_size(0, 0);
  CSSToLengthConversionData conversion_data(nullptr,  // ComputedStyle
                                            font_sizes, viewport_size,
                                            1);  // zoom

  for (auto& curr_value : To<CSSValueList>(in_value)) {
    if (curr_value->IsURIValue())
      continue;

    const auto* filter_value = To<CSSFunctionValue>(curr_value.Get());
    FilterOperation::OperationType operation_type =
        FilterOperationForType(filter_value->FunctionType());
    // TODO(fserb): Take an ExecutionContext argument to this function,
    // so we can have workers using UseCounter as well.
    // countFilterUse(operationType, state.document());
    DCHECK_LE(filter_value->length(), 1u);

    const CSSPrimitiveValue* first_value = nullptr;
    if (filter_value->length())
      first_value = DynamicTo<CSSPrimitiveValue>(filter_value->Item(0));

    double first_number =
        ResolveFirstArgumentForFunction(*filter_value, first_value);

    switch (filter_value->FunctionType()) {
      case CSSValueID::kGrayscale:
      case CSSValueID::kSepia:
      case CSSValueID::kSaturate:
      case CSSValueID::kHueRotate: {
        operations.Operations().push_back(
            MakeGarbageCollected<BasicColorMatrixFilterOperation>(
                first_number, operation_type));
        break;
      }
      case CSSValueID::kInvert:
      case CSSValueID::kBrightness:
      case CSSValueID::kContrast:
      case CSSValueID::kOpacity: {
        operations.Operations().push_back(
            MakeGarbageCollected<BasicComponentTransferFilterOperation>(
                first_number, operation_type));
        break;
      }
      case CSSValueID::kBlur: {
        Length std_deviation = Length::Fixed(0);
        if (filter_value->length() >= 1) {
          std_deviation = first_value->ConvertToLength(conversion_data);
        }
        operations.Operations().push_back(
            MakeGarbageCollected<BlurFilterOperation>(std_deviation));
        break;
      }
      case CSSValueID::kDropShadow: {
        ShadowData shadow = StyleBuilderConverter::ConvertShadow(
            conversion_data, nullptr, filter_value->Item(0));
        // For offscreen canvas, the default color is always black.
        if (shadow.GetColor().IsCurrentColor()) {
          shadow.OverrideColor(Color::kBlack);
        }
        operations.Operations().push_back(
            DropShadowFilterOperation::Create(shadow));
        break;
      }
      default:
        NOTREACHED();
        break;
    }
  }
  return operations;
}

}  // namespace blink
