// Copyright 2015 Google Inc. 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.

#include "base/time.h"
#include "cobalt/cssom/css_computed_style_data.h"
#include "cobalt/cssom/css_transition.h"
#include "cobalt/cssom/css_transition_set.h"
#include "cobalt/cssom/keyword_value.h"
#include "cobalt/cssom/length_value.h"
#include "cobalt/cssom/number_value.h"
#include "cobalt/cssom/property_key_list_value.h"
#include "cobalt/cssom/property_list_value.h"
#include "cobalt/cssom/rgba_color_value.h"
#include "cobalt/cssom/string_value.h"
#include "cobalt/cssom/time_list_value.h"
#include "cobalt/cssom/timing_function.h"
#include "cobalt/cssom/timing_function_list_value.h"

#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace cssom {

namespace {
scoped_refptr<TimeListValue> MakeTimeListWithSingleTime(float time_in_seconds) {
  scoped_ptr<TimeListValue::Builder> time_list(new TimeListValue::Builder());
  time_list->push_back(base::TimeDelta::FromMicroseconds(static_cast<int64>(
      time_in_seconds * base::Time::kMicrosecondsPerSecond)));
  return make_scoped_refptr(new TimeListValue(time_list.Pass()));
}

scoped_refptr<PropertyListValue> MakePropertyListWithSingleProperty(
    const scoped_refptr<PropertyValue>& property_value) {
  scoped_ptr<PropertyListValue::Builder> property_list_builder(
      new PropertyListValue::Builder());
  property_list_builder->push_back(property_value.get());
  return make_scoped_refptr(
      new PropertyListValue(property_list_builder.Pass()));
}

scoped_refptr<PropertyKeyListValue> MakePropertyNameListWithSingleProperty(
    PropertyKey property) {
  scoped_ptr<PropertyKeyListValue::Builder> property_name_list(
      new PropertyKeyListValue::Builder());
  property_name_list->push_back(property);
  return make_scoped_refptr(
      new PropertyKeyListValue(property_name_list.Pass()));
}

scoped_refptr<TimingFunctionListValue> MakeTimingFunctionWithSingleProperty(
    const scoped_refptr<TimingFunction>& timing_function) {
  scoped_ptr<TimingFunctionListValue::Builder> timing_function_list(
      new TimingFunctionListValue::Builder());
  timing_function_list->push_back(timing_function);
  return make_scoped_refptr(
      new TimingFunctionListValue(timing_function_list.Pass()));
}

scoped_refptr<CSSComputedStyleData> CreateTestComputedData() {
  scoped_refptr<CSSComputedStyleData> initial_data = new CSSComputedStyleData();

  initial_data->set_background_color(new RGBAColorValue(0xffffffff));
  initial_data->set_color(new RGBAColorValue(0x00000000));
  initial_data->set_display(KeywordValue::GetBlock());
  initial_data->set_font_family(
      MakePropertyListWithSingleProperty(new StringValue("Roboto")));
  initial_data->set_font_size(new LengthValue(16, kPixelsUnit));
  initial_data->set_height(new LengthValue(400, kPixelsUnit));
  initial_data->set_opacity(new NumberValue(0.5f));
  initial_data->set_width(new LengthValue(400, kPixelsUnit));
  initial_data->set_transform(KeywordValue::GetNone());
  initial_data->set_transition_delay(MakeTimeListWithSingleTime(0.0f));
  initial_data->set_transition_duration(MakeTimeListWithSingleTime(0.0f));
  initial_data->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));
  initial_data->set_transition_timing_function(
      MakeTimingFunctionWithSingleProperty(TimingFunction::GetLinear()));

  return initial_data;
}
}  // namespace

class TransitionSetTest : public testing::Test {
 public:
  TransitionSetTest() {
    // Initialize start and end styles to the same data.
    start_ = CreateTestComputedData();
    end_ = CreateTestComputedData();
  }

 protected:
  scoped_refptr<CSSComputedStyleData> start_;
  scoped_refptr<CSSComputedStyleData> end_;
};

TEST_F(TransitionSetTest, TransitionSetStartsEmpty) {
  TransitionSet transition_set;
  EXPECT_TRUE(transition_set.empty());
}

