/*
 * Copyright (C) 2006, 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.
 *
 * 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 "WebKitDLL.h"
#include "WebHTMLRepresentation.h"

#include "WebKit.h"
#include "WebFrame.h"
#include "WebKitStatisticsPrivate.h"
#pragma warning(push, 0)
#include <WebCore/BString.h>
#include <WebCore/HTMLInputElement.h>
#include <WebCore/TextResourceDecoder.h>
#pragma warning(pop)

using namespace WebCore;

// WebHTMLRepresentation ------------------------------------------------------

WebHTMLRepresentation::WebHTMLRepresentation()
    : m_refCount(0)
    , m_frame(0)
{
    WebHTMLRepresentationCount++;
    gClassCount++;
    gClassNameCount.add("WebHTMLRepresentation");
}

WebHTMLRepresentation::~WebHTMLRepresentation()
{
    if (m_frame) {
        m_frame->Release();
        m_frame = 0;
    }

    WebHTMLRepresentationCount--;
    gClassCount--;
    gClassNameCount.remove("WebHTMLRepresentation");
}

WebHTMLRepresentation* WebHTMLRepresentation::createInstance(WebFrame* frame)
{
    WebHTMLRepresentation* instance = new WebHTMLRepresentation();
    instance->m_frame = frame;
    frame->AddRef();
    instance->AddRef();
    return instance;
}

// IUnknown -------------------------------------------------------------------

HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::QueryInterface(REFIID riid, void** ppvObject)
{
    *ppvObject = 0;
    if (IsEqualGUID(riid, IID_IUnknown))
        *ppvObject = static_cast<IWebHTMLRepresentation*>(this);
    else if (IsEqualGUID(riid, IID_IWebHTMLRepresentation))
        *ppvObject = static_cast<IWebHTMLRepresentation*>(this);
    else if (IsEqualGUID(riid, IID_IWebDocumentRepresentation))
        *ppvObject = static_cast<IWebDocumentRepresentation*>(this);
    else
        return E_NOINTERFACE;

    AddRef();
    return S_OK;
}

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

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

    return newRef;
}

// IWebHTMLRepresentation --------------------------------------------------------------------

HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::supportedMIMETypes( 
        /* [out][in] */ BSTR* /*types*/,
        /* [out][in] */ int* /*cTypes*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::supportedNonImageMIMETypes( 
        /* [out][in] */ BSTR* /*types*/,
        /* [out][in] */ int* /*cTypes*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::supportedImageMIMETypes( 
        /* [out][in] */ BSTR* /*types*/,
        /* [out][in] */ int* /*cTypes*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::attributedStringFromDOMNodes( 
        /* [in] */ IDOMNode* /*startNode*/,
        /* [in] */ int /*startOffset*/,
        /* [in] */ IDOMNode* /*endNode*/,
        /* [in] */ int /*endOffset*/,
        /* [retval][out] */ IDataObject** /*attributedString*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::elementWithName( 
        /* [in] */ BSTR name,
        /* [in] */ IDOMElement* form,
        /* [retval][out] */ IDOMElement** element)
{
    if (!m_frame)
        return E_FAIL;

    return m_frame->elementWithName(name, form, element);
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::elementDoesAutoComplete( 
        /* [in] */ IDOMElement* element,
        /* [retval][out] */ BOOL* result)
{
    BOOL doesAutoComplete;
    HRESULT hr = m_frame->elementDoesAutoComplete(element, &doesAutoComplete);
    *result = doesAutoComplete ? TRUE : FALSE;
    return hr;
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::elementIsPassword( 
        /* [in] */ IDOMElement* element,
        /* [retval][out] */ BOOL* result)
{
    bool isPassword;
    HRESULT hr = m_frame->elementIsPassword(element, &isPassword);
    *result = isPassword ?  TRUE : FALSE;
    return hr;
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::formForElement( 
        /* [in] */ IDOMElement* element,
        /* [retval][out] */ IDOMElement** form)
{
    if (!m_frame)
        return E_FAIL;

    return m_frame->formForElement(element, form);
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::currentForm( 
        /* [retval][out] */ IDOMElement** form)
{
    if (!m_frame)
        return E_FAIL;

    return m_frame->currentForm(form);
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::controlsInForm( 
        /* [in] */ IDOMElement* form,
        /* [out][in] */ IDOMElement** controls,
        /* [out][in] */ int* cControls)
{
    return m_frame->controlsInForm(form, controls, cControls);
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::searchForLabels( 
        /* [size_is][in] */ BSTR* labels,
        /* [in] */ int cLabels,
        /* [in] */ IDOMElement* beforeElement,
        /* [retval][out] */ BSTR* result)
{
    return m_frame->searchForLabelsBeforeElement(labels, cLabels, beforeElement, result);
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::matchLabels( 
        /* [size_is][in] */ BSTR* labels,
        /* [in] */ int cLabels,
        /* [in] */ IDOMElement* againstElement,
        /* [retval][out] */ BSTR* result)
{
    return m_frame->matchLabelsAgainstElement(labels, cLabels, againstElement, result);
}

// IWebDocumentRepresentation ----------------------------------------------------------------

HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::setDataSource( 
        /* [in] */ IWebDataSource* /*dataSource*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::receivedData( 
        /* [in] */ IStream* /*data*/,
        /* [in] */ IWebDataSource* /*dataSource*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::receivedError( 
        /* [in] */ IWebError* /*error*/,
        /* [in] */ IWebDataSource* /*dataSource*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::finishedLoadingWithDataSource( 
        /* [in] */ IWebDataSource* /*dataSource*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::canProvideDocumentSource( 
        /* [retval][out] */ BOOL* result)
{
    bool canProvideSource;
    HRESULT hr = this->m_frame->canProvideDocumentSource(&canProvideSource);
    *result = canProvideSource ? TRUE : FALSE;
    return hr;
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::documentSource( 
        /* [retval][out] */ BSTR* source)
{
    if (!source)
        return E_FAIL;

    *source = 0;

    HRESULT hr = S_OK;

    COMPtr<IWebDataSource> dataSource;
    hr = m_frame->dataSource(&dataSource);
    if (FAILED(hr))
        return hr;

    COMPtr<IStream> data;
    hr = dataSource->data(&data);
    if (FAILED(hr))
        return hr;

    STATSTG stat;
    hr = data->Stat(&stat, STATFLAG_NONAME);
    if (FAILED(hr))
        return hr;

    if (stat.cbSize.HighPart || !stat.cbSize.LowPart)
        return E_FAIL;

    Vector<char> dataBuffer(stat.cbSize.LowPart);
    ULONG read;
    
    hr = data->Read(dataBuffer.data(), static_cast<ULONG>(dataBuffer.size()), &read);
    if (FAILED(hr))
        return hr;

    WebCore::Frame* frame = core(m_frame);
    if (!frame)
        return E_FAIL;

    WebCore::Document* doc = frame->document();
    if (!doc)
        return E_FAIL;

    WebCore::TextResourceDecoder* decoder = doc->decoder();
    if (!decoder)
        return E_FAIL;

    *source = WebCore::BString(decoder->encoding().decode(dataBuffer.data(), dataBuffer.size())).release();
    return S_OK;
}
    
HRESULT STDMETHODCALLTYPE WebHTMLRepresentation::title( 
        /* [retval][out] */ BSTR* /*docTitle*/)
{
    ASSERT_NOT_REACHED();
    return E_NOTIMPL;
}
