/**
 * Copyright (C) 2008, 2009 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"

#if ENABLE(WML)
#include "WMLGoElement.h"

#include "Attribute.h"
#include "FormData.h"
#include "FormDataBuilder.h"
#include "FormSubmission.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "HTMLNames.h"
#include "ResourceRequest.h"
#include "TextEncoding.h"
#include "WMLCardElement.h"
#include "WMLDocument.h"
#include "WMLNames.h"
#include "WMLPageState.h"
#include "WMLPostfieldElement.h"
#include "WMLTimerElement.h"
#include "WMLVariables.h"
#include <wtf/text/CString.h>

namespace WebCore {

using namespace WMLNames;

WMLGoElement::WMLGoElement(const QualifiedName& tagName, Document* doc)
    : WMLTaskElement(tagName, doc)
{
}
 
PassRefPtr<WMLGoElement> WMLGoElement::create(const QualifiedName& tagName, Document* document)
{
    return adoptRef(new WMLGoElement(tagName, document));
}

void WMLGoElement::registerPostfieldElement(WMLPostfieldElement* postfield)
{
    ASSERT(m_postfieldElements.find(postfield) == WTF::notFound);
    m_postfieldElements.append(postfield);
}
 
void WMLGoElement::deregisterPostfieldElement(WMLPostfieldElement* postfield)
{
    size_t position = m_postfieldElements.find(postfield);
    ASSERT(position != WTF::notFound);
    m_postfieldElements.remove(position);
}

void WMLGoElement::parseMappedAttribute(Attribute* attr)
{
    if (attr->name() == HTMLNames::methodAttr)
        m_formAttributes.parseMethodType(attr->value());
    else if (attr->name() == HTMLNames::enctypeAttr)
        m_formAttributes.parseEncodingType(parseValueSubstitutingVariableReferences(attr->value()));
    else if (attr->name() == HTMLNames::accept_charsetAttr)
        m_formAttributes.setAcceptCharset(parseValueForbiddingVariableReferences(attr->value()));
    else
        WMLTaskElement::parseMappedAttribute(attr);
}

void WMLGoElement::executeTask()
{
    ASSERT(document()->isWMLDocument());
    WMLDocument* document = static_cast<WMLDocument*>(this->document());

    WMLPageState* pageState = wmlPageStateForDocument(document);
    if (!pageState)
        return;

    WMLCardElement* card = document->activeCard();
    if (!card)
        return;

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

    FrameLoader* loader = frame->loader();
    if (!loader)
        return;

    String href = getAttribute(HTMLNames::hrefAttr);
    if (href.isEmpty())
        return;

    // Substitute variables within target url attribute value
    KURL url = document->completeURL(substituteVariableReferences(href, document, WMLVariableEscapingEscape));
    if (url.isEmpty())
        return;

    storeVariableState(pageState);

    // Stop the timer of the current card if it is active
    if (WMLTimerElement* eventTimer = card->eventTimer())
        eventTimer->stop();

    // FIXME: 'newcontext' handling not implemented for external cards
    bool inSameDeck = document->url().path() == url.path();
    if (inSameDeck && url.hasFragmentIdentifier()) {
        if (WMLCardElement* card = WMLCardElement::findNamedCardInDocument(document, url.fragmentIdentifier())) {
            if (card->isNewContext())
                pageState->reset();
        }
    }

    // Prepare loading the destination url
    ResourceRequest request(url);

    if (getAttribute(sendrefererAttr) == "true")
        request.setHTTPReferrer(loader->outgoingReferrer());

    String cacheControl = getAttribute(cache_controlAttr);

    if (m_formAttributes.method() == FormSubmission::PostMethod)
        preparePOSTRequest(request, inSameDeck, cacheControl);
    else
        prepareGETRequest(request, url);

    // Set HTTP cache-control header if needed
    if (!cacheControl.isEmpty()) {
        request.setHTTPHeaderField("cache-control", cacheControl);

        if (cacheControl == "no-cache")
            request.setCachePolicy(ReloadIgnoringCacheData);
    }

    loader->load(request, false);
}

void WMLGoElement::preparePOSTRequest(ResourceRequest& request, bool inSameDeck, const String& cacheControl)
{
    request.setHTTPMethod("POST");

    if (inSameDeck && cacheControl != "no-cache") {
        request.setCachePolicy(ReturnCacheDataDontLoad);
        return;
    }

    RefPtr<FormData> data;

    if (m_formAttributes.isMultiPartForm()) { // multipart/form-data
        Vector<char> boundary = FormDataBuilder::generateUniqueBoundaryString();
        data = createFormData(boundary.data());
        request.setHTTPContentType(m_formAttributes.encodingType() + "; boundary=" + boundary.data());
    } else {
        // text/plain or application/x-www-form-urlencoded
        data = createFormData(CString());
        request.setHTTPContentType(m_formAttributes.encodingType());
    }

    request.setHTTPBody(data.get());
}

void WMLGoElement::prepareGETRequest(ResourceRequest& request, const KURL& url)
{
    request.setHTTPMethod("GET");

    // Eventually display error message?
    if (m_formAttributes.isMultiPartForm())
        return;

    RefPtr<FormData> data = createFormData(CString());

    KURL remoteURL(url);
    remoteURL.setQuery(data->flattenToString());
    request.setURL(remoteURL);
}

PassRefPtr<FormData> WMLGoElement::createFormData(const CString& boundary)
{
    CString key;
    CString value;

    Vector<char> encodedData;
    TextEncoding encoding = FormDataBuilder::encodingFromAcceptCharset(m_formAttributes.acceptCharset(), document()).encodingForFormSubmission();

    Vector<WMLPostfieldElement*>::iterator it = m_postfieldElements.begin();
    Vector<WMLPostfieldElement*>::iterator end = m_postfieldElements.end();

    RefPtr<FormData> result = FormData::create();
    for (; it != end; ++it) {
        (*it)->encodeData(encoding, key, value);

        if (m_formAttributes.isMultiPartForm()) {
            Vector<char> header;
            FormDataBuilder::beginMultiPartHeader(header, boundary, key);
            FormDataBuilder::finishMultiPartHeader(header);
            result->appendData(header.data(), header.size());

            if (size_t dataSize = value.length())
                result->appendData(value.data(), dataSize);

            result->appendData("\r\n", 2);
        } else
            FormDataBuilder::addKeyValuePairAsFormData(encodedData, key, value);
    }

    if (m_formAttributes.isMultiPartForm())
        FormDataBuilder::addBoundaryToMultiPartHeader(encodedData, boundary, true);

    result->appendData(encodedData.data(), encodedData.size());
    return result;
}

}

#endif
