/*
 * Copyright (C) 2006, 2007 Apple, Inc.  All rights reserved.
 * Copyright (C) 2012 Google, 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 "sky/engine/core/editing/UndoStack.h"

#include "sky/engine/core/dom/ContainerNode.h"
#include "sky/engine/core/editing/UndoStep.h"
#include "sky/engine/platform/EventDispatchForbiddenScope.h"
#include "sky/engine/wtf/TemporaryChange.h"

namespace blink {

// Arbitrary depth limit for the undo stack, to keep it from using
// unbounded memory. This is the maximum number of distinct undoable
// actions -- unbroken stretches of typed characters are coalesced
// into a single action.
static const size_t maximumUndoStackDepth = 1000;

UndoStack::UndoStack()
    : m_inRedo(false)
{
}

DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(UndoStack)

PassOwnPtr<UndoStack> UndoStack::create()
{
    return adoptPtr(new UndoStack());
}

void UndoStack::registerUndoStep(PassRefPtr<UndoStep> step)
{
    if (m_undoStack.size() == maximumUndoStackDepth)
        m_undoStack.removeFirst(); // drop oldest item off the far end
    if (!m_inRedo)
        m_redoStack.clear();
    m_undoStack.append(step);
}

void UndoStack::registerRedoStep(PassRefPtr<UndoStep> step)
{
    m_redoStack.append(step);
}

void UndoStack::didUnloadFrame(const LocalFrame& frame)
{
    EventDispatchForbiddenScope assertNoEventDispatch;
    filterOutUndoSteps(m_undoStack, frame);
    filterOutUndoSteps(m_redoStack, frame);
}

void UndoStack::filterOutUndoSteps(UndoStepStack& stack, const LocalFrame& frame)
{
    UndoStepStack newStack;
    while (!stack.isEmpty()) {
        UndoStep* step = stack.first().get();
        if (!step->belongsTo(frame))
            newStack.append(step);
        stack.removeFirst();
    }
    stack.swap(newStack);
}

bool UndoStack::canUndo() const
{
    return !m_undoStack.isEmpty();
}

bool UndoStack::canRedo() const
{
    return !m_redoStack.isEmpty();
}

void UndoStack::undo()
{
    if (canUndo()) {
        UndoStepStack::iterator back = --m_undoStack.end();
        RefPtr<UndoStep> step(back->get());
        m_undoStack.remove(back);
        step->unapply();
        // unapply will call us back to push this command onto the redo stack.
    }
}

void UndoStack::redo()
{
    if (canRedo()) {
        UndoStepStack::iterator back = --m_redoStack.end();
        RefPtr<UndoStep> step(back->get());
        m_redoStack.remove(back);

        ASSERT(!m_inRedo);
        TemporaryChange<bool> redoScope(m_inRedo, true);
        step->reapply();
        // reapply will call us back to push this command onto the undo stack.
    }
}

} // namespace blink
