/**
 * This file is part of the theme implementation for form controls in WebCore.
 *
 * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Computer, Inc.
 *
 * 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 "core/paint/ThemePainter.h"

#include "core/InputTypeNames.h"
#include "core/frame/FrameView.h"
#include "core/html/HTMLDataListElement.h"
#include "core/html/HTMLDataListOptionsCollection.h"
#include "core/html/HTMLInputElement.h"
#include "core/html/HTMLOptionElement.h"
#include "core/html/parser/HTMLParserIdioms.h"
#include "core/html/shadow/ShadowElementNames.h"
#include "core/layout/LayoutTheme.h"
#include "core/paint/MediaControlsPainter.h"
#include "core/paint/PaintInfo.h"
#include "core/style/ComputedStyle.h"
#include "platform/Theme.h"
#include "platform/graphics/GraphicsContextStateSaver.h"
#include "public/platform/Platform.h"
#include "public/platform/WebFallbackThemeEngine.h"
#include "public/platform/WebRect.h"

// The methods in this file are shared by all themes on every platform.

namespace blink {

static WebFallbackThemeEngine::State getWebFallbackThemeState(const LayoutObject& o)
{
    if (!LayoutTheme::isEnabled(o))
        return WebFallbackThemeEngine::StateDisabled;
    if (LayoutTheme::isPressed(o))
        return WebFallbackThemeEngine::StatePressed;
    if (LayoutTheme::isHovered(o))
        return WebFallbackThemeEngine::StateHover;

    return WebFallbackThemeEngine::StateNormal;
}

ThemePainter::ThemePainter(Theme* platformTheme)
    : m_platformTheme(platformTheme)
{
}

bool ThemePainter::paint(const LayoutObject& o, const PaintInfo& paintInfo, const IntRect&r)
{
    ControlPart part = o.styleRef().appearance();

    if (LayoutTheme::theme().shouldUseFallbackTheme(o.styleRef()))
        return paintUsingFallbackTheme(o, paintInfo, r);

    if (m_platformTheme) {
        switch (part) {
        case CheckboxPart:
        case RadioPart:
        case PushButtonPart:
        case SquareButtonPart:
        case ButtonPart:
        case InnerSpinButtonPart:
            m_platformTheme->paint(part, LayoutTheme::controlStatesForLayoutObject(o), const_cast<GraphicsContext&>(paintInfo.context), r, o.styleRef().effectiveZoom(), o.view()->frameView());
            return false;
        default:
            break;
        }
    }

    // Call the appropriate paint method based off the appearance value.
    switch (part) {
    case CheckboxPart:
        return paintCheckbox(o, paintInfo, r);
    case RadioPart:
        return paintRadio(o, paintInfo, r);
    case PushButtonPart:
    case SquareButtonPart:
    case ButtonPart:
        return paintButton(o, paintInfo, r);
    case InnerSpinButtonPart:
        return paintInnerSpinButton(o, paintInfo, r);
    case MenulistPart:
        return paintMenuList(o, paintInfo, r);
    case MeterPart:
        return true;
    case ProgressBarPart:
        return paintProgressBar(o, paintInfo, r);
    case SliderHorizontalPart:
    case SliderVerticalPart:
        return paintSliderTrack(o, paintInfo, r);
    case SliderThumbHorizontalPart:
    case SliderThumbVerticalPart:
        return paintSliderThumb(o, paintInfo, r);
    case MediaEnterFullscreenButtonPart:
    case MediaExitFullscreenButtonPart:
        return MediaControlsPainter::paintMediaFullscreenButton(o, paintInfo, r);
    case MediaPlayButtonPart:
        return MediaControlsPainter::paintMediaPlayButton(o, paintInfo, r);
    case MediaOverlayPlayButtonPart:
        return MediaControlsPainter::paintMediaOverlayPlayButton(o, paintInfo, r);
    case MediaMuteButtonPart:
        return MediaControlsPainter::paintMediaMuteButton(o, paintInfo, r);
    case MediaToggleClosedCaptionsButtonPart:
        return MediaControlsPainter::paintMediaToggleClosedCaptionsButton(o, paintInfo, r);
    case MediaSliderPart:
        return MediaControlsPainter::paintMediaSlider(o, paintInfo, r);
    case MediaSliderThumbPart:
        return MediaControlsPainter::paintMediaSliderThumb(o, paintInfo, r);
    case MediaVolumeSliderContainerPart:
        return true;
    case MediaVolumeSliderPart:
        return MediaControlsPainter::paintMediaVolumeSlider(o, paintInfo, r);
    case MediaVolumeSliderThumbPart:
        return MediaControlsPainter::paintMediaVolumeSliderThumb(o, paintInfo, r);
    case MediaFullScreenVolumeSliderPart:
    case MediaFullScreenVolumeSliderThumbPart:
    case MediaTimeRemainingPart:
    case MediaCurrentTimePart:
    case MediaControlsBackgroundPart:
        return true;
    case MediaCastOffButtonPart:
    case MediaOverlayCastOffButtonPart:
        return MediaControlsPainter::paintMediaCastButton(o, paintInfo, r);
    case MediaTrackSelectionCheckmarkPart:
        return MediaControlsPainter::paintMediaTrackSelectionCheckmark(o, paintInfo, r);
    case MediaClosedCaptionsIconPart:
        return MediaControlsPainter::paintMediaClosedCaptionsIcon(o, paintInfo, r);
    case MediaSubtitlesIconPart:
        return MediaControlsPainter::paintMediaSubtitlesIcon(o, paintInfo, r);
    case MenulistButtonPart:
    case TextFieldPart:
    case TextAreaPart:
        return true;
    case SearchFieldPart:
        return paintSearchField(o, paintInfo, r);
    case SearchFieldCancelButtonPart:
        return paintSearchFieldCancelButton(o, paintInfo, r);
    default:
        break;
    }

    return true; // We don't support the appearance, so let the normal background/border paint.
}

bool ThemePainter::paintBorderOnly(const LayoutObject& o, const PaintInfo& paintInfo, const IntRect&r)
{
    // Call the appropriate paint method based off the appearance value.
    switch (o.styleRef().appearance()) {
    case TextFieldPart:
        return paintTextField(o, paintInfo, r);
    case TextAreaPart:
        return paintTextArea(o, paintInfo, r);
    case MenulistButtonPart:
    case SearchFieldPart:
    case ListboxPart:
        return true;
    case CheckboxPart:
    case RadioPart:
    case PushButtonPart:
    case SquareButtonPart:
    case ButtonPart:
    case MenulistPart:
    case MeterPart:
    case ProgressBarPart:
    case SliderHorizontalPart:
    case SliderVerticalPart:
    case SliderThumbHorizontalPart:
    case SliderThumbVerticalPart:
    case SearchFieldCancelButtonPart:
    default:
        break;
    }

    return false;
}

bool ThemePainter::paintDecorations(const LayoutObject& o, const PaintInfo& paintInfo, const IntRect&r)
{
    // Call the appropriate paint method based off the appearance value.
    switch (o.styleRef().appearance()) {
    case MenulistButtonPart:
        return paintMenuListButton(o, paintInfo, r);
    case TextFieldPart:
    case TextAreaPart:
    case CheckboxPart:
    case RadioPart:
    case PushButtonPart:
    case SquareButtonPart:
    case ButtonPart:
    case MenulistPart:
    case MeterPart:
    case ProgressBarPart:
    case SliderHorizontalPart:
    case SliderVerticalPart:
    case SliderThumbHorizontalPart:
    case SliderThumbVerticalPart:
    case SearchFieldPart:
    case SearchFieldCancelButtonPart:
    default:
        break;
    }

    return false;
}

void ThemePainter::paintSliderTicks(const LayoutObject& o, const PaintInfo& paintInfo, const IntRect&rect)
{
    Node* node = o.node();
    if (!isHTMLInputElement(node))
        return;

    HTMLInputElement* input = toHTMLInputElement(node);
    if (input->type() != InputTypeNames::range || !input->userAgentShadowRoot()->hasChildren())
        return;

    HTMLDataListElement* dataList = input->dataList();
    if (!dataList)
        return;

    double min = input->minimum();
    double max = input->maximum();
    ControlPart part = o.styleRef().appearance();
    // We don't support ticks on alternate sliders like MediaVolumeSliders.
    if (part !=  SliderHorizontalPart && part != SliderVerticalPart)
        return;
    bool isHorizontal = part ==  SliderHorizontalPart;

    IntSize thumbSize;
    LayoutObject* thumbLayoutObject = input->userAgentShadowRoot()->getElementById(ShadowElementNames::sliderThumb())->layoutObject();
    if (thumbLayoutObject) {
        const ComputedStyle& thumbStyle = thumbLayoutObject->styleRef();
        int thumbWidth = thumbStyle.width().intValue();
        int thumbHeight = thumbStyle.height().intValue();
        thumbSize.setWidth(isHorizontal ? thumbWidth : thumbHeight);
        thumbSize.setHeight(isHorizontal ? thumbHeight : thumbWidth);
    }

    IntSize tickSize = LayoutTheme::theme().sliderTickSize();
    float zoomFactor = o.styleRef().effectiveZoom();
    FloatRect tickRect;
    int tickRegionSideMargin = 0;
    int tickRegionWidth = 0;
    IntRect trackBounds;
    LayoutObject* trackLayoutObject = input->userAgentShadowRoot()->getElementById(ShadowElementNames::sliderTrack())->layoutObject();
    // We can ignoring transforms because transform is handled by the graphics context.
    if (trackLayoutObject)
        trackBounds = trackLayoutObject->absoluteBoundingBoxRectIgnoringTransforms();
    IntRect sliderBounds = o.absoluteBoundingBoxRectIgnoringTransforms();

    // Make position relative to the transformed ancestor element.
    trackBounds.setX(trackBounds.x() - sliderBounds.x() + rect.x());
    trackBounds.setY(trackBounds.y() - sliderBounds.y() + rect.y());

    if (isHorizontal) {
        tickRect.setWidth(floor(tickSize.width() * zoomFactor));
        tickRect.setHeight(floor(tickSize.height() * zoomFactor));
        tickRect.setY(floor(rect.y() + rect.height() / 2.0 + LayoutTheme::theme().sliderTickOffsetFromTrackCenter() * zoomFactor));
        tickRegionSideMargin = trackBounds.x() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0;
        tickRegionWidth = trackBounds.width() - thumbSize.width();
    } else {
        tickRect.setWidth(floor(tickSize.height() * zoomFactor));
        tickRect.setHeight(floor(tickSize.width() * zoomFactor));
        tickRect.setX(floor(rect.x() + rect.width() / 2.0 + LayoutTheme::theme().sliderTickOffsetFromTrackCenter() * zoomFactor));
        tickRegionSideMargin = trackBounds.y() + (thumbSize.width() - tickSize.width() * zoomFactor) / 2.0;
        tickRegionWidth = trackBounds.height() - thumbSize.width();
    }
    HTMLDataListOptionsCollection* options = dataList->options();
    for (unsigned i = 0; HTMLOptionElement* optionElement = options->item(i); i++) {
        String value = optionElement->value();
        if (!input->isValidValue(value))
            continue;
        double parsedValue = parseToDoubleForNumberType(input->sanitizeValue(value));
        double tickFraction = (parsedValue - min) / (max - min);
        double tickRatio = isHorizontal && o.styleRef().isLeftToRightDirection() ? tickFraction : 1.0 - tickFraction;
        double tickPosition = round(tickRegionSideMargin + tickRegionWidth * tickRatio);
        if (isHorizontal)
            tickRect.setX(tickPosition);
        else
            tickRect.setY(tickPosition);
        paintInfo.context.fillRect(tickRect, o.resolveColor(CSSPropertyColor));
    }
}

bool ThemePainter::paintUsingFallbackTheme(const LayoutObject& o, const PaintInfo& i, const IntRect&r)
{
    ControlPart part = o.styleRef().appearance();
    switch (part) {
    case CheckboxPart:
        return paintCheckboxUsingFallbackTheme(o, i, r);
    case RadioPart:
        return paintRadioUsingFallbackTheme(o, i, r);
    default:
        break;
    }
    return true;
}

bool ThemePainter::paintCheckboxUsingFallbackTheme(const LayoutObject& o, const PaintInfo& i, const IntRect&r)
{
    WebFallbackThemeEngine::ExtraParams extraParams;
    WebCanvas* canvas = i.context.canvas();
    extraParams.button.checked = LayoutTheme::isChecked(o);
    extraParams.button.indeterminate = LayoutTheme::isIndeterminate(o);

    float zoomLevel = o.styleRef().effectiveZoom();
    GraphicsContextStateSaver stateSaver(i.context);
    IntRect unzoomedRect = r;
    if (zoomLevel != 1) {
        unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
        unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
        i.context.translate(unzoomedRect.x(), unzoomedRect.y());
        i.context.scale(zoomLevel, zoomLevel);
        i.context.translate(-unzoomedRect.x(), -unzoomedRect.y());
    }

    Platform::current()->fallbackThemeEngine()->paint(canvas, WebFallbackThemeEngine::PartCheckbox, getWebFallbackThemeState(o), WebRect(unzoomedRect), &extraParams);
    return false;
}

bool ThemePainter::paintRadioUsingFallbackTheme(const LayoutObject& o, const PaintInfo& i, const IntRect&r)
{
    WebFallbackThemeEngine::ExtraParams extraParams;
    WebCanvas* canvas = i.context.canvas();
    extraParams.button.checked = LayoutTheme::isChecked(o);
    extraParams.button.indeterminate = LayoutTheme::isIndeterminate(o);

    float zoomLevel = o.styleRef().effectiveZoom();
    GraphicsContextStateSaver stateSaver(i.context);
    IntRect unzoomedRect = r;
    if (zoomLevel != 1) {
        unzoomedRect.setWidth(unzoomedRect.width() / zoomLevel);
        unzoomedRect.setHeight(unzoomedRect.height() / zoomLevel);
        i.context.translate(unzoomedRect.x(), unzoomedRect.y());
        i.context.scale(zoomLevel, zoomLevel);
        i.context.translate(-unzoomedRect.x(), -unzoomedRect.y());
    }

    Platform::current()->fallbackThemeEngine()->paint(canvas, WebFallbackThemeEngine::PartRadio, getWebFallbackThemeState(o), WebRect(unzoomedRect), &extraParams);
    return false;
}

} // namespace blink
