// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_CSSOM_RADIAL_GRADIENT_VALUE_H_
#define COBALT_CSSOM_RADIAL_GRADIENT_VALUE_H_

#include <string>
#include <utility>
#include <vector>

#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "cobalt/base/polymorphic_equatable.h"
#include "cobalt/cssom/color_stop.h"
#include "cobalt/cssom/property_list_value.h"
#include "cobalt/cssom/property_value.h"

namespace cobalt {
namespace cssom {

// A radial gradient is specified by indicating the center of the gradient (
// where the 0% ellipse will be) and the size and shape of the ending shape (the
// 100% ellipse). Color stops are given as a list. Starting from the center and
// progressing towards (and potentially beyond) the ending shape
// uniformly-scaled concentric ellipses are drawn and colored according to the
// specified color stops.
//   https://www.w3.org/TR/css3-images/#radial-gradients
class RadialGradientValue : public PropertyValue {
 public:
  enum Shape {
    kCircle,
    kEllipse,
  };

  enum SizeKeyword {
    kClosestSide,
    kFarthestSide,
    kClosestCorner,
    kFarthestCorner,
  };

  RadialGradientValue(Shape shape, SizeKeyword size_keyword,
                      const scoped_refptr<PropertyListValue>& position,
                      ColorStopList color_stop_list)
      : shape_(shape),
        size_keyword_(size_keyword),
        size_value_(nullptr),
        position_(position),
        color_stop_list_(std::move(color_stop_list)) {}

  RadialGradientValue(Shape shape,
                      const scoped_refptr<PropertyListValue>& size_value,
                      const scoped_refptr<PropertyListValue>& position,
                      ColorStopList color_stop_list)
      : shape_(shape),
        size_value_(size_value),
        position_(position),
        color_stop_list_(std::move(color_stop_list)) {}

  void Accept(PropertyValueVisitor* visitor) override;

  const Shape& shape() const { return shape_; }

  base::Optional<SizeKeyword> size_keyword() const { return size_keyword_; }
  const scoped_refptr<PropertyListValue>& size_value() const {
    return size_value_;
  }

  const scoped_refptr<PropertyListValue>& position() const { return position_; }

  const ColorStopList& color_stop_list() const { return color_stop_list_; }

  std::string ToString() const override;

  bool operator==(const RadialGradientValue& other) const;

  DEFINE_POLYMORPHIC_EQUATABLE_TYPE(RadialGradientValue);

 private:
  ~RadialGradientValue() override {}

  const Shape shape_;

  // Exactly one of |size_keyword_| and |size_value_| is engaged.
  const base::Optional<SizeKeyword> size_keyword_;
  const scoped_refptr<PropertyListValue> size_value_;

  const scoped_refptr<PropertyListValue> position_;
  const ColorStopList color_stop_list_;

  DISALLOW_COPY_AND_ASSIGN(RadialGradientValue);
};

}  // namespace cssom
}  // namespace cobalt

#endif  // COBALT_CSSOM_RADIAL_GRADIENT_VALUE_H_
