// Copyright 2014 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 "services/view_manager/scheduled_animation_group.h"

#include <set>

#include "mojo/converters/geometry/geometry_type_converters.h"
#include "services/view_manager/server_view.h"

using mojo::ANIMATION_PROPERTY_NONE;
using mojo::ANIMATION_PROPERTY_OPACITY;
using mojo::ANIMATION_PROPERTY_TRANSFORM;
using mojo::AnimationProperty;

namespace view_manager {
namespace {

using Sequences = std::vector<ScheduledAnimationSequence>;

// Gets the value of |property| from |view| into |value|.
void GetValueFromView(const ServerView* view,
                      AnimationProperty property,
                      ScheduledAnimationValue* value) {
  switch (property) {
    case ANIMATION_PROPERTY_NONE:
      NOTREACHED();
      break;
    case ANIMATION_PROPERTY_OPACITY:
      value->float_value = view->opacity();
      break;
    case ANIMATION_PROPERTY_TRANSFORM:
      value->transform = view->transform();
      break;
  }
}

// Sets the value of |property| from |value| into |view|.
void SetViewPropertyFromValue(ServerView* view,
                              AnimationProperty property,
                              const ScheduledAnimationValue& value) {
  switch (property) {
    case ANIMATION_PROPERTY_NONE:
      break;
    case ANIMATION_PROPERTY_OPACITY:
      view->SetOpacity(value.float_value);
      break;
    case ANIMATION_PROPERTY_TRANSFORM:
      view->SetTransform(value.transform);
      break;
  }
}

// Sets the value of |property| into |view| between two points.
void SetViewPropertyFromValueBetween(ServerView* view,
                                     AnimationProperty property,
                                     double value,
                                     gfx::Tween::Type tween_type,
                                     const ScheduledAnimationValue& start,
                                     const ScheduledAnimationValue& target) {
  const double tween_value = gfx::Tween::CalculateValue(tween_type, value);
  switch (property) {
    case ANIMATION_PROPERTY_NONE:
      break;
    case ANIMATION_PROPERTY_OPACITY:
      view->SetOpacity(gfx::Tween::FloatValueBetween(
          tween_value, start.float_value, target.float_value));
      break;
    case ANIMATION_PROPERTY_TRANSFORM:
      view->SetTransform(gfx::Tween::TransformValueBetween(
          tween_value, start.transform, target.transform));
      break;
  }
}

gfx::Tween::Type AnimationTypeToTweenType(mojo::AnimationTweenType type) {
  switch (type) {
    case mojo::ANIMATION_TWEEN_TYPE_LINEAR:
      return gfx::Tween::LINEAR;
    case mojo::ANIMATION_TWEEN_TYPE_EASE_IN:
      return gfx::Tween::EASE_IN;
    case mojo::ANIMATION_TWEEN_TYPE_EASE_OUT:
      return gfx::Tween::EASE_OUT;
    case mojo::ANIMATION_TWEEN_TYPE_EASE_IN_OUT:
      return gfx::Tween::EASE_IN_OUT;
  }
  return gfx::Tween::LINEAR;
}

void ConvertToScheduledValue(const mojo::AnimationValue& transport_value,
                             ScheduledAnimationValue* value) {
  value->float_value = transport_value.float_value;
  value->transform = transport_value.transform.To<gfx::Transform>();
}

void ConvertToScheduledElement(const mojo::AnimationElement& transport_element,
                               ScheduledAnimationElement* element) {
  element->property = transport_element.property;
  element->duration =
      base::TimeDelta::FromMicroseconds(transport_element.duration);
  element->tween_type = AnimationTypeToTweenType(transport_element.tween_type);
  if (transport_element.property != ANIMATION_PROPERTY_NONE) {
    if (transport_element.start_value.get()) {
      element->is_start_valid = true;
      ConvertToScheduledValue(*transport_element.start_value,
                              &(element->start_value));
    } else {
      element->is_start_valid = false;
    }
    ConvertToScheduledValue(*transport_element.target_value,
                            &(element->target_value));
  }
}

bool IsAnimationValueValid(AnimationProperty property,
                           const mojo::AnimationValue& value) {
  switch (property) {
    case ANIMATION_PROPERTY_NONE:
      NOTREACHED();
      return false;
    case ANIMATION_PROPERTY_OPACITY:
      return value.float_value >= 0.f && value.float_value <= 1.f;
    case ANIMATION_PROPERTY_TRANSFORM:
      return value.transform.get() && value.transform->matrix.size() == 16u;
  }
  return false;
}

bool IsAnimationElementValid(const mojo::AnimationElement& element) {
  if (element.property == ANIMATION_PROPERTY_NONE)
    return true;  // None is a pause and doesn't need any values.
  if (element.start_value.get() &&
      !IsAnimationValueValid(element.property, *element.start_value))
    return false;
  // For all other properties we require a target.
  return element.target_value.get() &&
         IsAnimationValueValid(element.property, *element.target_value);
}

bool IsAnimationSequenceValid(const mojo::AnimationSequence& sequence) {
  if (sequence.elements.size() == 0u)
    return false;

  for (size_t i = 0; i < sequence.elements.size(); ++i) {
    if (!IsAnimationElementValid(*sequence.elements[i]))
      return false;
  }
  return true;
}

bool IsAnimationGroupValid(const mojo::AnimationGroup& transport_group) {
  if (transport_group.sequences.size() == 0u)
    return false;
  for (size_t i = 0; i < transport_group.sequences.size(); ++i) {
    if (!IsAnimationSequenceValid(*transport_group.sequences[i]))
      return false;
  }
  return true;
}

// If the start value for |element| isn't valid, the value for the property
// is obtained from |view| and placed into |element|.
void GetStartValueFromViewIfNecessary(const ServerView* view,
                                      ScheduledAnimationElement* element) {
  if (element->property != ANIMATION_PROPERTY_NONE &&
      !element->is_start_valid) {
    GetValueFromView(view, element->property, &(element->start_value));
  }
}

void GetScheduledAnimationProperties(const Sequences& sequences,
                                     std::set<AnimationProperty>* properties) {
  for (const ScheduledAnimationSequence& sequence : sequences) {
    for (const ScheduledAnimationElement& element : sequence.elements)
      properties->insert(element.property);
  }
}

void SetPropertyToTargetProperty(ServerView* view,
                                 mojo::AnimationProperty property,
                                 const Sequences& sequences) {
  // NOTE: this doesn't deal with |cycle_count| quite right, but I'm honestly
  // not sure we really want to support the same property in multiple sequences
  // animating at once so I'm not dealing.
  base::TimeDelta max_end_duration;
  scoped_ptr<ScheduledAnimationValue> value;
  for (const ScheduledAnimationSequence& sequence : sequences) {
    base::TimeDelta duration;
    for (const ScheduledAnimationElement& element : sequence.elements) {
      if (element.property != property)
        continue;

      duration += element.duration;
      if (duration > max_end_duration) {
        max_end_duration = duration;
        value.reset(new ScheduledAnimationValue(element.target_value));
      }
    }
  }
  if (value.get())
    SetViewPropertyFromValue(view, property, *value);
}

void ConvertSequenceToScheduled(
    const mojo::AnimationSequence& transport_sequence,
    base::TimeTicks now,
    ScheduledAnimationSequence* sequence) {
  sequence->run_until_stopped = transport_sequence.cycle_count == 0u;
  sequence->cycle_count = transport_sequence.cycle_count;
  DCHECK_NE(0u, transport_sequence.elements.size());
  sequence->elements.resize(transport_sequence.elements.size());

  base::TimeTicks element_start_time = now;
  for (size_t i = 0; i < transport_sequence.elements.size(); ++i) {
    ConvertToScheduledElement(*(transport_sequence.elements[i].get()),
                              &(sequence->elements[i]));
    sequence->elements[i].start_time = element_start_time;
    sequence->duration += sequence->elements[i].duration;
    element_start_time += sequence->elements[i].duration;
  }
}

bool AdvanceSequence(ServerView* view,
                     ScheduledAnimationSequence* sequence,
                     base::TimeTicks now) {
  ScheduledAnimationElement* element =
      &(sequence->elements[sequence->current_index]);
  while (element->start_time + element->duration < now) {
    SetViewPropertyFromValue(view, element->property, element->target_value);
    if (++sequence->current_index == sequence->elements.size()) {
      if (!sequence->run_until_stopped && --sequence->cycle_count == 0) {
        SetViewPropertyFromValue(view, element->property,
                                 element->target_value);
        return false;
      }

      sequence->current_index = 0;
    }
    sequence->elements[sequence->current_index].start_time =
        element->start_time + element->duration;
    element = &(sequence->elements[sequence->current_index]);
    GetStartValueFromViewIfNecessary(view, element);

    // It's possible for the delta between now and |last_tick_time_| to be very
    // big (could happen if machine sleeps and is woken up much later). Normally
    // the repeat count is smallish, so we don't bother optimizing it. OTOH if
    // a sequence repeats forever we optimize it lest we get stuck in this loop
    // for a very long time.
    if (sequence->run_until_stopped && sequence->current_index == 0) {
      element->start_time =
          now - base::TimeDelta::FromMicroseconds(
                    (now - element->start_time).InMicroseconds() %
                    sequence->duration.InMicroseconds());
    }
  }
  return true;
}

}  // namespace

ScheduledAnimationValue::ScheduledAnimationValue() {
}
ScheduledAnimationValue::~ScheduledAnimationValue() {
}

ScheduledAnimationElement::ScheduledAnimationElement()
    : property(ANIMATION_PROPERTY_OPACITY),
      tween_type(gfx::Tween::EASE_IN),
      is_start_valid(false) {
}
ScheduledAnimationElement::~ScheduledAnimationElement() {
}

ScheduledAnimationSequence::ScheduledAnimationSequence()
    : run_until_stopped(false), cycle_count(0), current_index(0u) {
}
ScheduledAnimationSequence::~ScheduledAnimationSequence() {
}

ScheduledAnimationGroup::~ScheduledAnimationGroup() {
}

// static
scoped_ptr<ScheduledAnimationGroup> ScheduledAnimationGroup::Create(
    ServerView* view,
    base::TimeTicks now,
    uint32_t id,
    const mojo::AnimationGroup& transport_group) {
  if (!IsAnimationGroupValid(transport_group))
    return nullptr;

  scoped_ptr<ScheduledAnimationGroup> group(
      new ScheduledAnimationGroup(view, id, now));
  group->sequences_.resize(transport_group.sequences.size());
  for (size_t i = 0; i < transport_group.sequences.size(); ++i) {
    const mojo::AnimationSequence& transport_sequence(
        *(transport_group.sequences[i]));
    DCHECK_NE(0u, transport_sequence.elements.size());
    ConvertSequenceToScheduled(transport_sequence, now, &group->sequences_[i]);
  }
  return group.Pass();
}

void ScheduledAnimationGroup::ObtainStartValues() {
  for (ScheduledAnimationSequence& sequence : sequences_)
    GetStartValueFromViewIfNecessary(view_, &(sequence.elements[0]));
}

void ScheduledAnimationGroup::SetValuesToTargetValuesForPropertiesNotIn(
    const ScheduledAnimationGroup& other) {
  std::set<AnimationProperty> our_properties;
  GetScheduledAnimationProperties(sequences_, &our_properties);

  std::set<AnimationProperty> other_properties;
  GetScheduledAnimationProperties(other.sequences_, &other_properties);

  for (AnimationProperty property : our_properties) {
    if (other_properties.count(property) == 0 &&
        property != ANIMATION_PROPERTY_NONE) {
      SetPropertyToTargetProperty(view_, property, sequences_);
    }
  }
}

bool ScheduledAnimationGroup::Tick(base::TimeTicks time) {
  for (Sequences::iterator i = sequences_.begin(); i != sequences_.end();) {
    if (!AdvanceSequence(view_, &(*i), time)) {
      i = sequences_.erase(i);
      continue;
    }
    const ScheduledAnimationElement& active_element(
        i->elements[i->current_index]);
    const double percent =
        (time - active_element.start_time).InMillisecondsF() /
        active_element.duration.InMillisecondsF();
    SetViewPropertyFromValueBetween(
        view_, active_element.property, percent, active_element.tween_type,
        active_element.start_value, active_element.target_value);
    ++i;
  }
  return sequences_.empty();
}

ScheduledAnimationGroup::ScheduledAnimationGroup(ServerView* view,
                                                 uint32_t id,
                                                 base::TimeTicks time_scheduled)
    : view_(view), id_(id), time_scheduled_(time_scheduled) {
}

}  // namespace view_manager
