// Copyright 2013 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 <algorithm>

#include "base/debug/trace_event_argument.h"
#include "base/values.h"
#include "cc/base/math_util.h"
#include "cc/output/filter_operation.h"
#include "ui/gfx/animation/tween.h"

namespace cc {

bool FilterOperation::operator==(const FilterOperation& other) const {
  if (type_ != other.type_)
    return false;
  if (type_ == COLOR_MATRIX)
    return !memcmp(matrix_, other.matrix_, sizeof(matrix_));
  if (type_ == DROP_SHADOW) {
    return amount_ == other.amount_ &&
           drop_shadow_offset_ == other.drop_shadow_offset_ &&
           drop_shadow_color_ == other.drop_shadow_color_;
  }
  if (type_ == REFERENCE)
    return image_filter_.get() == other.image_filter_.get();
  if (type_ == ALPHA_THRESHOLD) {
    return region_ == other.region_ &&
        amount_ == other.amount_ &&
        outer_threshold_ == other.outer_threshold_;
  }
  return amount_ == other.amount_;
}

FilterOperation::FilterOperation(FilterType type, float amount)
    : type_(type),
      amount_(amount),
      outer_threshold_(0),
      drop_shadow_offset_(0, 0),
      drop_shadow_color_(0),
      zoom_inset_(0) {
  DCHECK_NE(type_, DROP_SHADOW);
  DCHECK_NE(type_, COLOR_MATRIX);
  DCHECK_NE(type_, REFERENCE);
  memset(matrix_, 0, sizeof(matrix_));
}

FilterOperation::FilterOperation(FilterType type,
                                 const gfx::Point& offset,
                                 float stdDeviation,
                                 SkColor color)
    : type_(type),
      amount_(stdDeviation),
      outer_threshold_(0),
      drop_shadow_offset_(offset),
      drop_shadow_color_(color),
      zoom_inset_(0) {
  DCHECK_EQ(type_, DROP_SHADOW);
  memset(matrix_, 0, sizeof(matrix_));
}

FilterOperation::FilterOperation(FilterType type, SkScalar matrix[20])
    : type_(type),
      amount_(0),
      outer_threshold_(0),
      drop_shadow_offset_(0, 0),
      drop_shadow_color_(0),
      zoom_inset_(0) {
  DCHECK_EQ(type_, COLOR_MATRIX);
  memcpy(matrix_, matrix, sizeof(matrix_));
}

FilterOperation::FilterOperation(FilterType type, float amount, int inset)
    : type_(type),
      amount_(amount),
      outer_threshold_(0),
      drop_shadow_offset_(0, 0),
      drop_shadow_color_(0),
      zoom_inset_(inset) {
  DCHECK_EQ(type_, ZOOM);
  memset(matrix_, 0, sizeof(matrix_));
}

FilterOperation::FilterOperation(
    FilterType type,
    const skia::RefPtr<SkImageFilter>& image_filter)
    : type_(type),
      amount_(0),
      outer_threshold_(0),
      drop_shadow_offset_(0, 0),
      drop_shadow_color_(0),
      image_filter_(image_filter),
      zoom_inset_(0) {
  DCHECK_EQ(type_, REFERENCE);
  memset(matrix_, 0, sizeof(matrix_));
}

FilterOperation::FilterOperation(FilterType type,
                                 const SkRegion& region,
                                 float inner_threshold,
                                 float outer_threshold)
    : type_(type),
      amount_(inner_threshold),
      outer_threshold_(outer_threshold),
      drop_shadow_offset_(0, 0),
      drop_shadow_color_(0),
      zoom_inset_(0),
      region_(region) {
  DCHECK_EQ(type_, ALPHA_THRESHOLD);
  memset(matrix_, 0, sizeof(matrix_));
}

FilterOperation::FilterOperation(const FilterOperation& other)
    : type_(other.type_),
      amount_(other.amount_),
      outer_threshold_(other.outer_threshold_),
      drop_shadow_offset_(other.drop_shadow_offset_),
      drop_shadow_color_(other.drop_shadow_color_),
      image_filter_(other.image_filter_),
      zoom_inset_(other.zoom_inset_),
      region_(other.region_) {
  memcpy(matrix_, other.matrix_, sizeof(matrix_));
}

FilterOperation::~FilterOperation() {
}

static FilterOperation CreateNoOpFilter(FilterOperation::FilterType type) {
  switch (type) {
    case FilterOperation::GRAYSCALE:
      return FilterOperation::CreateGrayscaleFilter(0.f);
    case FilterOperation::SEPIA:
      return FilterOperation::CreateSepiaFilter(0.f);
    case FilterOperation::SATURATE:
      return FilterOperation::CreateSaturateFilter(1.f);
    case FilterOperation::HUE_ROTATE:
      return FilterOperation::CreateHueRotateFilter(0.f);
    case FilterOperation::INVERT:
      return FilterOperation::CreateInvertFilter(0.f);
    case FilterOperation::BRIGHTNESS:
      return FilterOperation::CreateBrightnessFilter(1.f);
    case FilterOperation::CONTRAST:
      return FilterOperation::CreateContrastFilter(1.f);
    case FilterOperation::OPACITY:
      return FilterOperation::CreateOpacityFilter(1.f);
    case FilterOperation::BLUR:
      return FilterOperation::CreateBlurFilter(0.f);
    case FilterOperation::DROP_SHADOW:
      return FilterOperation::CreateDropShadowFilter(
          gfx::Point(0, 0), 0.f, SK_ColorTRANSPARENT);
    case FilterOperation::COLOR_MATRIX: {
      SkScalar matrix[20];
      memset(matrix, 0, 20 * sizeof(SkScalar));
      matrix[0] = matrix[6] = matrix[12] = matrix[18] = 1.f;
      return FilterOperation::CreateColorMatrixFilter(matrix);
    }
    case FilterOperation::ZOOM:
      return FilterOperation::CreateZoomFilter(1.f, 0);
    case FilterOperation::SATURATING_BRIGHTNESS:
      return FilterOperation::CreateSaturatingBrightnessFilter(0.f);
    case FilterOperation::REFERENCE:
      return FilterOperation::CreateReferenceFilter(
          skia::RefPtr<SkImageFilter>());
    case FilterOperation::ALPHA_THRESHOLD:
      return FilterOperation::CreateAlphaThresholdFilter(SkRegion(), 1.f, 0.f);
  }
  NOTREACHED();
  return FilterOperation::CreateEmptyFilter();
}

static float ClampAmountForFilterType(float amount,
                                      FilterOperation::FilterType type) {
  switch (type) {
    case FilterOperation::GRAYSCALE:
    case FilterOperation::SEPIA:
    case FilterOperation::INVERT:
    case FilterOperation::OPACITY:
    case FilterOperation::ALPHA_THRESHOLD:
      return MathUtil::ClampToRange(amount, 0.f, 1.f);
    case FilterOperation::SATURATE:
    case FilterOperation::BRIGHTNESS:
    case FilterOperation::CONTRAST:
    case FilterOperation::BLUR:
    case FilterOperation::DROP_SHADOW:
      return std::max(amount, 0.f);
    case FilterOperation::ZOOM:
      return std::max(amount, 1.f);
    case FilterOperation::HUE_ROTATE:
    case FilterOperation::SATURATING_BRIGHTNESS:
      return amount;
    case FilterOperation::COLOR_MATRIX:
    case FilterOperation::REFERENCE:
      NOTREACHED();
      return amount;
  }
  NOTREACHED();
  return amount;
}

// static
FilterOperation FilterOperation::Blend(const FilterOperation* from,
                                       const FilterOperation* to,
                                       double progress) {
  FilterOperation blended_filter = FilterOperation::CreateEmptyFilter();

  if (!from && !to)
    return blended_filter;

  const FilterOperation& from_op = from ? *from : CreateNoOpFilter(to->type());
  const FilterOperation& to_op = to ? *to : CreateNoOpFilter(from->type());

  if (from_op.type() != to_op.type())
    return blended_filter;

  DCHECK(to_op.type() != FilterOperation::COLOR_MATRIX);
  blended_filter.set_type(to_op.type());

  if (to_op.type() == FilterOperation::REFERENCE) {
    if (progress > 0.5)
      blended_filter.set_image_filter(to_op.image_filter());
    else
      blended_filter.set_image_filter(from_op.image_filter());
    return blended_filter;
  }

  blended_filter.set_amount(ClampAmountForFilterType(
      gfx::Tween::FloatValueBetween(progress, from_op.amount(), to_op.amount()),
      to_op.type()));

  if (to_op.type() == FilterOperation::DROP_SHADOW) {
    gfx::Point blended_offset(
        gfx::Tween::LinearIntValueBetween(progress,
                                          from_op.drop_shadow_offset().x(),
                                          to_op.drop_shadow_offset().x()),
        gfx::Tween::LinearIntValueBetween(progress,
                                          from_op.drop_shadow_offset().y(),
                                          to_op.drop_shadow_offset().y()));
    blended_filter.set_drop_shadow_offset(blended_offset);
    blended_filter.set_drop_shadow_color(gfx::Tween::ColorValueBetween(
        progress, from_op.drop_shadow_color(), to_op.drop_shadow_color()));
  } else if (to_op.type() == FilterOperation::ZOOM) {
    blended_filter.set_zoom_inset(
        std::max(gfx::Tween::LinearIntValueBetween(
                     from_op.zoom_inset(), to_op.zoom_inset(), progress),
                 0));
  } else if (to_op.type() == FilterOperation::ALPHA_THRESHOLD) {
    blended_filter.set_outer_threshold(ClampAmountForFilterType(
            gfx::Tween::FloatValueBetween(progress,
                                          from_op.outer_threshold(),
                                          to_op.outer_threshold()),
            to_op.type()));
    blended_filter.set_region(to_op.region());
  }

  return blended_filter;
}

void FilterOperation::AsValueInto(base::debug::TracedValue* value) const {
  value->SetInteger("type", type_);
  switch (type_) {
    case FilterOperation::GRAYSCALE:
    case FilterOperation::SEPIA:
    case FilterOperation::SATURATE:
    case FilterOperation::HUE_ROTATE:
    case FilterOperation::INVERT:
    case FilterOperation::BRIGHTNESS:
    case FilterOperation::CONTRAST:
    case FilterOperation::OPACITY:
    case FilterOperation::BLUR:
    case FilterOperation::SATURATING_BRIGHTNESS:
      value->SetDouble("amount", amount_);
      break;
    case FilterOperation::DROP_SHADOW:
      value->SetDouble("std_deviation", amount_);
      value->BeginArray("offset");
      MathUtil::AddToTracedValue(drop_shadow_offset_, value);
      value->EndArray();
      value->SetInteger("color", drop_shadow_color_);
      break;
    case FilterOperation::COLOR_MATRIX: {
      value->BeginArray("matrix");
      for (size_t i = 0; i < arraysize(matrix_); ++i)
        value->AppendDouble(matrix_[i]);
      value->EndArray();
      break;
    }
    case FilterOperation::ZOOM:
      value->SetDouble("amount", amount_);
      value->SetDouble("inset", zoom_inset_);
      break;
    case FilterOperation::REFERENCE: {
      int count_inputs = 0;
      bool can_filter_image_gpu = false;
      if (image_filter_) {
        count_inputs = image_filter_->countInputs();
        can_filter_image_gpu = image_filter_->canFilterImageGPU();
      }
      value->SetBoolean("is_null", !image_filter_);
      value->SetInteger("count_inputs", count_inputs);
      value->SetBoolean("can_filter_image_gpu", can_filter_image_gpu);
      break;
    }
    case FilterOperation::ALPHA_THRESHOLD: {
        value->SetDouble("inner_threshold", amount_);
        value->SetDouble("outer_threshold", outer_threshold_);
        scoped_ptr<base::ListValue> region_value(new base::ListValue());
        value->BeginArray("region");
        for (SkRegion::Iterator it(region_); !it.done(); it.next()) {
          value->AppendInteger(it.rect().x());
          value->AppendInteger(it.rect().y());
          value->AppendInteger(it.rect().width());
          value->AppendInteger(it.rect().height());
        }
        value->EndArray();
      }
      break;
  }
}

}  // namespace cc
