1/*
2 * Copyright (C) 2011 Google Inc.  All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27
28#include "core/html/track/TextTrackCueList.h"
29
30namespace blink {
31
32TextTrackCueList::TextTrackCueList()
33{
34}
35
36DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(TextTrackCueList);
37
38unsigned long TextTrackCueList::length() const
39{
40    return m_list.size();
41}
42
43unsigned long TextTrackCueList::getCueIndex(TextTrackCue* cue) const
44{
45    return m_list.find(cue);
46}
47
48TextTrackCue* TextTrackCueList::item(unsigned index) const
49{
50    if (index < m_list.size())
51        return m_list[index].get();
52    return 0;
53}
54
55TextTrackCue* TextTrackCueList::getCueById(const AtomicString& id) const
56{
57    for (size_t i = 0; i < m_list.size(); ++i) {
58        if (m_list[i]->id() == id)
59            return m_list[i].get();
60    }
61    return 0;
62}
63
64TextTrackCueList* TextTrackCueList::activeCues()
65{
66    if (!m_activeCues)
67        m_activeCues = create();
68
69    m_activeCues->clear();
70    for (size_t i = 0; i < m_list.size(); ++i) {
71        RefPtrWillBeRawPtr<TextTrackCue> cue = m_list[i];
72        if (cue->isActive())
73            m_activeCues->add(cue);
74    }
75    return m_activeCues.get();
76}
77
78bool TextTrackCueList::add(PassRefPtrWillBeRawPtr<TextTrackCue> cue)
79{
80    ASSERT(cue->startTime() >= 0);
81    ASSERT(cue->endTime() >= 0);
82
83    return add(cue, 0, m_list.size());
84}
85
86bool TextTrackCueList::add(PassRefPtrWillBeRawPtr<TextTrackCue> prpCue, size_t start, size_t end)
87{
88    ASSERT_WITH_SECURITY_IMPLICATION(start <= m_list.size());
89    ASSERT_WITH_SECURITY_IMPLICATION(end <= m_list.size());
90
91    // Maintain text track cue order:
92    // http://www.whatwg.org/specs/web-apps/current-work/#text-track-cue-order
93    RefPtrWillBeRawPtr<TextTrackCue> cue = prpCue;
94    if (start == end) {
95        if (!m_list.isEmpty() && (start > 0) && (m_list[start - 1].get() == cue.get()))
96            return false;
97
98        m_list.insert(start, cue);
99        invalidateCueIndexes(start);
100        return true;
101    }
102
103    size_t index = (start + end) / 2;
104    if (cue->startTime() < m_list[index]->startTime() || (cue->startTime() == m_list[index]->startTime() && cue->endTime() > m_list[index]->endTime()))
105        return add(cue.release(), start, index);
106
107    return add(cue.release(), index + 1, end);
108}
109
110bool TextTrackCueList::remove(TextTrackCue* cue)
111{
112    size_t index = m_list.find(cue);
113    if (index == kNotFound)
114        return false;
115
116    cue->setIsActive(false);
117    m_list.remove(index);
118    return true;
119}
120
121bool TextTrackCueList::contains(TextTrackCue* cue) const
122{
123    return m_list.contains(cue);
124}
125
126bool TextTrackCueList::updateCueIndex(TextTrackCue* cue)
127{
128    if (!contains(cue))
129        return false;
130
131    remove(cue);
132    return add(cue);
133}
134
135void TextTrackCueList::clear()
136{
137    m_list.clear();
138}
139
140void TextTrackCueList::invalidateCueIndexes(size_t start)
141{
142    for (size_t i = start; i < m_list.size(); ++i)
143        m_list[i]->invalidateCueIndex();
144}
145
146void TextTrackCueList::trace(Visitor* visitor)
147{
148    visitor->trace(m_list);
149    visitor->trace(m_activeCues);
150}
151
152} // namespace blink
153