/*
 * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
 *
 * 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.
 *
 */

#include "config.h"
#include "InputElement.h"

#include "BeforeTextInsertedEvent.h"

#if ENABLE(WCSS)
#include "CSSPropertyNames.h"
#include "CSSRule.h"
#include "CSSRuleList.h"
#include "CSSStyleRule.h"
#include "CSSStyleSelector.h"
#endif

#include "Chrome.h"
#include "ChromeClient.h"
#include "Document.h"
#include "Event.h"
#include "EventNames.h"
#include "Frame.h"
#include "HTMLInputElement.h"
#include "HTMLNames.h"
#include "MappedAttribute.h"
#include "Page.h"
#include "RenderTextControlSingleLine.h"
#include "SelectionController.h"
#include "TextIterator.h"

#if ENABLE(WML)
#include "WMLInputElement.h"
#include "WMLNames.h"
#endif

namespace WebCore {

using namespace HTMLNames;

// FIXME: According to HTML4, the length attribute's value can be arbitrarily
// large. However, due to https://bugs.webkit.org/show_bug.cgi?id=14536 things
// get rather sluggish when a text field has a larger number of characters than
// this, even when just clicking in the text field.
const int InputElement::s_maximumLength = 524288;
const int InputElement::s_defaultSize = 20;

void InputElement::dispatchFocusEvent(InputElement* inputElement, Element* element)
{
    if (!inputElement->isTextField())
        return;

    Document* document = element->document();
    if (inputElement->isPasswordField() && document->frame())
        document->setUseSecureKeyboardEntryWhenActive(true);
}

void InputElement::dispatchBlurEvent(InputElement* inputElement, Element* element)
{
    if (!inputElement->isTextField())
        return;

    Document* document = element->document();
    Frame* frame = document->frame();
    if (!frame)
        return;

    if (inputElement->isPasswordField())
        document->setUseSecureKeyboardEntryWhenActive(false);

    frame->textFieldDidEndEditing(element);
}

void InputElement::updateFocusAppearance(InputElementData& data, InputElement* inputElement, Element* element, bool restorePreviousSelection)
{
    ASSERT(inputElement->isTextField());

    if (!restorePreviousSelection || data.cachedSelectionStart() == -1)
        inputElement->select();
    else
        // Restore the cached selection.
        updateSelectionRange(inputElement, element, data.cachedSelectionStart(), data.cachedSelectionEnd());

    Document* document = element->document();
    if (document && document->frame())
        document->frame()->revealSelection();
}

void InputElement::updateSelectionRange(InputElement* inputElement, Element* element, int start, int end)
{
    if (!inputElement->isTextField())
        return;

    element->document()->updateLayoutIgnorePendingStylesheets();

    if (RenderTextControl* renderer = toRenderTextControl(element->renderer()))
        renderer->setSelectionRange(start, end);
}

void InputElement::aboutToUnload(InputElement* inputElement, Element* element)
{
    if (!inputElement->isTextField() || !element->focused())
        return;

    Document* document = element->document();
    Frame* frame = document->frame();
    if (!frame)
        return;

    frame->textFieldDidEndEditing(element);
}

void InputElement::setValueFromRenderer(InputElementData& data, InputElement* inputElement, Element* element, const String& value)
{
    // Renderer and our event handler are responsible for sanitizing values.
    ASSERT_UNUSED(inputElement, value == inputElement->sanitizeValue(value) || inputElement->sanitizeValue(value).isEmpty());

    // Workaround for bug where trailing \n is included in the result of textContent.
    // The assert macro above may also be simplified to:  value == constrainValue(value)
    // http://bugs.webkit.org/show_bug.cgi?id=9661
    if (value == "\n")
        data.setValue("");
    else
        data.setValue(value);

    element->setFormControlValueMatchesRenderer(true);

    element->dispatchEvent(Event::create(eventNames().inputEvent, true, false));
    notifyFormStateChanged(element);
}

String InputElement::sanitizeValue(const InputElement* inputElement, const String& proposedValue)
{
#if ENABLE(WCSS)
    InputElementData data = const_cast<InputElement*>(inputElement)->data();
    if (!isConformToInputMask(data, proposedValue)) {
        if (isConformToInputMask(data, data.value()))
            return data.value();
        return String();
    }
#endif
    return InputElement::sanitizeUserInputValue(inputElement, proposedValue, s_maximumLength);
}

String InputElement::sanitizeUserInputValue(const InputElement* inputElement, const String& proposedValue, int maxLength)
{
    if (!inputElement->isTextField())
        return proposedValue;

    String string = proposedValue;
    string.replace("\r\n", " ");
    string.replace('\r', ' ');
    string.replace('\n', ' ');

    unsigned newLength = numCharactersInGraphemeClusters(string, maxLength);
    for (unsigned i = 0; i < newLength; ++i) {
        const UChar current = string[i];
        if (current < ' ' && current != '\t') {
            newLength = i;
            break;
        }
    }
    return string.left(newLength);
}

void InputElement::handleBeforeTextInsertedEvent(InputElementData& data, InputElement* inputElement, Element* element, Event* event)
{
    ASSERT(event->isBeforeTextInsertedEvent());
    // Make sure that the text to be inserted will not violate the maxLength.

    // We use RenderTextControlSingleLine::text() instead of InputElement::value()
    // because they can be mismatched by sanitizeValue() in
    // RenderTextControlSingleLine::subtreeHasChanged() in some cases.
    unsigned oldLength = numGraphemeClusters(toRenderTextControlSingleLine(element->renderer())->text());

    // selectionLength represents the selection length of this text field to be
    // removed by this insertion.
    // If the text field has no focus, we don't need to take account of the
    // selection length. The selection is the source of text drag-and-drop in
    // that case, and nothing in the text field will be removed.
    unsigned selectionLength = element->focused() ? numGraphemeClusters(plainText(element->document()->frame()->selection()->selection().toNormalizedRange().get())) : 0;
    ASSERT(oldLength >= selectionLength);

    // Selected characters will be removed by the next text event.
    unsigned baseLength = oldLength - selectionLength;
    unsigned maxLength = static_cast<unsigned>(data.maxLength()); // maxLength() can never be negative.
    unsigned appendableLength = maxLength > baseLength ? maxLength - baseLength : 0;

    // Truncate the inserted text to avoid violating the maxLength and other constraints.
    BeforeTextInsertedEvent* textEvent = static_cast<BeforeTextInsertedEvent*>(event);
#if ENABLE(WCSS)
    RefPtr<Range> range = element->document()->frame()->selection()->selection().toNormalizedRange();
    String candidateString = toRenderTextControlSingleLine(element->renderer())->text();
    if (selectionLength)
        candidateString.replace(range->startOffset(), range->endOffset(), textEvent->text());
    else
        candidateString.insert(textEvent->text(), range->startOffset());
    if (!isConformToInputMask(inputElement->data(), candidateString)) {
        textEvent->setText("");
        return;
      }
#endif
    textEvent->setText(sanitizeUserInputValue(inputElement, textEvent->text(), appendableLength));
}

void InputElement::parseSizeAttribute(InputElementData& data, Element* element, MappedAttribute* attribute)
{
    data.setSize(attribute->isNull() ? InputElement::s_defaultSize : attribute->value().toInt());

    if (RenderObject* renderer = element->renderer())
        renderer->setNeedsLayoutAndPrefWidthsRecalc();
}

void InputElement::parseMaxLengthAttribute(InputElementData& data, InputElement* inputElement, Element* element, MappedAttribute* attribute)
{
    int maxLength = attribute->isNull() ? InputElement::s_maximumLength : attribute->value().toInt();
    if (maxLength <= 0 || maxLength > InputElement::s_maximumLength)
        maxLength = InputElement::s_maximumLength;

    int oldMaxLength = data.maxLength();
    data.setMaxLength(maxLength);

    if (oldMaxLength != maxLength)
        updateValueIfNeeded(data, inputElement);

    element->setNeedsStyleRecalc();
}

void InputElement::updateValueIfNeeded(InputElementData& data, InputElement* inputElement)
{
    String oldValue = data.value();
    String newValue = sanitizeValue(inputElement, oldValue);
    if (newValue != oldValue)
        inputElement->setValue(newValue);
}

void InputElement::notifyFormStateChanged(Element* element)
{
    Document* document = element->document();
    Frame* frame = document->frame();
    if (!frame)
        return;

    if (Page* page = frame->page())
        page->chrome()->client()->formStateDidChange(element);
}

// InputElementData
InputElementData::InputElementData()
    : m_size(InputElement::s_defaultSize)
    , m_maxLength(InputElement::s_maximumLength)
    , m_cachedSelectionStart(-1)
    , m_cachedSelectionEnd(-1)
#if ENABLE(WCSS)
    , m_inputFormatMask("*m")
    , m_maxInputCharsAllowed(InputElement::s_maximumLength)
#endif
{
}

const AtomicString& InputElementData::name() const
{
    return m_name.isNull() ? emptyAtom : m_name;
}

InputElement* toInputElement(Element* element)
{
    if (element->isHTMLElement() && (element->hasTagName(inputTag) || element->hasTagName(isindexTag)))
        return static_cast<HTMLInputElement*>(element);

#if ENABLE(WML)
    if (element->isWMLElement() && element->hasTagName(WMLNames::inputTag))
        return static_cast<WMLInputElement*>(element);
#endif

    return 0;
}

#if ENABLE(WCSS)
static inline const AtomicString& formatCodes()
{
    DEFINE_STATIC_LOCAL(AtomicString, codes, ("AaNnXxMm"));
    return codes;
}

static unsigned cursorPositionToMaskIndex(const String& inputFormatMask, unsigned cursorPosition)
{
    UChar mask;
    int index = -1;
    do {
        mask = inputFormatMask[++index];
        if (mask == '\\')
            ++index;
        else if (mask == '*' || (isASCIIDigit(mask) && mask != '0')) {
            index = inputFormatMask.length() - 1;
            break;
        }
    } while (cursorPosition--);

    return index;
}

bool InputElement::isConformToInputMask(const InputElementData& data, const String& inputChars)
{
    for (unsigned i = 0; i < inputChars.length(); ++i)
        if (!isConformToInputMask(data, inputChars[i], i))
            return false;
    return true;
}

bool InputElement::isConformToInputMask(const InputElementData& data, UChar inChar, unsigned cursorPosition)
{
    String inputFormatMask = data.inputFormatMask();

    if (inputFormatMask.isEmpty() || inputFormatMask == "*M" || inputFormatMask == "*m")
        return true;

    if (cursorPosition >= data.maxInputCharsAllowed())
        return false;

    unsigned maskIndex = cursorPositionToMaskIndex(inputFormatMask, cursorPosition);
    bool ok = true;
    UChar mask = inputFormatMask[maskIndex];
    // Match the inputed character with input mask
    switch (mask) {
    case 'A':
        ok = !isASCIIDigit(inChar) && !isASCIILower(inChar) && isASCIIPrintable(inChar);
        break;
    case 'a':
        ok = !isASCIIDigit(inChar) && !isASCIIUpper(inChar) && isASCIIPrintable(inChar);
        break;
    case 'N':
        ok = isASCIIDigit(inChar);
        break;
    case 'n':
        ok = !isASCIIAlpha(inChar) && isASCIIPrintable(inChar);
        break;
    case 'X':
        ok = !isASCIILower(inChar) && isASCIIPrintable(inChar);
        break;
    case 'x':
        ok = !isASCIIUpper(inChar) && isASCIIPrintable(inChar);
        break;
    case 'M':
    case 'm':
        ok = isASCIIPrintable(inChar);
        break;
    default:
        ok = (mask == inChar);
        break;
    }

    return ok;
}

String InputElement::validateInputMask(InputElementData& data, String& inputMask)
{
    inputMask.replace("\\\\", "\\");

    bool isValid = true;
    bool hasWildcard = false;
    unsigned escapeCharCount = 0;
    unsigned maskLength = inputMask.length();
    UChar formatCode;
    for (unsigned i = 0; i < maskLength; ++i) {
        formatCode = inputMask[i];
        if (formatCodes().find(formatCode) == -1) {
            if (formatCode == '*' || (isASCIIDigit(formatCode) && formatCode != '0')) {
                // Validate codes which ends with '*f' or 'nf'
                formatCode = inputMask[++i];
                if ((i + 1 != maskLength) || formatCodes().find(formatCode) == -1) {
                    isValid = false;
                    break;
                }
                hasWildcard = true;
            } else if (formatCode == '\\') {
                // skip over the next mask character
                ++i;
                ++escapeCharCount;
            } else {
                isValid = false;
                break;
            }
        }
    }

    if (!isValid)
        return String();
    // calculate the number of characters allowed to be entered by input mask
    unsigned allowedLength = maskLength;
    if (escapeCharCount)
        allowedLength -= escapeCharCount;

    if (hasWildcard) {
        formatCode = inputMask[maskLength - 2];
        if (formatCode == '*')
            allowedLength = data.maxInputCharsAllowed();
        else {
            unsigned leftLen = String(&formatCode).toInt();
            allowedLength = leftLen + allowedLength - 2;
        }
    }

    if (allowedLength < data.maxInputCharsAllowed())
        data.setMaxInputCharsAllowed(allowedLength);

    return inputMask;
}

#endif

}
