/*
 * Copyright (C) 2007 Kevin Ollivier <kevino@theolliviers.com>
 *
 * 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 COMPUTER, 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 COMPUTER, 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 "RenderTheme.h"

#include "Document.h"
#include "FrameView.h"
#include "GraphicsContext.h"
#include "HostWindow.h"
#include "LocalDC.h"
#include "NotImplemented.h"
#include "PaintInfo.h"
#include "RenderView.h"

#include <wx/defs.h>

#include <wx/dc.h>
#include <wx/dcgraph.h>
#include <wx/renderer.h>
#include <wx/dcclient.h>
#include <wx/scrolwin.h>
#include <wx/settings.h>

namespace WebCore {

class RenderThemeWx : public RenderTheme {
private:
    RenderThemeWx() : RenderTheme() { }
    virtual ~RenderThemeWx();

public:
    static PassRefPtr<RenderTheme> create();

    // A method asking if the theme's controls actually care about redrawing when hovered.
    virtual bool supportsHover(const RenderStyle*) const { return true; }

    virtual bool paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& r)
    {
        return paintButton(o, i, r);
    }
 
    virtual void setCheckboxSize(RenderStyle*) const;

    virtual bool paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& r)
    {
        return paintButton(o, i, r);
    }

    virtual void setRadioSize(RenderStyle*) const;

    virtual void adjustRepaintRect(const RenderObject*, IntRect&);

    virtual void adjustButtonStyle(StyleResolver*, RenderStyle*, Element*) const;
    virtual bool paintButton(RenderObject*, const PaintInfo&, const IntRect&);

    virtual void adjustTextFieldStyle(StyleResolver*, RenderStyle*, Element*) const;
    virtual bool paintTextField(RenderObject*, const PaintInfo&, const IntRect&);

    virtual int minimumMenuListSize(RenderStyle*) const;

    virtual void adjustMenuListStyle(StyleResolver*, RenderStyle*, Element*) const;
    virtual bool paintMenuList(RenderObject*, const PaintInfo&, const IntRect&);

    virtual void adjustMenuListButtonStyle(StyleResolver*, RenderStyle*, Element*) const;
    virtual bool paintMenuListButton(RenderObject*, const PaintInfo&, const IntRect&);

    virtual bool isControlStyled(const RenderStyle*, const BorderData&,
                                 const FillLayer&, const Color&) const;

    virtual bool controlSupportsTints(const RenderObject*) const;

    virtual void systemFont(int propId, FontDescription&) const;

    virtual Color platformActiveSelectionBackgroundColor() const;
    virtual Color platformInactiveSelectionBackgroundColor() const;
    
    virtual Color platformActiveSelectionForegroundColor() const;
    virtual Color platformInactiveSelectionForegroundColor() const;
    
    virtual int popupInternalPaddingLeft(RenderStyle*) const;
    virtual int popupInternalPaddingRight(RenderStyle*) const;
    virtual int popupInternalPaddingTop(RenderStyle*) const;
    virtual int popupInternalPaddingBottom(RenderStyle*) const;

private:
    void addIntrinsicMargins(RenderStyle*) const;
    void close();

    bool supportsFocus(ControlPart) const;
};


// Constants

#define MINIMUM_MENU_LIST_SIZE 21
#define POPUP_INTERNAL_PADDING_LEFT 6
#define POPUP_INTERNAL_PADDING_TOP 2
#define POPUP_INTERNAL_PADDING_BOTTOM 2

#ifdef __WXMAC__
#define POPUP_INTERNAL_PADDING_RIGHT 22
#else
#define POPUP_INTERNAL_PADDING_RIGHT 20
#endif

RenderThemeWx::~RenderThemeWx()
{
}

PassRefPtr<RenderTheme> RenderThemeWx::create()
{
    return adoptRef(new RenderThemeWx());
}

PassRefPtr<RenderTheme> RenderTheme::themeForPage(Page* page)
{
    static RenderTheme* rt = RenderThemeWx::create().leakRef();
    return rt;
}

wxWindow* nativeWindowForRenderObject(RenderObject* o)
{
    FrameView* frameView = o->view()->frameView();
    ASSERT(frameView);
    ASSERT(frameView->hostWindow());
    return frameView->hostWindow()->platformPageClient();
}


bool RenderThemeWx::isControlStyled(const RenderStyle* style, const BorderData& border,
                                     const FillLayer& background, const Color& backgroundColor) const
{
    if (style->appearance() == TextFieldPart || style->appearance() == TextAreaPart)
        return style->border() != border;

    // Normally CSS can be used to set properties of form controls (such as adding a background bitmap).
    // However, for this to work RenderThemeWx needs to adjust uncustomized elements (e.g. buttons) to reflect the
    // changes made by CSS. Since we don't do that right now, the native parts of form elements appear in odd places. 
    // Until we have time to implement that support, we return false here, so that we ignore customizations 
    // and always use the native theme drawing to draw form controls.
    return false;
}

void RenderThemeWx::adjustRepaintRect(const RenderObject* o, IntRect& r)
{
    switch (o->style()->appearance()) {
        case MenulistPart: {
            r.setWidth(r.width() + 100);
            break;
        }
        default:
            break;
    }
}

bool RenderThemeWx::controlSupportsTints(const RenderObject* o) const
{
    if (!isEnabled(o))
        return false;

    // Checkboxes only have tint when checked.
    if (o->style()->appearance() == CheckboxPart)
        return isChecked(o);

    // For now assume other controls have tint if enabled.
    return true;
}

void RenderThemeWx::systemFont(int propId, FontDescription& fontDescription) const
{
    // no-op
}

void RenderThemeWx::addIntrinsicMargins(RenderStyle* style) const
{
    // Cut out the intrinsic margins completely if we end up using a small font size
    if (style->fontSize() < 11)
        return;

    // Intrinsic margin value.
    const int m = 2;

    // FIXME: Using width/height alone and not also dealing with min-width/max-width is flawed.
    if (style->width().isIntrinsicOrAuto()) {
        if (style->marginLeft().quirk())
            style->setMarginLeft(Length(m, Fixed));

        if (style->marginRight().quirk())
            style->setMarginRight(Length(m, Fixed));
    }

    if (style->height().isAuto()) {
        if (style->marginTop().quirk())
            style->setMarginTop(Length(m, Fixed));

        if (style->marginBottom().quirk())
            style->setMarginBottom(Length(m, Fixed));
    }
}

void RenderThemeWx::setCheckboxSize(RenderStyle* style) const
{
    // If the width and height are both specified, then we have nothing to do.
    if (!style->width().isIntrinsicOrAuto() && !style->height().isAuto())
        return;

    // FIXME:  A hard-coded size of 13 is used.  This is wrong but necessary for now.  It matches Firefox.
    // At different DPI settings on Windows, querying the theme gives you a larger size that accounts for
    // the higher DPI.  Until our entire engine honors a DPI setting other than 96, we can't rely on the theme's
    // metrics.
    if (style->width().isIntrinsicOrAuto())
        style->setWidth(Length(13, Fixed));

    if (style->height().isAuto())
        style->setHeight(Length(13, Fixed));
}

void RenderThemeWx::setRadioSize(RenderStyle* style) const
{
    // This is the same as checkboxes.
    setCheckboxSize(style);
}

bool RenderThemeWx::supportsFocus(ControlPart part) const
{
    switch (part) {
        case PushButtonPart:
        case ButtonPart:
        case TextFieldPart:
        case MenulistPart:
            return true;
        default: // No for all others...
            return false;
    }
}

void RenderThemeWx::adjustButtonStyle(StyleResolver*, RenderStyle* style, Element*) const
{
    addIntrinsicMargins(style);
}

bool RenderThemeWx::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
    wxWindow* window = nativeWindowForRenderObject(o);
    wxDC* dc = static_cast<wxDC*>(i.context->platformContext());
    LocalDC localDC(dc, r, /*transparent =*/ true);

    int flags = 0;
    
    IntRect rect = r;

    if (!isEnabled(o))
        flags |= wxCONTROL_DISABLED;

    ControlPart part = o->style()->appearance();
    if (supportsFocus(part) && isFocused(o))
        flags |= wxCONTROL_FOCUSED;

    if (isPressed(o))
        flags |= wxCONTROL_PRESSED;
    
    if (part == PushButtonPart || part == ButtonPart)
        wxRendererNative::Get().DrawPushButton(window, *localDC.context(), rect, flags);
    else if(part == RadioPart) {
        if (isChecked(o))
            flags |= wxCONTROL_CHECKED;
#if wxCHECK_VERSION(2,9,1)
        wxRendererNative::Get().DrawRadioBitmap(window, *localDC.context(), rect, flags);
#elif wxCHECK_VERSION(2,9,0)
        wxRendererNative::Get().DrawRadioButton(window, *localDC.context(), rect, flags);
#else
        wxRenderer_DrawRadioButton(window, *localDC.context(), rect, flags);
#endif
    }
    else if(part == CheckboxPart) {
        if (isChecked(o))
            flags |= wxCONTROL_CHECKED;
        wxRendererNative::Get().DrawCheckBox(window, *localDC.context(), rect, flags);
    }
    return false;
}

