/*
 * Copyright (C) 2013 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#pragma once

#include <wtf/MediaTime.h>
#include <wtf/RefPtr.h>
#include <wtf/StdMap.h>

namespace WebCore {

class MediaSample;
class SampleMap;

class PresentationOrderSampleMap {
    friend class SampleMap;
public:
    using MapType = StdMap<MediaTime, RefPtr<MediaSample>>;
    typedef MapType::iterator iterator;
    typedef MapType::const_iterator const_iterator;
    typedef MapType::reverse_iterator reverse_iterator;
    typedef MapType::const_reverse_iterator const_reverse_iterator;
    typedef std::pair<iterator, iterator> iterator_range;
    typedef MapType::value_type value_type;

    iterator begin() { return m_samples.begin(); }
    const_iterator begin() const { return m_samples.begin(); }
    iterator end() { return m_samples.end(); }
    const_iterator end() const { return m_samples.end(); }
    reverse_iterator rbegin() { return m_samples.rbegin(); }
    const_reverse_iterator rbegin() const { return m_samples.rbegin(); }
    reverse_iterator rend() { return m_samples.rend(); }
    const_reverse_iterator rend() const { return m_samples.rend(); }

    WEBCORE_EXPORT iterator findSampleWithPresentationTime(const MediaTime&);
    WEBCORE_EXPORT iterator findSampleContainingPresentationTime(const MediaTime&);
    WEBCORE_EXPORT iterator findSampleContainingOrAfterPresentationTime(const MediaTime&);
    WEBCORE_EXPORT iterator findSampleStartingOnOrAfterPresentationTime(const MediaTime&);
    WEBCORE_EXPORT iterator findSampleStartingAfterPresentationTime(const MediaTime&);
    WEBCORE_EXPORT reverse_iterator reverseFindSampleContainingPresentationTime(const MediaTime&);
    WEBCORE_EXPORT reverse_iterator reverseFindSampleBeforePresentationTime(const MediaTime&);
    WEBCORE_EXPORT iterator_range findSamplesBetweenPresentationTimes(const MediaTime&, const MediaTime&);
    WEBCORE_EXPORT iterator_range findSamplesBetweenPresentationTimesFromEnd(const MediaTime&, const MediaTime&);

private:
    MapType m_samples;
};

class DecodeOrderSampleMap {
    friend class SampleMap;
public:
    typedef std::pair<MediaTime, MediaTime> KeyType;
    using MapType = StdMap<KeyType, RefPtr<MediaSample>>;
    typedef MapType::iterator iterator;
    typedef MapType::const_iterator const_iterator;
    typedef MapType::reverse_iterator reverse_iterator;
    typedef MapType::const_reverse_iterator const_reverse_iterator;
    typedef std::pair<reverse_iterator, reverse_iterator> reverse_iterator_range;
    typedef MapType::value_type value_type;

    iterator begin() { return m_samples.begin(); }
    const_iterator begin() const { return m_samples.begin(); }
    iterator end() { return m_samples.end(); }
    const_iterator end() const { return m_samples.end(); }
    reverse_iterator rbegin() { return m_samples.rbegin(); }
    const_reverse_iterator rbegin() const { return m_samples.rbegin(); }
    reverse_iterator rend() { return m_samples.rend(); }
    const_reverse_iterator rend() const { return m_samples.rend(); }

    WEBCORE_EXPORT iterator findSampleWithDecodeKey(const KeyType&);
    WEBCORE_EXPORT reverse_iterator reverseFindSampleWithDecodeKey(const KeyType&);
    WEBCORE_EXPORT reverse_iterator findSyncSamplePriorToPresentationTime(const MediaTime&, const MediaTime& threshold = MediaTime::positiveInfiniteTime());
    WEBCORE_EXPORT reverse_iterator findSyncSamplePriorToDecodeIterator(reverse_iterator);
    WEBCORE_EXPORT iterator findSyncSampleAfterPresentationTime(const MediaTime&, const MediaTime& threshold = MediaTime::positiveInfiniteTime());
    WEBCORE_EXPORT iterator findSyncSampleAfterDecodeIterator(iterator);
    WEBCORE_EXPORT reverse_iterator_range findDependentSamples(MediaSample*);

private:
    MapType m_samples;
    PresentationOrderSampleMap m_presentationOrder;
};

class SampleMap {
public:
    SampleMap() = default;

    WEBCORE_EXPORT bool empty() const;
    size_t size() const { return m_decodeOrder.m_samples.size(); }
    WEBCORE_EXPORT void clear();
    WEBCORE_EXPORT void addSample(MediaSample&);
    WEBCORE_EXPORT void removeSample(MediaSample*);
    size_t sizeInBytes() const { return m_totalSize; }

    template<typename I>
    void addRange(I begin, I end);

    DecodeOrderSampleMap& decodeOrder() { return m_decodeOrder; }
    const DecodeOrderSampleMap& decodeOrder() const { return m_decodeOrder; }
    PresentationOrderSampleMap& presentationOrder() { return m_decodeOrder.m_presentationOrder; }
    const PresentationOrderSampleMap& presentationOrder() const { return m_decodeOrder.m_presentationOrder; }

private:
    DecodeOrderSampleMap m_decodeOrder;
    size_t m_totalSize { 0 };
};

template<typename I>
inline void SampleMap::addRange(I begin, I end)
{
    for (I iter = begin; iter != end; ++iter)
        addSample(*iter->second);
}

} // namespace WebCore
