/*
 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
 * Copyright (C) 2010 Apple Inc. All rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#pragma once

#include "EditingBehaviorTypes.h"

namespace WebCore {

class EditingBehavior {

public:
    explicit EditingBehavior(EditingBehaviorType type)
        : m_type(type)
    {
    }

    // Individual functions for each case where we have more than one style of editing behavior.
    // Create a new function for any platform difference so we can control it here.

    // When extending a selection beyond the top or bottom boundary of an editable area,
    // maintain the horizontal position on Windows but extend it to the boundary of the editable
    // content on Mac.
    bool shouldMoveCaretToHorizontalBoundaryWhenPastTopOrBottom() const
    {
        return m_type != EditingWindowsBehavior;
    }

    // On Windows, selections should always be considered as directional, regardless if it is
    // mouse-based or keyboard-based.
    bool shouldConsiderSelectionAsDirectional() const { return m_type != EditingMacBehavior && m_type != EditingIOSBehavior; }

    // On Mac, when revealing a selection (for example as a result of a Find operation on the Browser),
    // content should be scrolled such that the selection gets certer aligned.
    bool shouldCenterAlignWhenSelectionIsRevealed() const { return m_type == EditingMacBehavior || m_type == EditingIOSBehavior; }

    // On Mac, style is considered present when present at the beginning of selection. On other platforms,
    // style has to be present throughout the selection.
    bool shouldToggleStyleBasedOnStartOfSelection() const { return m_type == EditingMacBehavior || m_type == EditingIOSBehavior; }

    // Standard Mac behavior when extending to a boundary is grow the selection rather than leaving the base
    // in place and moving the extent. Matches NSTextView.
    bool shouldAlwaysGrowSelectionWhenExtendingToBoundary() const { return m_type == EditingMacBehavior || m_type == EditingIOSBehavior; }

    // On Mac, when processing a contextual click, the object being clicked upon should be selected.
    bool shouldSelectOnContextualMenuClick() const { return m_type == EditingMacBehavior || m_type == EditingIOSBehavior; }

    // On Linux, should be able to get and insert spelling suggestions without selecting the misspelled word.
    bool shouldAllowSpellingSuggestionsWithoutSelection() const
    {
        return m_type == EditingUnixBehavior;
    }
    
    // On Mac and Windows, pressing backspace (when it isn't handled otherwise) should navigate back.
    bool shouldNavigateBackOnBackspace() const
    {
        return m_type != EditingUnixBehavior;
    }

    // On Mac, selecting backwards by word/line from the middle of a word/line, and then going
    // forward leaves the caret back in the middle with no selection, instead of directly selecting
    // to the other end of the line/word (Unix/Windows behavior).
    bool shouldExtendSelectionByWordOrLineAcrossCaret() const { return m_type != EditingMacBehavior && m_type != EditingIOSBehavior; }

    // Based on native behavior, when using ctrl(alt)+arrow to move caret by word, ctrl(alt)+left arrow moves caret to
    // immediately before the word in all platforms, for example, the word break positions are: "|abc |def |hij |opq".
    // But ctrl+right arrow moves caret to "abc |def |hij |opq" on Windows and "abc| def| hij| opq|" on Mac and Linux.
    bool shouldSkipSpaceWhenMovingRight() const { return m_type == EditingWindowsBehavior; }

    // On iOS the last entered character in a secure filed is shown momentarily, removing and adding back the
    // space when deleting password cause space been showed insecurely.
    bool shouldRebalanceWhiteSpacesInSecureField() const { return m_type != EditingIOSBehavior; }

    bool shouldSelectBasedOnDictionaryLookup() const { return m_type == EditingMacBehavior; }

    // Linux and Windows always extend selections from the extent endpoint.
    bool shouldAlwaysExtendSelectionFromExtentEndpoint() const { return m_type != EditingMacBehavior && m_type != EditingIOSBehavior; }

    // On iOS, we don't want to select all the text when focusing a field. Instead, match platform behavior by going to the end of the line.
    bool shouldMoveSelectionToEndWhenFocusingTextInput() const { return m_type == EditingIOSBehavior; }
    
    // On iOS, when smart delete is on, it is always on, and should do not additional checks (i.e. WordGranularity).
    bool shouldAlwaysSmartDelete() const { return m_type == EditingIOSBehavior; }
    
    // On iOS, we should turn on smart insert and delete and newlines around paragraphs to match UIKit behaviour.
    bool shouldSmartInsertDeleteParagraphs() const { return m_type == EditingIOSBehavior; }

private:
    EditingBehaviorType m_type;
};

} // namespace WebCore
