/*
 * Copyright (C) 2007, 2009, 2010 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 COMPUTER, INC. ``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 COMPUTER, INC. OR
 * 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.
 */

#include "config.h"
#include "core/html/TimeRanges.h"

#include "bindings/v8/ExceptionState.h"
#include "bindings/v8/ExceptionStatePlaceholder.h"
#include "core/dom/ExceptionCode.h"
#include <math.h>

using namespace WebCore;
using namespace std;

TimeRanges::TimeRanges(double start, double end)
{
    ScriptWrappable::init(this);
    add(start, end);
}

PassRefPtr<TimeRanges> TimeRanges::create(const blink::WebTimeRanges& webRanges)
{
    RefPtr<TimeRanges> ranges = TimeRanges::create();

    unsigned size = webRanges.size();
    for (unsigned i = 0; i < size; ++i)
        ranges->add(webRanges[i].start, webRanges[i].end);

    return ranges.release();
}

PassRefPtr<TimeRanges> TimeRanges::copy() const
{
    RefPtr<TimeRanges> newSession = TimeRanges::create();

    unsigned size = m_ranges.size();
    for (unsigned i = 0; i < size; i++)
        newSession->add(m_ranges[i].m_start, m_ranges[i].m_end);

    return newSession.release();
}

void TimeRanges::invert()
{
    RefPtr<TimeRanges> inverted = TimeRanges::create();
    double posInf = std::numeric_limits<double>::infinity();
    double negInf = -std::numeric_limits<double>::infinity();

    if (!m_ranges.size())
        inverted->add(negInf, posInf);
    else {
        double start = m_ranges.first().m_start;
        if (start != negInf)
            inverted->add(negInf, start);

        for (size_t index = 0; index + 1 < m_ranges.size(); ++index)
            inverted->add(m_ranges[index].m_end, m_ranges[index + 1].m_start);

        double end = m_ranges.last().m_end;
        if (end != posInf)
            inverted->add(end, posInf);
    }

    m_ranges.swap(inverted->m_ranges);
}

void TimeRanges::intersectWith(const TimeRanges* other)
{
    ASSERT(other);

    if (other == this)
        return;

    RefPtr<TimeRanges> invertedOther = other->copy();
    invertedOther->invert();

    invert();
    unionWith(invertedOther.get());
    invert();
}

void TimeRanges::unionWith(const TimeRanges* other)
{
    ASSERT(other);
    RefPtr<TimeRanges> unioned = copy();
    for (size_t index = 0; index < other->m_ranges.size(); ++index) {
        const Range& range = other->m_ranges[index];
        unioned->add(range.m_start, range.m_end);
    }

    m_ranges.swap(unioned->m_ranges);
}

double TimeRanges::start(unsigned index, ExceptionState& exceptionState) const
{
    if (index >= length()) {
        exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is not less than the object's length (" + String::number(length()) + ").");
        return 0;
    }
    return m_ranges[index].m_start;
}

double TimeRanges::end(unsigned index, ExceptionState& exceptionState) const
{
    if (index >= length()) {
        exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is not less than the object's length (" + String::number(length()) + ").");
        return 0;
    }
    return m_ranges[index].m_end;
}

void TimeRanges::add(double start, double end)
{
    ASSERT(start <= end);
    unsigned int overlappingArcIndex;
    Range addedRange(start, end);

    // For each present range check if we need to:
    // - merge with the added range, in case we are overlapping or contiguous
    // - Need to insert in place, we we are completely, not overlapping and not contiguous
    // in between two ranges.
    //
    // TODO: Given that we assume that ranges are correctly ordered, this could be optimized.

    for (overlappingArcIndex = 0; overlappingArcIndex < m_ranges.size(); overlappingArcIndex++) {
        if (addedRange.isOverlappingRange(m_ranges[overlappingArcIndex])
         || addedRange.isContiguousWithRange(m_ranges[overlappingArcIndex])) {
            // We need to merge the addedRange and that range.
            addedRange = addedRange.unionWithOverlappingOrContiguousRange(m_ranges[overlappingArcIndex]);
            m_ranges.remove(overlappingArcIndex);
            overlappingArcIndex--;
        } else {
            // Check the case for which there is no more to do
            if (!overlappingArcIndex) {
                if (addedRange.isBeforeRange(m_ranges[0])) {
                    // First index, and we are completely before that range (and not contiguous, nor overlapping).
                    // We just need to be inserted here.
                    break;
                }
            } else {
                if (m_ranges[overlappingArcIndex - 1].isBeforeRange(addedRange)
                 && addedRange.isBeforeRange(m_ranges[overlappingArcIndex])) {
                    // We are exactly after the current previous range, and before the current range, while
                    // not overlapping with none of them. Insert here.
                    break;
                }
            }
        }
    }

    // Now that we are sure we don't overlap with any range, just add it.
    m_ranges.insert(overlappingArcIndex, addedRange);
}

bool TimeRanges::contain(double time) const
{
    for (unsigned n = 0; n < length(); n++) {
        if (time >= start(n, IGNORE_EXCEPTION) && time <= end(n, IGNORE_EXCEPTION))
            return true;
    }
    return false;
}

double TimeRanges::nearest(double time) const
{
    double closest = 0;
    unsigned count = length();
    for (unsigned ndx = 0; ndx < count; ndx++) {
        double startTime = start(ndx, IGNORE_EXCEPTION);
        double endTime = end(ndx, IGNORE_EXCEPTION);
        if (time >= startTime && time <= endTime)
            return time;
        if (fabs(startTime - time) < closest)
            closest = fabsf(startTime - time);
        else if (fabs(endTime - time) < closest)
            closest = fabsf(endTime - time);
    }
    return closest;
}
