/*
 * Copyright (C) 2005, 2006, 2007, 2008 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 "TypingCommand.h"

#include "BeforeTextInsertedEvent.h"
#include "BreakBlockquoteCommand.h"
#include "DeleteSelectionCommand.h"
#include "Document.h"
#include "Editor.h"
#include "Element.h"
#include "Frame.h"
#include "HTMLNames.h"
#include "InsertLineBreakCommand.h"
#include "InsertParagraphSeparatorCommand.h"
#include "InsertTextCommand.h"
#include "RenderObject.h"
#include "SelectionController.h"
#include "VisiblePosition.h"
#include "htmlediting.h"
#include "visible_units.h"

namespace WebCore {

using namespace HTMLNames;

TypingCommand::TypingCommand(Document *document, ETypingCommand commandType, const String &textToInsert, bool selectInsertedText, TextGranularity granularity, bool killRing)
    : CompositeEditCommand(document), 
      m_commandType(commandType), 
      m_textToInsert(textToInsert), 
      m_openForMoreTyping(true), 
      m_selectInsertedText(selectInsertedText),
      m_smartDelete(false),
      m_granularity(granularity),
      m_killRing(killRing),
      m_openedByBackwardDelete(false)
{
    updatePreservesTypingStyle(m_commandType);
}

void TypingCommand::deleteSelection(Document* document, bool smartDelete)
{
    ASSERT(document);
    
    Frame* frame = document->frame();
    ASSERT(frame);
    
    if (!frame->selection()->isRange())
        return;
    
    EditCommand* lastEditCommand = frame->editor()->lastEditCommand();
    if (isOpenForMoreTypingCommand(lastEditCommand)) {
        static_cast<TypingCommand*>(lastEditCommand)->deleteSelection(smartDelete);
        return;
    }
    
    RefPtr<TypingCommand> typingCommand = TypingCommand::create(document, DeleteSelection, "", false);
    typingCommand->setSmartDelete(smartDelete);
    typingCommand->apply();
}

void TypingCommand::deleteKeyPressed(Document *document, bool smartDelete, TextGranularity granularity, bool killRing)
{
    ASSERT(document);
    
    Frame *frame = document->frame();
    ASSERT(frame);
    
    EditCommand* lastEditCommand = frame->editor()->lastEditCommand();
    if (granularity == CharacterGranularity && isOpenForMoreTypingCommand(lastEditCommand)) {
        static_cast<TypingCommand*>(lastEditCommand)->deleteKeyPressed(granularity, killRing);
        return;
    }
    
    RefPtr<TypingCommand> typingCommand = TypingCommand::create(document, DeleteKey, "", false, granularity, killRing);
    typingCommand->setSmartDelete(smartDelete);
    typingCommand->apply();
}

void TypingCommand::forwardDeleteKeyPressed(Document *document, bool smartDelete, TextGranularity granularity, bool killRing)
{
    // FIXME: Forward delete in TextEdit appears to open and close a new typing command.
    ASSERT(document);
    
    Frame *frame = document->frame();
    ASSERT(frame);
    
    EditCommand* lastEditCommand = frame->editor()->lastEditCommand();
    if (granularity == CharacterGranularity && isOpenForMoreTypingCommand(lastEditCommand)) {
        static_cast<TypingCommand*>(lastEditCommand)->forwardDeleteKeyPressed(granularity, killRing);
        return;
    }

    RefPtr<TypingCommand> typingCommand = TypingCommand::create(document, ForwardDeleteKey, "", false, granularity, killRing);
    typingCommand->setSmartDelete(smartDelete);
    typingCommand->apply();
}

void TypingCommand::insertText(Document* document, const String& text, bool selectInsertedText, bool insertedTextIsComposition)
{
    ASSERT(document);
    
    Frame* frame = document->frame();
    ASSERT(frame);

    insertText(document, text, frame->selection()->selection(), selectInsertedText, insertedTextIsComposition);
}

void TypingCommand::insertText(Document* document, const String& text, const VisibleSelection& selectionForInsertion, bool selectInsertedText, bool insertedTextIsComposition)
{
    ASSERT(document);
    
    RefPtr<Frame> frame = document->frame();
    ASSERT(frame);
    
    VisibleSelection currentSelection = frame->selection()->selection();
    bool changeSelection = currentSelection != selectionForInsertion;
    
    String newText = text;
    Node* startNode = selectionForInsertion.start().node();
    
    if (startNode && startNode->rootEditableElement() && !insertedTextIsComposition) {        
        // Send BeforeTextInsertedEvent. The event handler will update text if necessary.
        ExceptionCode ec = 0;
        RefPtr<BeforeTextInsertedEvent> evt = BeforeTextInsertedEvent::create(text);
        startNode->rootEditableElement()->dispatchEvent(evt, ec);
        newText = evt->text();
    }
    
    if (newText.isEmpty())
        return;
    
    // Set the starting and ending selection appropriately if we are using a selection
    // that is different from the current selection.  In the future, we should change EditCommand
    // to deal with custom selections in a general way that can be used by all of the commands.
    RefPtr<EditCommand> lastEditCommand = frame->editor()->lastEditCommand();
    if (isOpenForMoreTypingCommand(lastEditCommand.get())) {
        TypingCommand* lastTypingCommand = static_cast<TypingCommand*>(lastEditCommand.get());
        if (changeSelection) {
            lastTypingCommand->setStartingSelection(selectionForInsertion);
            lastTypingCommand->setEndingSelection(selectionForInsertion);
        }
        lastTypingCommand->insertText(newText, selectInsertedText);
        if (changeSelection) {
            lastTypingCommand->setEndingSelection(currentSelection);
            frame->selection()->setSelection(currentSelection);
        }
        return;
    }

    RefPtr<TypingCommand> cmd = TypingCommand::create(document, InsertText, newText, selectInsertedText);
    if (changeSelection)  {
        cmd->setStartingSelection(selectionForInsertion);
        cmd->setEndingSelection(selectionForInsertion);
    }
    applyCommand(cmd);
    if (changeSelection) {
        cmd->setEndingSelection(currentSelection);
        frame->selection()->setSelection(currentSelection);
    }
}

void TypingCommand::insertLineBreak(Document *document)
{
    ASSERT(document);
    
    Frame *frame = document->frame();
    ASSERT(frame);
    
    EditCommand* lastEditCommand = frame->editor()->lastEditCommand();
    if (isOpenForMoreTypingCommand(lastEditCommand)) {
        static_cast<TypingCommand*>(lastEditCommand)->insertLineBreak();
        return;
    }

    applyCommand(TypingCommand::create(document, InsertLineBreak));
}

void TypingCommand::insertParagraphSeparatorInQuotedContent(Document *document)
{
    ASSERT(document);
    
    Frame *frame = document->frame();
    ASSERT(frame);
    
    EditCommand* lastEditCommand = frame->editor()->lastEditCommand();
    if (isOpenForMoreTypingCommand(lastEditCommand)) {
        static_cast<TypingCommand*>(lastEditCommand)->insertParagraphSeparatorInQuotedContent();
        return;
    }

    applyCommand(TypingCommand::create(document, InsertParagraphSeparatorInQuotedContent));
}

void TypingCommand::insertParagraphSeparator(Document *document)
{
    ASSERT(document);
    
    Frame *frame = document->frame();
    ASSERT(frame);
    
    EditCommand* lastEditCommand = frame->editor()->lastEditCommand();
    if (isOpenForMoreTypingCommand(lastEditCommand)) {
        static_cast<TypingCommand*>(lastEditCommand)->insertParagraphSeparator();
        return;
    }

    applyCommand(TypingCommand::create(document, InsertParagraphSeparator));
}

bool TypingCommand::isOpenForMoreTypingCommand(const EditCommand* cmd)
{
    return cmd && cmd->isTypingCommand() && static_cast<const TypingCommand*>(cmd)->isOpenForMoreTyping();
}

void TypingCommand::closeTyping(EditCommand* cmd)
{
    if (isOpenForMoreTypingCommand(cmd))
        static_cast<TypingCommand*>(cmd)->closeTyping();
}

void TypingCommand::doApply()
{
    if (endingSelection().isNone())
        return;
        
    if (m_commandType == DeleteKey)
        if (m_commands.isEmpty())
            m_openedByBackwardDelete = true;

    switch (m_commandType) {
        case DeleteSelection:
            deleteSelection(m_smartDelete);
            return;
        case DeleteKey:
            deleteKeyPressed(m_granularity, m_killRing);
            return;
        case ForwardDeleteKey:
            forwardDeleteKeyPressed(m_granularity, m_killRing);
            return;
        case InsertLineBreak:
            insertLineBreak();
            return;
        case InsertParagraphSeparator:
            insertParagraphSeparator();
            return;
        case InsertParagraphSeparatorInQuotedContent:
            insertParagraphSeparatorInQuotedContent();
            return;
        case InsertText:
            insertText(m_textToInsert, m_selectInsertedText);
            return;
    }

    ASSERT_NOT_REACHED();
}

EditAction TypingCommand::editingAction() const
{
    return EditActionTyping;
}

void TypingCommand::markMisspellingsAfterTyping()
{
#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
    if (!document()->frame()->editor()->isContinuousSpellCheckingEnabled()
     && !document()->frame()->editor()->isAutomaticQuoteSubstitutionEnabled()
     && !document()->frame()->editor()->isAutomaticLinkDetectionEnabled()
     && !document()->frame()->editor()->isAutomaticDashSubstitutionEnabled()
     && !document()->frame()->editor()->isAutomaticTextReplacementEnabled())
        return;
#else
    if (!document()->frame()->editor()->isContinuousSpellCheckingEnabled())
        return;
#endif
    // Take a look at the selection that results after typing and determine whether we need to spellcheck. 
    // Since the word containing the current selection is never marked, this does a check to
    // see if typing made a new word that is not in the current selection. Basically, you
    // get this by being at the end of a word and typing a space.    
    VisiblePosition start(endingSelection().start(), endingSelection().affinity());
    VisiblePosition previous = start.previous();
    if (previous.isNotNull()) {
        VisiblePosition p1 = startOfWord(previous, LeftWordIfOnBoundary);
        VisiblePosition p2 = startOfWord(start, LeftWordIfOnBoundary);
        if (p1 != p2)
            document()->frame()->editor()->markMisspellingsAfterTypingToPosition(p1);
    }
}

void TypingCommand::typingAddedToOpenCommand(ETypingCommand commandTypeForAddedTyping)
{
    updatePreservesTypingStyle(commandTypeForAddedTyping);
    
#if PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
    document()->frame()->editor()->appliedEditing(this);
    // Since the spellchecking code may also perform corrections and other replacements, it should happen after the typing changes.
    markMisspellingsAfterTyping();
#else
    // The old spellchecking code requires that checking be done first, to prevent issues like that in 6864072, where <doesn't> is marked as misspelled.
    markMisspellingsAfterTyping();
    document()->frame()->editor()->appliedEditing(this);
#endif
}

void TypingCommand::insertText(const String &text, bool selectInsertedText)
{
    // FIXME: Need to implement selectInsertedText for cases where more than one insert is involved.
    // This requires support from insertTextRunWithoutNewlines and insertParagraphSeparator for extending
    // an existing selection; at the moment they can either put the caret after what's inserted or
    // select what's inserted, but there's no way to "extend selection" to include both an old selection
    // that ends just before where we want to insert text and the newly inserted text.
    int offset = 0;
    int newline;
    while ((newline = text.find('\n', offset)) != -1) {
        if (newline != offset)
            insertTextRunWithoutNewlines(text.substring(offset, newline - offset), false);
        insertParagraphSeparator();
        offset = newline + 1;
    }
    if (offset == 0)
        insertTextRunWithoutNewlines(text, selectInsertedText);
    else {
        int length = text.length();
        if (length != offset) {
            insertTextRunWithoutNewlines(text.substring(offset, length - offset), selectInsertedText);
        }
    }
}

void TypingCommand::insertTextRunWithoutNewlines(const String &text, bool selectInsertedText)
{
    RefPtr<InsertTextCommand> command;
    if (!document()->frame()->typingStyle() && !m_commands.isEmpty()) {
        EditCommand* lastCommand = m_commands.last().get();
        if (lastCommand->isInsertTextCommand())
            command = static_cast<InsertTextCommand*>(lastCommand);
    }
    if (!command) {
        command = InsertTextCommand::create(document());
        applyCommandToComposite(command);
    }
    command->input(text, selectInsertedText);
    typingAddedToOpenCommand(InsertText);
}

void TypingCommand::insertLineBreak()
{
    applyCommandToComposite(InsertLineBreakCommand::create(document()));
    typingAddedToOpenCommand(InsertLineBreak);
}

void TypingCommand::insertParagraphSeparator()
{
    applyCommandToComposite(InsertParagraphSeparatorCommand::create(document()));
    typingAddedToOpenCommand(InsertParagraphSeparator);
}

void TypingCommand::insertParagraphSeparatorInQuotedContent()
{
    // If the selection starts inside a table, just insert the paragraph separator normally
    // Breaking the blockquote would also break apart the table, which is unecessary when inserting a newline
    if (enclosingNodeOfType(endingSelection().start(), &isTableStructureNode)) {
        insertParagraphSeparator();
        return;
    }
        
    applyCommandToComposite(BreakBlockquoteCommand::create(document()));
    typingAddedToOpenCommand(InsertParagraphSeparatorInQuotedContent);
}

bool TypingCommand::makeEditableRootEmpty()
{
    Element* root = endingSelection().rootEditableElement();
    if (!root->firstChild())
        return false;

    if (root->firstChild() == root->lastChild() && root->firstElementChild() && root->firstElementChild()->hasTagName(brTag)) {
        // If there is a single child and it could be a placeholder, leave it alone.
        if (root->renderer() && root->renderer()->isBlockFlow())
            return false;
    }

    while (Node* child = root->firstChild())
        removeNode(child);

    addBlockPlaceholderIfNeeded(root);
    setEndingSelection(VisibleSelection(Position(root, 0), DOWNSTREAM));

    return true;
}

void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool killRing)
{
    VisibleSelection selectionToDelete;
    VisibleSelection selectionAfterUndo;
    
    switch (endingSelection().selectionType()) {
        case VisibleSelection::RangeSelection:
            selectionToDelete = endingSelection();
            selectionAfterUndo = selectionToDelete;
            break;
        case VisibleSelection::CaretSelection: {
            // After breaking out of an empty mail blockquote, we still want continue with the deletion
            // so actual content will get deleted, and not just the quote style.
            if (breakOutOfEmptyMailBlockquotedParagraph())
                typingAddedToOpenCommand(DeleteKey);
        
            m_smartDelete = false;

            SelectionController selection;
            selection.setSelection(endingSelection());
            selection.modify(SelectionController::EXTEND, SelectionController::BACKWARD, granularity);
            if (killRing && selection.isCaret() && granularity != CharacterGranularity) 
                selection.modify(SelectionController::EXTEND, SelectionController::BACKWARD, CharacterGranularity); 
            
            if (endingSelection().visibleStart().previous(true).isNull()) {
                // When the caret is at the start of the editable area in an empty list item, break out of the list item.
                if (breakOutOfEmptyListItem()) {
                    typingAddedToOpenCommand(DeleteKey);
                    return;
                }
                // When there are no visible positions in the editing root, delete its entire contents.
                if (endingSelection().visibleStart().next(true).isNull() && makeEditableRootEmpty()) {
                    typingAddedToOpenCommand(DeleteKey);
                    return;
                }
            }
            
            VisiblePosition visibleStart(endingSelection().visibleStart());
            // If we have a caret selection on an empty cell, we have nothing to do.
            if (isEmptyTableCell(visibleStart.deepEquivalent().node()))
                return;

            // If the caret is at the start of a paragraph after a table, move content into the last table cell.
            if (isStartOfParagraph(visibleStart) && isFirstPositionAfterTable(visibleStart.previous(true))) {
                // Unless the caret is just before a table.  We don't want to move a table into the last table cell.
                if (isLastPositionBeforeTable(visibleStart))
                    return;
                // Extend the selection backward into the last cell, then deletion will handle the move.
                selection.modify(SelectionController::EXTEND, SelectionController::BACKWARD, granularity);
            // If the caret is just after a table, select the table and don't delete anything.
            } else if (Node* table = isFirstPositionAfterTable(visibleStart)) {
                setEndingSelection(VisibleSelection(Position(table, 0), endingSelection().start(), DOWNSTREAM));
                typingAddedToOpenCommand(DeleteKey);
                return;
            }

            selectionToDelete = selection.selection();

            if (granularity == CharacterGranularity && selectionToDelete.end().node() == selectionToDelete.start().node() && selectionToDelete.end().deprecatedEditingOffset() - selectionToDelete.start().deprecatedEditingOffset() > 1) {
                // If there are multiple Unicode code points to be deleted, adjust the range to match platform conventions.
                selectionToDelete.setWithoutValidation(selectionToDelete.end(), selectionToDelete.end().previous(BackwardDeletion));
            }

            if (!startingSelection().isRange() || selectionToDelete.base() != startingSelection().start())
                selectionAfterUndo = selectionToDelete;
            else
                // It's a little tricky to compute what the starting selection would have been in the original document.
                // We can't let the VisibleSelection class's validation kick in or it'll adjust for us based on
                // the current state of the document and we'll get the wrong result.
                selectionAfterUndo.setWithoutValidation(startingSelection().end(), selectionToDelete.extent());
            break;
        }
        case VisibleSelection::NoSelection:
            ASSERT_NOT_REACHED();
            break;
    }
    
    ASSERT(!selectionToDelete.isNone());
    if (selectionToDelete.isNone())
        return;
    
    if (selectionToDelete.isCaret() || !document()->frame()->shouldDeleteSelection(selectionToDelete))
        return;
    
    if (killRing)
        document()->frame()->editor()->addToKillRing(selectionToDelete.toNormalizedRange().get(), false);
    // Make undo select everything that has been deleted, unless an undo will undo more than just this deletion.
    // FIXME: This behaves like TextEdit except for the case where you open with text insertion and then delete
    // more text than you insert.  In that case all of the text that was around originally should be selected.
    if (m_openedByBackwardDelete)
        setStartingSelection(selectionAfterUndo);
    CompositeEditCommand::deleteSelection(selectionToDelete, m_smartDelete);
    setSmartDelete(false);
    typingAddedToOpenCommand(DeleteKey);
}

void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool killRing)
{
    VisibleSelection selectionToDelete;
    VisibleSelection selectionAfterUndo;

    switch (endingSelection().selectionType()) {
        case VisibleSelection::RangeSelection:
            selectionToDelete = endingSelection();
            selectionAfterUndo = selectionToDelete;
            break;
        case VisibleSelection::CaretSelection: {
            m_smartDelete = false;

            // Handle delete at beginning-of-block case.
            // Do nothing in the case that the caret is at the start of a
            // root editable element or at the start of a document.
            SelectionController selection;
            selection.setSelection(endingSelection());
            selection.modify(SelectionController::EXTEND, SelectionController::FORWARD, granularity);
            if (killRing && selection.isCaret() && granularity != CharacterGranularity) 
                selection.modify(SelectionController::EXTEND, SelectionController::FORWARD, CharacterGranularity); 
            
            Position downstreamEnd = endingSelection().end().downstream();
            VisiblePosition visibleEnd = endingSelection().visibleEnd();
            if (visibleEnd == endOfParagraph(visibleEnd))
                downstreamEnd = visibleEnd.next(true).deepEquivalent().downstream();
            // When deleting tables: Select the table first, then perform the deletion
            if (downstreamEnd.node() && downstreamEnd.node()->renderer() && downstreamEnd.node()->renderer()->isTable() && downstreamEnd.deprecatedEditingOffset() == 0) {
                setEndingSelection(VisibleSelection(endingSelection().end(), lastDeepEditingPositionForNode(downstreamEnd.node()), DOWNSTREAM));
                typingAddedToOpenCommand(ForwardDeleteKey);
                return;
            }

            // deleting to end of paragraph when at end of paragraph needs to merge the next paragraph (if any)
            if (granularity == ParagraphBoundary && selection.selection().isCaret() && isEndOfParagraph(selection.selection().visibleEnd()))
                selection.modify(SelectionController::EXTEND, SelectionController::FORWARD, CharacterGranularity);

            selectionToDelete = selection.selection();
            if (!startingSelection().isRange() || selectionToDelete.base() != startingSelection().start())
                selectionAfterUndo = selectionToDelete;
            else {
                // It's a little tricky to compute what the starting selection would have been in the original document.
                // We can't let the VisibleSelection class's validation kick in or it'll adjust for us based on
                // the current state of the document and we'll get the wrong result.
                Position extent = startingSelection().end();
                if (extent.node() != selectionToDelete.end().node())
                    extent = selectionToDelete.extent();
                else {
                    int extraCharacters;
                    if (selectionToDelete.start().node() == selectionToDelete.end().node())
                        extraCharacters = selectionToDelete.end().deprecatedEditingOffset() - selectionToDelete.start().deprecatedEditingOffset();
                    else
                        extraCharacters = selectionToDelete.end().deprecatedEditingOffset();
                    extent = Position(extent.node(), extent.deprecatedEditingOffset() + extraCharacters);
                }
                selectionAfterUndo.setWithoutValidation(startingSelection().start(), extent);
            }
            break;
        }
        case VisibleSelection::NoSelection:
            ASSERT_NOT_REACHED();
            break;
    }
    
    ASSERT(!selectionToDelete.isNone());
    if (selectionToDelete.isNone())
        return;
    
    if (selectionToDelete.isCaret() || !document()->frame()->shouldDeleteSelection(selectionToDelete))
        return;
        
    if (killRing)
        document()->frame()->editor()->addToKillRing(selectionToDelete.toNormalizedRange().get(), false);
    // make undo select what was deleted
    setStartingSelection(selectionAfterUndo);
    CompositeEditCommand::deleteSelection(selectionToDelete, m_smartDelete);
    setSmartDelete(false);
    typingAddedToOpenCommand(ForwardDeleteKey);
}

void TypingCommand::deleteSelection(bool smartDelete)
{
    CompositeEditCommand::deleteSelection(smartDelete);
    typingAddedToOpenCommand(DeleteSelection);
}

void TypingCommand::updatePreservesTypingStyle(ETypingCommand commandType)
{
    switch (commandType) {
        case DeleteSelection:
        case DeleteKey:
        case ForwardDeleteKey:
        case InsertParagraphSeparator:
        case InsertLineBreak:
            m_preservesTypingStyle = true;
            return;
        case InsertParagraphSeparatorInQuotedContent:
        case InsertText:
            m_preservesTypingStyle = false;
            return;
    }
    ASSERT_NOT_REACHED();
    m_preservesTypingStyle = false;
}

bool TypingCommand::isTypingCommand() const
{
    return true;
}

} // namespace WebCore
