// 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.

#ifndef COBALT_WEB_ANIMATIONS_TIMED_TASK_QUEUE_H_
#define COBALT_WEB_ANIMATIONS_TIMED_TASK_QUEUE_H_

#include <map>
#include <set>

#include "base/memory/weak_ptr.h"
#include "base/time.h"
#include "base/timer.h"

namespace cobalt {
namespace web_animations {

// Logic for registering a time-variable set of transitions and tracking them
// so that we can fire transitionend events when the transitions end.
class TimedTaskQueue {
 public:
  class Task {
   public:
    ~Task() { task_queue_->Deregister(this); }

    bool fired() const { return fired_; }
    base::TimeDelta fire_time() const { return fire_time_; }

   private:
    Task(TimedTaskQueue* task_queue, const base::TimeDelta& fire_time,
         const base::Closure& callback)
        : task_queue_(task_queue),
          fired_(false),
          fire_time_(fire_time),
          callback_(callback) {
      task_queue_->Register(this);
    }

    void Fire() {
      DCHECK(!fired_);
      fired_ = true;
      callback_.Run();
    }

    TimedTaskQueue* task_queue_;
    bool fired_;
    base::TimeDelta fire_time_;
    base::Closure callback_;

    friend class TimedTaskQueue;
  };

  TimedTaskQueue();

  scoped_ptr<Task> QueueTask(base::TimeDelta fire_time,
                             const base::Closure& task);

  void UpdateTime(base::TimeDelta time);

  bool empty() const { return task_priority_queue_.empty(); }
  base::TimeDelta next_fire_time() const {
    DCHECK(!empty());
    return (*task_priority_queue_.begin())->fire_time();
  }

 private:
  // The FireTimeSortedTaskList is used to keep a list of tasks
  // sorted by their end time, so that we can easily see which element is
  // next to be fired.  We use a sorted list versus a heap so that we can
  // remove/modify elements in the middle of the list as necessary.
  class FireTimeComparator {
   public:
    bool operator()(const Task* lhs, const Task* rhs) const {
      return lhs->fire_time() < rhs->fire_time();
    }
  };
  typedef std::multiset<Task*, FireTimeComparator> FireTimeSortedTaskList;

  // The TaskMap is used to lookup tasks given their associated
  // element and property name, in order to update or remove them from the
  // set of tasks.
  typedef std::map<Task*, FireTimeSortedTaskList::iterator> TaskMap;

  // Called by the Task nested class.
  void Register(Task* task);
  void Deregister(Task* task);

  // Finds the specified task in all queues and removes it from them.
  void RemoveTaskFromQueue(Task* task);

  FireTimeSortedTaskList task_priority_queue_;
  TaskMap task_map_;
};

}  // namespace web_animations
}  // namespace cobalt

#endif  // COBALT_WEB_ANIMATIONS_TIMED_TASK_QUEUE_H_
