/*
 * 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 "cobalt/cssom/timing_function.h"

#include <algorithm>

#include "base/lazy_instance.h"
#include "base/logging.h"

namespace cobalt {
namespace cssom {

namespace {

struct NonTrivialStaticFields {
  // Values for keyword timing values are provided by the specification:
  //  https://www.w3.org/TR/css3-transitions/#transition-timing-function-property
  NonTrivialStaticFields()
      : ease(new CubicBezierTimingFunction(0.25f, 0.1f, 0.25f, 1.0f)),
        ease_in(new CubicBezierTimingFunction(0.42f, 0.0f, 1.0f, 1.0f)),
        ease_in_out(new CubicBezierTimingFunction(0.42f, 0.0f, 0.58f, 1.0f)),
        ease_out(new CubicBezierTimingFunction(0.0f, 0.0f, 0.58f, 1.0f)),
        linear(new CubicBezierTimingFunction(0.0f, 0.0f, 1.0f, 1.0f)),
        step_end(new SteppingTimingFunction(1, SteppingTimingFunction::kEnd)),
        step_start(
            new SteppingTimingFunction(1, SteppingTimingFunction::kStart)) {}

  const scoped_refptr<TimingFunction> ease;
  const scoped_refptr<TimingFunction> ease_in;
  const scoped_refptr<TimingFunction> ease_in_out;
  const scoped_refptr<TimingFunction> ease_out;
  const scoped_refptr<TimingFunction> linear;
  const scoped_refptr<TimingFunction> step_end;
  const scoped_refptr<TimingFunction> step_start;

 private:
  DISALLOW_COPY_AND_ASSIGN(NonTrivialStaticFields);
};

base::LazyInstance<NonTrivialStaticFields> non_trivial_static_fields =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

const scoped_refptr<TimingFunction>& TimingFunction::GetEase() {
  return non_trivial_static_fields.Get().ease;
}

const scoped_refptr<TimingFunction>& TimingFunction::GetEaseIn() {
  return non_trivial_static_fields.Get().ease_in;
}

const scoped_refptr<TimingFunction>& TimingFunction::GetEaseInOut() {
  return non_trivial_static_fields.Get().ease_in_out;
}

const scoped_refptr<TimingFunction>& TimingFunction::GetEaseOut() {
  return non_trivial_static_fields.Get().ease_out;
}

const scoped_refptr<TimingFunction>& TimingFunction::GetLinear() {
  return non_trivial_static_fields.Get().linear;
}

const scoped_refptr<TimingFunction>& TimingFunction::GetStepEnd() {
  return non_trivial_static_fields.Get().step_end;
}

const scoped_refptr<TimingFunction>& TimingFunction::GetStepStart() {
  return non_trivial_static_fields.Get().step_start;
}

float CubicBezierTimingFunction::Evaluate(float x) const {
  return static_cast<float>(cubic_bezier_.Solve(x));
}

float SteppingTimingFunction::Evaluate(float x) const {
  // number_of_steps_ must be greater than 0.  This is DCHECK'd in the
  // constructor.
  int offset_amount = value_change_location_ == kStart ? 1 : 0;
  return std::min(static_cast<int>(x * number_of_steps_ + offset_amount) /
                      static_cast<float>(number_of_steps_),
                  1.0f);
}

std::string CubicBezierTimingFunction::ToString() {
  return base::StringPrintf("cubic-bezier(%.7g,%.7g,%.7g,%.7g)",
                            cubic_bezier_.x1(), cubic_bezier_.y1(),
                            cubic_bezier_.x2(), cubic_bezier_.y2());
}

std::string SteppingTimingFunction::ToString() {
  std::string result = base::StringPrintf("steps(%d, ", number_of_steps_);
  switch (value_change_location_) {
    case kStart: {
      result.append(kStartKeywordName);
      break;
    }
    case kEnd: {
      result.append(kEndKeywordName);
      break;
    }
  }
  result.push_back(')');
  return result;
}

}  // namespace cssom
}  // namespace cobalt