void RenderThemeWx::adjustTextFieldStyle(StyleResolver*, RenderStyle* style, Element*) const
{

}

bool RenderThemeWx::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
    wxWindow* window = nativeWindowForRenderObject(o);
    wxDC* dc = static_cast<wxDC*>(i.context->platformContext());
    LocalDC localDC(dc, r);
    int flags = 0;
    
    IntRect rect = r;

    ControlPart part = o->style()->appearance();
    if (supportsFocus(part) && isFocused(o))
        flags |= wxCONTROL_FOCUSED;

#if wxCHECK_VERSION(2,9,0)
    wxRendererNative::Get().DrawTextCtrl(window, *localDC.context(), rect, flags);
#else
    wxRenderer_DrawTextCtrl(window, *localDC.context(), r, 0);
#endif

    return false;
}

int RenderThemeWx::minimumMenuListSize(RenderStyle*) const 
{ 
    return MINIMUM_MENU_LIST_SIZE; 
}

void RenderThemeWx::adjustMenuListStyle(StyleResolver*, RenderStyle* style, Element*) const
{
     style->resetBorder();

    // Height is locked to auto.
    style->setHeight(Length(Auto));
    
    style->setPaddingTop(Length(2, Fixed));
    style->setPaddingBottom(Length(2, Fixed));
}
    
