/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 *           (C) 2000 Simon Hausmann (hausmann@kde.org)
 *           (C) 2001 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2004-2017 Apple Inc. All rights reserved.
 *
 * 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 "HTMLFrameSetElement.h"

#include "CSSPropertyNames.h"
#include "DOMWrapperWorld.h"
#include "Document.h"
#include "ElementIterator.h"
#include "Event.h"
#include "Frame.h"
#include "FrameLoader.h"
#include "FrameLoaderClient.h"
#include "HTMLBodyElement.h"
#include "HTMLCollection.h"
#include "HTMLFrameElement.h"
#include "HTMLNames.h"
#include "HTMLParserIdioms.h"
#include "Length.h"
#include "MouseEvent.h"
#include "RenderFrameSet.h"
#include "Text.h"
#include <wtf/IsoMallocInlines.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(HTMLFrameSetElement);

using namespace HTMLNames;

HTMLFrameSetElement::HTMLFrameSetElement(const QualifiedName& tagName, Document& document)
    : HTMLElement(tagName, document)
    , m_totalRows(1)
    , m_totalCols(1)
    , m_border(6)
    , m_borderSet(false)
    , m_borderColorSet(false)
    , m_frameborder(true)
    , m_frameborderSet(false)
    , m_noresize(false)
{
    ASSERT(hasTagName(framesetTag));
    setHasCustomStyleResolveCallbacks();
}

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

bool HTMLFrameSetElement::hasPresentationalHintsForAttribute(const QualifiedName& name) const
{
    if (name == bordercolorAttr)
        return true;
    return HTMLElement::hasPresentationalHintsForAttribute(name);
}

void HTMLFrameSetElement::collectPresentationalHintsForAttribute(const QualifiedName& name, const AtomString& value, MutableStyleProperties& style)
{
    if (name == bordercolorAttr)
        addHTMLColorToStyle(style, CSSPropertyBorderColor, value);
    else
        HTMLElement::collectPresentationalHintsForAttribute(name, value, style);
}

void HTMLFrameSetElement::parseAttribute(const QualifiedName& name, const AtomString& value)
{
    if (name == rowsAttr) {
        // FIXME: What is the right thing to do when removing this attribute?
        // Why not treat it the same way we treat setting it to the empty string?
        if (!value.isNull()) {
            m_rowLengths = newLengthArray(value.string(), m_totalRows);
            // FIXME: Would be nice to optimize the case where m_rowLengths did not change.
            invalidateStyleForSubtree();
        }
        return;
    }

    if (name == colsAttr) {
        // FIXME: What is the right thing to do when removing this attribute?
        // Why not treat it the same way we treat setting it to the empty string?
        if (!value.isNull()) {
            m_colLengths = newLengthArray(value.string(), m_totalCols);
            // FIXME: Would be nice to optimize the case where m_colLengths did not change.
            invalidateStyleForSubtree();
        }
        return;
    }

    if (name == frameborderAttr) {
        if (!value.isNull()) {
            if (equalLettersIgnoringASCIICase(value, "no"_s) || value == "0"_s) {
                m_frameborder = false;
                m_frameborderSet = true;
            } else if (equalLettersIgnoringASCIICase(value, "yes"_s) || value == "1"_s) {
                m_frameborderSet = true;
            }
        } else {
            m_frameborder = false;
            m_frameborderSet = false;
        }
        // FIXME: Do we need to trigger repainting?
        return;
    }

    if (name == noresizeAttr) {
        // FIXME: This should set m_noresize to false if the value is null.
        m_noresize = true;
        return;
    }

    if (name == borderAttr) {
        if (!value.isNull()) {
            m_border = parseHTMLInteger(value).value_or(0);
            m_borderSet = true;
        } else
            m_borderSet = false;
        // FIXME: Do we need to trigger repainting?
        return;
    }

    if (name == bordercolorAttr) {
        m_borderColorSet = !value.isEmpty();
        // FIXME: Clearly wrong: This can overwrite the value inherited from the parent frameset.
        // FIXME: Do we need to trigger repainting?
        return;
    }

    auto& eventName = HTMLBodyElement::eventNameForWindowEventHandlerAttribute(name);
    if (!eventName.isNull()) {
        document().setWindowAttributeEventListener(eventName, name, value, mainThreadNormalWorld());
        return;
    }

    HTMLElement::parseAttribute(name, value);
}

bool HTMLFrameSetElement::rendererIsNeeded(const RenderStyle& style)
{
    // For compatibility, frames render even when display: none is set.
    // However, we delay creating a renderer until stylesheets have loaded. 
    return !style.isNotFinal();
}

RenderPtr<RenderElement> HTMLFrameSetElement::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
{
    if (style.hasContent())
        return RenderElement::createFor(*this, WTFMove(style));
    
    return createRenderer<RenderFrameSet>(*this, WTFMove(style));
}

RefPtr<HTMLFrameSetElement> HTMLFrameSetElement::findContaining(Element* descendant)
{
    return ancestorsOfType<HTMLFrameSetElement>(*descendant).first();
}

void HTMLFrameSetElement::willAttachRenderers()
{
    // Inherit default settings from parent frameset.
    // FIXME: This is not dynamic.
    const auto containingFrameSet = findContaining(this);
    if (!containingFrameSet)
        return;
    if (!m_frameborderSet)
        m_frameborder = containingFrameSet->hasFrameBorder();
    if (m_frameborder) {
        if (!m_borderSet)
            m_border = containingFrameSet->border();
        if (!m_borderColorSet)
            m_borderColorSet = containingFrameSet->hasBorderColor();
    }
    if (!m_noresize)
        m_noresize = containingFrameSet->noResize();
}

void HTMLFrameSetElement::defaultEventHandler(Event& event)
{
    if (is<MouseEvent>(event) && !m_noresize && is<RenderFrameSet>(renderer())) {
        if (downcast<RenderFrameSet>(*renderer()).userResize(downcast<MouseEvent>(event))) {
            event.setDefaultHandled();
            return;
        }
    }
    HTMLElement::defaultEventHandler(event);
}

void HTMLFrameSetElement::willRecalcStyle(Style::Change)
{
    if (needsStyleRecalc() && renderer())
        renderer()->setNeedsLayout();
}

Node::InsertedIntoAncestorResult HTMLFrameSetElement::insertedIntoAncestor(InsertionType insertionType, ContainerNode& parentOfInsertedTree)
{
    HTMLElement::insertedIntoAncestor(insertionType, parentOfInsertedTree);
    return InsertedIntoAncestorResult::Done;
}

void HTMLFrameSetElement::removedFromAncestor(RemovalType removalType, ContainerNode& oldParentOfRemovedTree)
{
    HTMLElement::removedFromAncestor(removalType, oldParentOfRemovedTree);
}

WindowProxy* HTMLFrameSetElement::namedItem(const AtomString& name)
{
    RefPtr frameElement = children()->namedItem(name);
    if (!is<HTMLFrameElement>(frameElement))
        return nullptr;

    return downcast<HTMLFrameElement>(*frameElement).contentWindow();
}

Vector<AtomString> HTMLFrameSetElement::supportedPropertyNames() const
{
    // NOTE: Left empty as no specification defines this named getter and we
    //       have not historically exposed these named items for enumeration.
    return { };
}

} // namespace WebCore