TEST_F(TransitionSetTest, TransitionPropertyOfAllGeneratesATransition) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  EXPECT_FALSE(transition_set.empty());
  EXPECT_TRUE(
      transition_set.GetTransitionForProperty(kBackgroundColorProperty));
}

TEST_F(TransitionSetTest,
       TransitionPropertyOfSpecificValueGeneratesATransition) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kBackgroundColorProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  EXPECT_FALSE(transition_set.empty());
  EXPECT_TRUE(
      transition_set.GetTransitionForProperty(kBackgroundColorProperty));
}

TEST_F(TransitionSetTest, TransitionPropertyOfNoneGeneratesNoTransition) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(KeywordValue::GetNone());

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  EXPECT_TRUE(transition_set.empty());
}

TEST_F(TransitionSetTest, TransitionDurationOfZeroGeneratesNoTransition) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(0.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kBackgroundColorProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  EXPECT_TRUE(transition_set.empty());
  EXPECT_EQ(static_cast<Transition*>(NULL),
            transition_set.GetTransitionForProperty(kBackgroundColorProperty));
}

TEST_F(TransitionSetTest, NoStyleChangesGeneratesNoTransitions) {
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kBackgroundColorProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  EXPECT_TRUE(transition_set.empty());
}

TEST_F(TransitionSetTest, TransitionDelayIsAccountedFor) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_delay(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kBackgroundColorProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  const Transition* transition =
      transition_set.GetTransitionForProperty(kBackgroundColorProperty);
  ASSERT_TRUE(transition);
  EXPECT_EQ(base::TimeDelta::FromSeconds(1), transition->delay());
}

// Here we start testing that the produced transitions are actually
// transitioning a given element correctly.  We use background color since it is
// the first animatable property we have available when these tests were
// written.
namespace {
void CheckTransitionsEqual(const Transition& a, const Transition& b) {
  EXPECT_TRUE(a.start_value()->Equals(*b.start_value()));
  EXPECT_TRUE(a.end_value()->Equals(*b.end_value()));
  EXPECT_TRUE(a.reversing_adjusted_start_value()->Equals(
      *b.reversing_adjusted_start_value()));

  const float kErrorEpsilon = 0.00015f;

  EXPECT_NEAR(a.duration().InSecondsF(), b.duration().InSecondsF(),
              kErrorEpsilon);
  EXPECT_NEAR(a.delay().InSecondsF(), b.delay().InSecondsF(), kErrorEpsilon);
  EXPECT_EQ(a.start_time(), b.start_time());
  EXPECT_EQ(a.target_property(), b.target_property());
  EXPECT_NEAR(a.reversing_shortening_factor(), b.reversing_shortening_factor(),
              kErrorEpsilon);
}
}  // namespace

TEST_F(TransitionSetTest, TransitionSetProducesValidFirstTransition) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  EXPECT_FALSE(transition_set.empty());
  const Transition* transition =
      transition_set.GetTransitionForProperty(kBackgroundColorProperty);
  ASSERT_TRUE(transition);

  Transition expected_transition(
      kBackgroundColorProperty, new RGBAColorValue(0xffffffff),
      new RGBAColorValue(0x00000000), base::TimeDelta(),
      base::TimeDelta::FromSeconds(1), base::TimeDelta(),
      TimingFunction::GetLinear(), new RGBAColorValue(0xffffffff), 1.0f);

  CheckTransitionsEqual(expected_transition, *transition);

  // The transition should remain untouched if the style remains unchanged and
  // the transition has not completed.
  transition_set.UpdateTransitions(base::TimeDelta::FromSecondsD(0.5), *end_,
                                   *end_);

  EXPECT_FALSE(transition_set.empty());
  transition =
      transition_set.GetTransitionForProperty(kBackgroundColorProperty);
  ASSERT_TRUE(transition);

  CheckTransitionsEqual(expected_transition, *transition);
}