bool RenderThemeWx::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
    wxWindow* window = nativeWindowForRenderObject(o);
    wxDC* dc = static_cast<wxDC*>(i.context->platformContext());

    LocalDC localDC(dc, r);
    IntRect rect = r;

    int flags = 0;      
    if (!isEnabled(o))
        flags |= wxCONTROL_DISABLED;
        
    if (supportsFocus(o->style()->appearance()) && isFocused(o))
        flags |= wxCONTROL_FOCUSED;

    if (isPressed(o))
        flags |= wxCONTROL_PRESSED;

#if wxCHECK_VERSION(2,9,0)
    wxRendererNative::Get().DrawChoice(window, *localDC.context(), rect, flags);
#else
    wxRenderer_DrawChoice(window, *localDC.context(), rect, flags);
#endif

    return false;
}

void RenderThemeWx::adjustMenuListButtonStyle(StyleResolver*, RenderStyle*, Element*) const
{
    notImplemented();
}
    
bool RenderThemeWx::paintMenuListButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
    wxWindow* window = nativeWindowForRenderObject(o);
    wxDC* dc = static_cast<wxDC*>(i.context->platformContext());
    LocalDC localDC(dc, r);
    IntRect rect = r;

    int flags = 0;      
    if (!isEnabled(o))
        flags |= wxCONTROL_DISABLED;
        
    if (supportsFocus(o->style()->appearance()) && isFocused(o))
        flags |= wxCONTROL_FOCUSED;
    
    if (isPressed(o))
        flags |= wxCONTROL_PRESSED;

    wxRendererNative::Get().DrawComboBoxDropButton(window, *localDC.context(), rect, flags);
            
    return false;
}

    
Color RenderThemeWx::platformActiveSelectionBackgroundColor() const
{
    return wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
}

Color RenderThemeWx::platformInactiveSelectionBackgroundColor() const
{
    return wxSystemSettings::GetColour(wxSYS_COLOUR_BTNSHADOW);
}

Color RenderThemeWx::platformActiveSelectionForegroundColor() const
{
    // FIXME: Get wx to return the correct value for each platform.
#if __WXMAC__
    return Color();
#else
    return Color(255, 255, 255);
#endif
}

Color RenderThemeWx::platformInactiveSelectionForegroundColor() const
{
#if __WXMAC__
    return Color();
#else
    return Color(255, 255, 255);
#endif
}

int RenderThemeWx::popupInternalPaddingLeft(RenderStyle*) const 
{ 
    return POPUP_INTERNAL_PADDING_LEFT; 
}

int RenderThemeWx::popupInternalPaddingRight(RenderStyle*) const 
{
    return POPUP_INTERNAL_PADDING_RIGHT;
}

int RenderThemeWx::popupInternalPaddingTop(RenderStyle*) const 
{
    return POPUP_INTERNAL_PADDING_TOP;
}

int RenderThemeWx::popupInternalPaddingBottom(RenderStyle*) const
{ 
    return POPUP_INTERNAL_PADDING_BOTTOM; 
}

}

