/**
 * 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"

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

#include "Attribute.h"
#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
#include "RenderImage.h"
#include "WMLNames.h"
#include "WMLVariables.h"

namespace WebCore {

using namespace WMLNames;

WMLImageElement::WMLImageElement(const QualifiedName& tagName, Document* doc)
    : WMLElement(tagName, doc)
    , m_imageLoader(this)
    , m_useFallbackAttribute(false)
{
}

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

WMLImageElement::~WMLImageElement()
{
}

bool WMLImageElement::mapToEntry(const QualifiedName& attrName, MappedAttributeEntry& result) const
{
    if (attrName == HTMLNames::widthAttr ||
        attrName == HTMLNames::heightAttr ||
        attrName == HTMLNames::vspaceAttr ||
        attrName == HTMLNames::hspaceAttr) {
        result = eUniversal;
        return false;
    }

    if (attrName == HTMLNames::alignAttr) {
        result = eReplaced;
        return false;
    }

    return WMLElement::mapToEntry(attrName, result);
}

void WMLImageElement::parseMappedAttribute(Attribute* attr)
{
    const QualifiedName& attrName = attr->name();

    if (attrName == HTMLNames::altAttr) {
        if (renderer() && renderer()->isImage())
            toRenderImage(renderer())->updateAltText();
    } else if (attrName == HTMLNames::srcAttr || attrName == localsrcAttr)
        m_imageLoader.updateFromElementIgnoringPreviousError();
    else if (attrName == HTMLNames::widthAttr)
        addCSSLength(attr, CSSPropertyWidth, attr->value());
    else if (attrName == HTMLNames::heightAttr)
        addCSSLength(attr, CSSPropertyHeight, attr->value());
    else if (attrName == HTMLNames::vspaceAttr) {
        addCSSLength(attr, CSSPropertyMarginTop, attr->value());
        addCSSLength(attr, CSSPropertyMarginBottom, attr->value());
    } else if (attrName == HTMLNames::hspaceAttr) {
        addCSSLength(attr, CSSPropertyMarginLeft, attr->value());
        addCSSLength(attr, CSSPropertyMarginRight, attr->value());
    } else if (attrName == HTMLNames::alignAttr)
        HTMLElement::addHTMLAlignmentToStyledElement(this, attr);
    else
        WMLElement::parseMappedAttribute(attr);
}

void WMLImageElement::attach()
{
    WMLElement::attach();

    if (renderer() && renderer()->isImage() && m_imageLoader.haveFiredBeforeLoadEvent()) {
        RenderImage* imageObj = toRenderImage(renderer());
        RenderImageResource* renderImageResource = imageObj->imageResource();
        if (renderImageResource->hasImage())
            return;
        renderImageResource->setCachedImage(m_imageLoader.image());
        
        // If we have no image at all because we have no src attribute, set
        // image height and width for the alt text instead.
        if (!m_imageLoader.image() && !imageObj->cachedImage())
            imageObj->setImageSizeForAltText();
    }
}

RenderObject* WMLImageElement::createRenderer(RenderArena* arena, RenderStyle*)
{
    RenderImage* image = new (arena) RenderImage(this);
    image->setImageResource(RenderImageResource::create());
    return image;
}

void WMLImageElement::insertedIntoDocument()
{
    // If we have been inserted from a renderer-less document,
    // our loader may have not fetched the image, so do it now.
    if (!m_imageLoader.image())
        m_imageLoader.updateFromElement();

    WMLElement::insertedIntoDocument();
}

bool WMLImageElement::isURLAttribute(Attribute* attr) const
{
    return attr->name() == HTMLNames::srcAttr
           || attr->name() == localsrcAttr;
}

const QualifiedName& WMLImageElement::imageSourceAttributeName() const
{
    // Spec: Any 'localsrc' parameter specified takes precedence over the 
    // image specified in the src parameter.
    if (hasAttribute(localsrcAttr) && !m_useFallbackAttribute)
        return localsrcAttr;

    return HTMLNames::srcAttr;
}

String WMLImageElement::altText() const
{
    return substituteVariableReferences(getAttribute(HTMLNames::altAttr), document());
}

}

#endif
