/*
 * Copyright (C) 2016 Igalia S.L.
 *
 * 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 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 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 "RenderThemeGadget.h"

#if !USE(GTK4)

#include "FloatRect.h"
#include "GRefPtrGtk.h"

namespace WebCore {

std::unique_ptr<RenderThemeGadget> RenderThemeGadget::create(const RenderThemeGadget::Info& info, RenderThemeGadget* parent, const Vector<RenderThemeGadget::Info> siblings, unsigned position)
{
    switch (info.type) {
    case RenderThemeGadget::Type::Generic:
        return makeUnique<RenderThemeGadget>(info, parent, siblings, position);
    case RenderThemeGadget::Type::Scrollbar:
        return makeUnique<RenderThemeScrollbarGadget>(info, parent, siblings, position);
    }

    ASSERT_NOT_REACHED();
    return nullptr;
}

static GRefPtr<GtkStyleContext> createStyleContext(GtkWidgetPath* path, GtkStyleContext* parent)
{
    GRefPtr<GtkStyleContext> context = adoptGRef(gtk_style_context_new());
    gtk_style_context_set_path(context.get(), path);
    gtk_style_context_set_parent(context.get(), parent);
    return context;
}

static void appendElementToPath(GtkWidgetPath* path, const RenderThemeGadget::Info& info)
{
    // Scrollbars need to use its GType to be able to get non-CSS style properties.
    gtk_widget_path_append_type(path, info.type == RenderThemeGadget::Type::Scrollbar ? GTK_TYPE_SCROLLBAR : G_TYPE_NONE);
    gtk_widget_path_iter_set_object_name(path, -1, info.name);
    for (const auto* className : info.classList)
        gtk_widget_path_iter_add_class(path, -1, className);
}

RenderThemeGadget::RenderThemeGadget(const RenderThemeGadget::Info& info, RenderThemeGadget* parent, const Vector<RenderThemeGadget::Info> siblings, unsigned position)
{
    GRefPtr<GtkWidgetPath> path = parent ? adoptGRef(gtk_widget_path_copy(gtk_style_context_get_path(parent->context()))) : adoptGRef(gtk_widget_path_new());
    if (!siblings.isEmpty()) {
        GRefPtr<GtkWidgetPath> siblingsPath = adoptGRef(gtk_widget_path_new());
        for (const auto& siblingInfo : siblings)
            appendElementToPath(siblingsPath.get(), siblingInfo);
        gtk_widget_path_append_with_siblings(path.get(), siblingsPath.get(), position);
    } else
        appendElementToPath(path.get(), info);
    m_context = createStyleContext(path.get(), parent ? parent->context() : nullptr);
}

RenderThemeGadget::~RenderThemeGadget() = default;

GtkBorder RenderThemeGadget::marginBox() const
{
    GtkBorder returnValue;
    gtk_style_context_get_margin(m_context.get(), gtk_style_context_get_state(m_context.get()), &returnValue);
    return returnValue;
}

GtkBorder RenderThemeGadget::borderBox() const
{
    GtkBorder returnValue;
    gtk_style_context_get_border(m_context.get(), gtk_style_context_get_state(m_context.get()), &returnValue);
    return returnValue;
}

GtkBorder RenderThemeGadget::paddingBox() const
{
    GtkBorder returnValue;
    gtk_style_context_get_padding(m_context.get(), gtk_style_context_get_state(m_context.get()), &returnValue);
    return returnValue;
}

GtkBorder RenderThemeGadget::contentsBox() const
{
    auto margin = marginBox();
    auto border = borderBox();
    auto padding = paddingBox();
    padding.left += margin.left + border.left;
    padding.right += margin.right + border.right;
    padding.top += margin.top + border.top;
    padding.bottom += margin.bottom + border.bottom;
    return padding;
}

Color RenderThemeGadget::color() const
{
    GdkRGBA returnValue;
    gtk_style_context_get_color(m_context.get(), gtk_style_context_get_state(m_context.get()), &returnValue);
    return returnValue;
}

Color RenderThemeGadget::backgroundColor() const
{
    GdkRGBA returnValue;

    ALLOW_DEPRECATED_DECLARATIONS_BEGIN
    gtk_style_context_get_background_color(m_context.get(), gtk_style_context_get_state(m_context.get()), &returnValue);
    ALLOW_DEPRECATED_DECLARATIONS_END

    return returnValue;
}

double RenderThemeGadget::opacity() const
{
    double returnValue;
    gtk_style_context_get(m_context.get(), gtk_style_context_get_state(m_context.get()), "opacity", &returnValue, nullptr);
    return returnValue;
}

GtkStateFlags RenderThemeGadget::state() const
{
    return gtk_style_context_get_state(m_context.get());
}

void RenderThemeGadget::setState(GtkStateFlags state)
{
    gtk_style_context_set_state(m_context.get(), state);
}

IntSize RenderThemeGadget::minimumSize() const
{
    int width, height;
    gtk_style_context_get(m_context.get(), gtk_style_context_get_state(m_context.get()), "min-width", &width, "min-height", &height, nullptr);
    return IntSize(width, height);
}

IntSize RenderThemeGadget::preferredSize() const
{
    auto margin = marginBox();
    auto border = borderBox();
    auto padding = paddingBox();
    auto minSize = minimumSize();
    minSize.expand(margin.left + margin.right + border.left + border.right + padding.left + padding.right,
        margin.top + margin.bottom + border.top + border.bottom + padding.top + padding.bottom);
    return minSize;
}

bool RenderThemeGadget::render(cairo_t* cr, const FloatRect& paintRect, FloatRect* contentsRect)
{
    FloatRect rect = paintRect;

    auto margin = marginBox();
    rect.move(margin.left, margin.top);
    rect.contract(margin.left + margin.right, margin.top + margin.bottom);

    auto minSize = minimumSize();
    rect.setWidth(std::max<float>(rect.width(), minSize.width()));
    rect.setHeight(std::max<float>(rect.height(), minSize.height()));

    gtk_render_background(m_context.get(), cr, rect.x(), rect.y(), rect.width(), rect.height());
    gtk_render_frame(m_context.get(), cr, rect.x(), rect.y(), rect.width(), rect.height());

    if (contentsRect) {
        auto border = borderBox();
        auto padding = paddingBox();
        *contentsRect = rect;
        contentsRect->move(border.left + padding.left, border.top + padding.top);
        contentsRect->contract(border.left + border.right + padding.left + padding.right, border.top + border.bottom + padding.top + padding.bottom);
    }

    return true;
}

RenderThemeBoxGadget::RenderThemeBoxGadget(const RenderThemeGadget::Info& info, GtkOrientation orientation, const Vector<RenderThemeGadget::Info> children, RenderThemeGadget* parent)
    : RenderThemeGadget(info, parent, Vector<RenderThemeGadget::Info>(), 0)
    , m_orientation(orientation)
{
    m_children.reserveCapacity(children.size());
    unsigned index = 0;
    for (const auto& childInfo : children)
        m_children.uncheckedAppend(RenderThemeGadget::create(childInfo, this, children, index++));
}

IntSize RenderThemeBoxGadget::preferredSize() const
{
    IntSize childrenSize;
    for (const auto& child : m_children) {
        IntSize childSize = child->preferredSize();
        switch (m_orientation) {
        case GTK_ORIENTATION_HORIZONTAL:
            childrenSize.setWidth(childrenSize.width() + childSize.width());
            childrenSize.setHeight(std::max(childrenSize.height(), childSize.height()));
            break;
        case GTK_ORIENTATION_VERTICAL:
            childrenSize.setWidth(std::max(childrenSize.width(), childSize.width()));
            childrenSize.setHeight(childrenSize.height() + childSize.height());
            break;
        }
    }
    return RenderThemeGadget::preferredSize().expandedTo(childrenSize);
}

RenderThemeScrollbarGadget::RenderThemeScrollbarGadget(const RenderThemeGadget::Info& info, RenderThemeGadget* parent, const Vector<RenderThemeGadget::Info> siblings, unsigned position)
    : RenderThemeGadget(info, parent, siblings, position)
{
    gboolean hasBackward, hasForward, hasSecondaryBackward, hasSecondaryForward;
    gtk_style_context_get_style(m_context.get(), "has-backward-stepper", &hasBackward, "has-forward-stepper", &hasForward,
        "has-secondary-backward-stepper", &hasSecondaryBackward, "has-secondary-forward-stepper", &hasSecondaryForward, nullptr);
    if (hasBackward)
        m_steppers.add(Steppers::Backward);
    if (hasForward)
        m_steppers.add(Steppers::Forward);
    if (hasSecondaryBackward)
        m_steppers.add(Steppers::SecondaryBackward);
    if (hasSecondaryForward)
        m_steppers.add(Steppers::SecondaryForward);
}

void RenderThemeScrollbarGadget::renderStepper(cairo_t* cr, const FloatRect& paintRect, RenderThemeGadget* stepperGadget, GtkOrientation orientation, Steppers stepper)
{
    FloatRect contentsRect;
    stepperGadget->render(cr, paintRect, &contentsRect);
    double angle;
    switch (stepper) {
    case Steppers::Backward:
    case Steppers::SecondaryBackward:
        angle = orientation == GTK_ORIENTATION_VERTICAL ? 0 : 3 * (G_PI / 2);
        break;
    case Steppers::Forward:
    case Steppers::SecondaryForward:
        angle = orientation == GTK_ORIENTATION_VERTICAL ? G_PI / 2 : G_PI;
        break;
    }

    int stepperSize = std::max(contentsRect.width(), contentsRect.height());
    gtk_render_arrow(stepperGadget->context(), cr, angle, contentsRect.x() + (contentsRect.width() - stepperSize) / 2,
        contentsRect.y() + (contentsRect.height() - stepperSize) / 2, stepperSize);
}

} // namespace WebCore

#endif // !USE(GTK4)
