// Copyright 2017 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_DOM_TRACK_LIST_BASE_H_
#define COBALT_DOM_TRACK_LIST_BASE_H_

#include <string>
#include <vector>

#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "cobalt/base/tokens.h"
#include "cobalt/dom/event.h"
#include "cobalt/dom/event_target.h"
#include "cobalt/dom/html_media_element.h"
#include "cobalt/dom/track_event.h"

namespace cobalt {
namespace dom {

// This class contains common operations for AudioTrackList and VideoTrackList.
template <typename TrackType>
class TrackListBase : public EventTarget {
 public:
  explicit TrackListBase(HTMLMediaElement* media_element) {
    DCHECK(media_element);
    media_element_ = base::AsWeakPtr(media_element);
  }

  uint32 length() const { return static_cast<uint32>(tracks_.size()); }
  scoped_refptr<TrackType> AnonymousIndexedGetter(uint32 index) const {
    if (index >= tracks_.size()) return NULL;
    return tracks_[index];
  }

  scoped_refptr<TrackType> GetTrackById(const std::string& id) const {
    for (size_t i = 0; i < tracks_.size(); ++i) {
      if (tracks_[i]->id() == id) {
        return tracks_[i];
      }
    }

    return NULL;
  }

  void Add(const scoped_refptr<TrackType>& track) {
    track->SetMediaElement(media_element_);
    tracks_.push_back(track);
    ScheduleEvent(new TrackEvent(base::Tokens::addtrack(), track));
  }

  void Remove(const std::string& id) {
    for (size_t i = 0; i < tracks_.size(); ++i) {
      scoped_refptr<TrackType> track = tracks_[i];
      if (track->id() != id) {
        continue;
      }
      track->SetMediaElement(NULL);
      ScheduleEvent(new TrackEvent(base::Tokens::removetrack(), track));
      tracks_.erase(tracks_.begin() + i);
      return;
    }
    NOTREACHED();
  }

  void RemoveAll() {
    for (size_t i = 0; i < tracks_.size(); ++i) {
      tracks_[i]->SetMediaElement(NULL);
    }

    tracks_.clear();
  }

  void ScheduleChangeEvent() {
    ScheduleEvent(new Event(base::Tokens::change()));
  }

 private:
  void ScheduleEvent(const scoped_refptr<Event>& event) {
    event->set_target(this);
    media_element_->ScheduleEvent(event);
  }

  base::WeakPtr<HTMLMediaElement> media_element_;
  std::vector<scoped_refptr<TrackType> > tracks_;
};

}  // namespace dom
}  // namespace cobalt

#endif  // COBALT_DOM_TRACK_LIST_BASE_H_