TEST_F(TransitionSetTest, TransitionSetRemovesTransitionAfterCompletion) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);

  EXPECT_FALSE(transition_set.empty());
  EXPECT_TRUE(
      transition_set.GetTransitionForProperty(kBackgroundColorProperty));

  transition_set.UpdateTransitions(base::TimeDelta::FromSecondsD(2.0), *end_,
                                   *end_);

  EXPECT_TRUE(transition_set.empty());
  EXPECT_EQ(static_cast<Transition*>(NULL),
            transition_set.GetTransitionForProperty(kBackgroundColorProperty));
}

TEST_F(TransitionSetTest, TransitionsFromTransitionsWork) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));
  scoped_refptr<CSSComputedStyleData> end2 = CreateTestComputedData();
  end2->set_background_color(new RGBAColorValue(0x000000ff));
  end2->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end2->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);
  transition_set.UpdateTransitions(base::TimeDelta::FromSecondsD(0.5), *end_,
                                   *end2);

  EXPECT_FALSE(transition_set.empty());
  const Transition* transition =
      transition_set.GetTransitionForProperty(kBackgroundColorProperty);
  ASSERT_TRUE(transition);

  CheckTransitionsEqual(
      Transition(
          kBackgroundColorProperty, new RGBAColorValue(0x80808080),
          new RGBAColorValue(0x000000ff), base::TimeDelta::FromSecondsD(0.5),
          base::TimeDelta::FromSecondsD(1.0f), base::TimeDelta(),
          TimingFunction::GetLinear(), new RGBAColorValue(0x80808080), 1.0f),
      *transition);
}

TEST_F(TransitionSetTest, ReverseTransitionsWork) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));
  start_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  start_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);
  transition_set.UpdateTransitions(base::TimeDelta::FromSecondsD(0.5), *end_,
                                   *start_);

  EXPECT_FALSE(transition_set.empty());
  const Transition* transition =
      transition_set.GetTransitionForProperty(kBackgroundColorProperty);
  ASSERT_TRUE(transition);

  CheckTransitionsEqual(
      Transition(
          kBackgroundColorProperty, new RGBAColorValue(0x80808080),
          new RGBAColorValue(0xffffffff), base::TimeDelta::FromSecondsD(0.5),
          base::TimeDelta::FromSecondsD(0.5f), base::TimeDelta(),
          TimingFunction::GetLinear(), new RGBAColorValue(0x00000000), 0.5f),
      *transition);

  // Let's try reversing the transition again.
  transition_set.UpdateTransitions(base::TimeDelta::FromSecondsD(0.75), *start_,
                                   *end_);

  EXPECT_FALSE(transition_set.empty());
  transition =
      transition_set.GetTransitionForProperty(kBackgroundColorProperty);
  ASSERT_TRUE(transition);

  CheckTransitionsEqual(
      Transition(
          kBackgroundColorProperty, new RGBAColorValue(0xc0c0c0c0),
          new RGBAColorValue(0x00000000), base::TimeDelta::FromSecondsD(0.75),
          base::TimeDelta::FromSecondsD(0.75f), base::TimeDelta(),
          TimingFunction::GetLinear(), new RGBAColorValue(0xffffffff), 0.75f),
      *transition);
}

// Make sure that we successfully remove transitions when the 'transition'
// CSS property is removed (and so we return to the default setting of
// 'all' for transition an '0' for duration).
TEST_F(TransitionSetTest, ClearingTransitionsWorks) {
  end_->set_background_color(new RGBAColorValue(0x00000000));
  end_->set_transition_duration(MakeTimeListWithSingleTime(1.0f));
  end_->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));
  scoped_refptr<CSSComputedStyleData> end2 = CreateTestComputedData();
  end2->set_background_color(new RGBAColorValue(0x000000ff));
  end2->set_transition_duration(MakeTimeListWithSingleTime(0.0f));
  end2->set_transition_property(
      MakePropertyNameListWithSingleProperty(kAllProperty));

  TransitionSet transition_set;
  transition_set.UpdateTransitions(base::TimeDelta(), *start_, *end_);
  transition_set.UpdateTransitions(base::TimeDelta::FromSecondsD(0.5), *end_,
                                   *end2);

  EXPECT_TRUE(transition_set.empty());
}

}  // namespace cssom
}  // namespace cobalt
