/*
 * Copyright (C) 2007 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. 
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "EditingDelegate.h"

#include "DumpRenderTree.h"
#include "LayoutTestController.h"
#include <WebCore/COMPtr.h>
#include <wtf/Platform.h>
#include <JavaScriptCore/Assertions.h>
#include <string>
#include <tchar.h>

using std::wstring;

EditingDelegate::EditingDelegate()
    : m_refCount(1)
    , m_acceptsEditing(true)
{
}

// IUnknown
HRESULT STDMETHODCALLTYPE EditingDelegate::QueryInterface(REFIID riid, void** ppvObject)
{
    *ppvObject = 0;
    if (IsEqualGUID(riid, IID_IUnknown))
        *ppvObject = static_cast<IWebEditingDelegate*>(this);
    else if (IsEqualGUID(riid, IID_IWebEditingDelegate))
        *ppvObject = static_cast<IWebEditingDelegate*>(this);
    else
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
}

ULONG STDMETHODCALLTYPE EditingDelegate::AddRef(void)
{
    return ++m_refCount;
}

ULONG STDMETHODCALLTYPE EditingDelegate::Release(void)
{
    ULONG newRef = --m_refCount;
    if (!newRef)
        delete this;

    return newRef;
}

static wstring dumpPath(IDOMNode* node)
{
    ASSERT(node);

    wstring result;

    BSTR name;
    if (FAILED(node->nodeName(&name)))
        return result;
    result.assign(name, SysStringLen(name));
    SysFreeString(name);

    COMPtr<IDOMNode> parent;
    if (SUCCEEDED(node->parentNode(&parent)))
        result += TEXT(" > ") + dumpPath(parent.get());

    return result;
}

static wstring dump(IDOMRange* range)
{
    ASSERT(range);

    int startOffset;
    if (FAILED(range->startOffset(&startOffset)))
        return 0;

    int endOffset;
    if (FAILED(range->endOffset(&endOffset)))
        return 0;

    COMPtr<IDOMNode> startContainer;
    if (FAILED(range->startContainer(&startContainer)))
        return 0;

    COMPtr<IDOMNode> endContainer;
    if (FAILED(range->endContainer(&endContainer)))
        return 0;

    wchar_t buffer[1024];
    _snwprintf(buffer, ARRAYSIZE(buffer), L"range from %ld of %s to %ld of %s", startOffset, dumpPath(startContainer.get()), endOffset, dumpPath(endContainer.get()));
    return buffer;
}

HRESULT STDMETHODCALLTYPE EditingDelegate::shouldBeginEditingInDOMRange( 
    /* [in] */ IWebView* webView,
    /* [in] */ IDOMRange* range,
    /* [retval][out] */ BOOL* result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
        _tprintf(TEXT("EDITING DELEGATE: shouldBeginEditingInDOMRange:%s\n"), dump(range));

    *result = m_acceptsEditing;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE EditingDelegate::shouldEndEditingInDOMRange( 
    /* [in] */ IWebView* webView,
    /* [in] */ IDOMRange* range,
    /* [retval][out] */ BOOL* result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
        _tprintf(TEXT("EDITING DELEGATE: shouldEndEditingInDOMRange:%s\n"), dump(range));

    *result = m_acceptsEditing;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE EditingDelegate::shouldInsertNode( 
    /* [in] */ IWebView* webView,
    /* [in] */ IDOMNode* node,
    /* [in] */ IDOMRange* range,
    /* [in] */ WebViewInsertAction action)
{
    static LPCTSTR insertactionstring[] = {
        TEXT("WebViewInsertActionTyped"),
        TEXT("WebViewInsertActionPasted"),
        TEXT("WebViewInsertActionDropped"),
    };

    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
        _tprintf(TEXT("EDITING DELEGATE: shouldInsertNode:%s replacingDOMRange:%s givenAction:%s\n"), dumpPath(node), dump(range), insertactionstring[action]);

    return S_OK;
}

HRESULT STDMETHODCALLTYPE EditingDelegate::shouldInsertText( 
    /* [in] */ IWebView* webView,
    /* [in] */ BSTR text,
    /* [in] */ IDOMRange* range,
    /* [in] */ WebViewInsertAction action,
    /* [retval][out] */ BOOL* result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    static LPCTSTR insertactionstring[] = {
        TEXT("WebViewInsertActionTyped"),
        TEXT("WebViewInsertActionPasted"),
        TEXT("WebViewInsertActionDropped"),
    };

    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
        _tprintf(TEXT("EDITING DELEGATE: shouldInsertText:%s replacingDOMRange:%s givenAction:%s\n"), text ? text : TEXT(""), dump(range), insertactionstring[action]);

    *result = m_acceptsEditing;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE EditingDelegate::shouldDeleteDOMRange( 
    /* [in] */ IWebView* webView,
    /* [in] */ IDOMRange* range,
    /* [retval][out] */ BOOL* result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
        _tprintf(TEXT("EDITING DELEGATE: shouldDeleteDOMRange:%s\n"), dump(range));

    *result = m_acceptsEditing;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE EditingDelegate::shouldChangeSelectedDOMRange( 
    /* [in] */ IWebView* webView,
    /* [in] */ IDOMRange* currentRange,
    /* [in] */ IDOMRange* proposedRange,
    /* [in] */ WebSelectionAffinity selectionAffinity,
    /* [in] */ BOOL stillSelecting,
    /* [retval][out] */ BOOL* result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    static LPCTSTR affinitystring[] = {
        TEXT("NSSelectionAffinityUpstream"),
        TEXT("NSSelectionAffinityDownstream")
    };
    static LPCTSTR boolstring[] = {
        TEXT("FALSE"),
        TEXT("TRUE")
    };

    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
        _tprintf(TEXT("EDITING DELEGATE: shouldChangeSelectedDOMRange:%s toDOMRange:%s affinity:%s stillSelecting:%s\n"), dump(currentRange), dump(proposedRange), affinitystring[selectionAffinity], boolstring[stillSelecting]);

    *result = m_acceptsEditing;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE EditingDelegate::shouldApplyStyle( 
    /* [in] */ IWebView* webView,
    /* [in] */ IDOMCSSStyleDeclaration* style,
    /* [in] */ IDOMRange* range,
    /* [retval][out] */ BOOL* result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
        _tprintf(TEXT("EDITING DELEGATE: shouldApplyStyle:%s toElementsInDOMRange:%s\n"), TEXT("'style description'")/*[[style description] UTF8String]*/, dump(range));

    *result = m_acceptsEditing;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE EditingDelegate::shouldChangeTypingStyle( 
    /* [in] */ IWebView* webView,
    /* [in] */ IDOMCSSStyleDeclaration* currentStyle,
    /* [in] */ IDOMCSSStyleDeclaration* proposedStyle,
    /* [retval][out] */ BOOL* result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
        _tprintf(TEXT("EDITING DELEGATE: shouldChangeTypingStyle:%s toStyle:%s\n"), TEXT("'currentStyle description'"), TEXT("'proposedStyle description'"));

    *result = m_acceptsEditing;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE EditingDelegate::doPlatformCommand( 
    /* [in] */ IWebView *webView,
    /* [in] */ BSTR command,
    /* [retval][out] */ BOOL *result)
{
    if (!result) {
        ASSERT_NOT_REACHED();
        return E_POINTER;
    }

    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
        _tprintf(TEXT("EDITING DELEGATE: doPlatformCommand:%s\n"), command ? command : TEXT(""));

    *result = m_acceptsEditing;
    return S_OK;
}

HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidBeginEditing( 
    /* [in] */ IWebNotification* notification)
{
    if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
        BSTR name;
        notification->name(&name);
        _tprintf(TEXT("EDITING DELEGATE: webViewDidBeginEditing:%s\n"), name ? name : TEXT(""));
        SysFreeString(name);
    }
    return S_OK;
}

HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChange( 
    /* [in] */ IWebNotification *notification)
{
    if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
        BSTR name;
        notification->name(&name);
        _tprintf(TEXT("EDITING DELEGATE: webViewDidBeginEditing:%s\n"), name ? name : TEXT(""));
        SysFreeString(name);
    }
    return S_OK;
}

HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidEndEditing( 
    /* [in] */ IWebNotification *notification)
{
    if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
        BSTR name;
        notification->name(&name);
        _tprintf(TEXT("EDITING DELEGATE: webViewDidEndEditing:%s\n"), name ? name : TEXT(""));
        SysFreeString(name);
    }
    return S_OK;
}

HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChangeTypingStyle( 
    /* [in] */ IWebNotification *notification)
{
    if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
        BSTR name;
        notification->name(&name);
        _tprintf(TEXT("EDITING DELEGATE: webViewDidChangeTypingStyle:%s\n"), name ? name : TEXT(""));
        SysFreeString(name);
    }
    return S_OK;
}

HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChangeSelection( 
    /* [in] */ IWebNotification *notification)
{
    if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
        BSTR name;
        notification->name(&name);
        _tprintf(TEXT("EDITING DELEGATE: webViewDidChangeSelection:%s\n"), name ? name : TEXT(""));
        SysFreeString(name);
    }
    return S_OK;
}

static int indexOfFirstWordCharacter(const TCHAR* text)
{
    const TCHAR* cursor = text;
    while (*cursor && !isalpha(*cursor))
        ++cursor;
    return *cursor ? (cursor - text) : -1;
};

static int wordLength(const TCHAR* text)
{
    const TCHAR* cursor = text;
    while (*cursor && isalpha(*cursor))
        ++cursor;
    return cursor - text;
};

HRESULT STDMETHODCALLTYPE EditingDelegate::checkSpellingOfString(
            /* [in] */ IWebView* view,
            /* [in] */ LPCTSTR text,
            /* [in] */ int length,
            /* [out] */ int* misspellingLocation,
            /* [out] */ int* misspellingLength)
{
    static const TCHAR* misspelledWords[] = {
        // These words are known misspelled words in webkit tests.
        // If there are other misspelled words in webkit tests, please add them in
        // this array.
        TEXT("foo"),
        TEXT("Foo"),
        TEXT("baz"),
        TEXT("fo"),
        TEXT("LibertyF"),
        TEXT("chello"),
        TEXT("xxxtestxxx"),
        TEXT("XXxxx"),
        TEXT("Textx"),
        TEXT("blockquoted"),
        TEXT("asd"),
        TEXT("Lorem"),
        TEXT("Nunc"),
        TEXT("Curabitur"),
        TEXT("eu"),
        TEXT("adlj"),
        TEXT("adaasj"),
        TEXT("sdklj"),
        TEXT("jlkds"),
        TEXT("jsaada"),
        TEXT("jlda"),
        TEXT("zz"),
        TEXT("contentEditable"),
        0,
    };

    wstring textString(text, length);
    int wordStart = indexOfFirstWordCharacter(textString.c_str());
    if (-1 == wordStart)
        return S_OK;
    wstring word = textString.substr(wordStart, wordLength(textString.c_str() + wordStart));
    for (size_t i = 0; misspelledWords[i]; ++i) {
        if (word == misspelledWords[i]) {
            *misspellingLocation = wordStart;
            *misspellingLength = word.size();
            break;
        }
    }

    return S_OK;
}
