/*
 * Copyright 2005-2007 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code 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 General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.java.swing.plaf.gtk;

import java.awt.*;
import java.awt.image.*;
import java.util.HashMap;
import javax.swing.*;
import javax.swing.plaf.synth.*;

import com.sun.java.swing.plaf.gtk.GTKConstants.ArrowType;
import com.sun.java.swing.plaf.gtk.GTKConstants.ExpanderStyle;
import com.sun.java.swing.plaf.gtk.GTKConstants.Orientation;
import com.sun.java.swing.plaf.gtk.GTKConstants.PositionType;
import com.sun.java.swing.plaf.gtk.GTKConstants.ShadowType;
import com.sun.java.swing.plaf.gtk.GTKConstants.TextDirection;

import sun.awt.image.SunWritableRaster;
import sun.swing.ImageCache;

/**
 * GTKEngine delegates all painting job to native GTK libraries.
 *
 * Painting with GTKEngine looks like this:
 * First, startPainting() is called. It prepares an offscreen buffer of the
 *   required size.
 * Then, any number of paintXXX() methods can be called. They effectively ignore
 *   the Graphics parameter and draw to the offscreen buffer.
 * Finally, finishPainting() should be called. It fills the data buffer passed
 *   in with the image data.
 *
 * @author Josh Outwater
 */
class GTKEngine {

    final static GTKEngine INSTANCE = new GTKEngine();

    /** Size of the image cache */
    private static final int CACHE_SIZE = 50;

    /** This enum mirrors that in gtk2_interface.h */
    static enum WidgetType {
        BUTTON, CHECK_BOX, CHECK_BOX_MENU_ITEM, COLOR_CHOOSER,
        COMBO_BOX, COMBO_BOX_ARROW_BUTTON, COMBO_BOX_TEXT_FIELD,
        DESKTOP_ICON, DESKTOP_PANE, EDITOR_PANE, FORMATTED_TEXT_FIELD,
        HANDLE_BOX, HPROGRESS_BAR,
        HSCROLL_BAR, HSCROLL_BAR_BUTTON_LEFT, HSCROLL_BAR_BUTTON_RIGHT,
        HSCROLL_BAR_TRACK, HSCROLL_BAR_THUMB,
        HSEPARATOR, HSLIDER, HSLIDER_TRACK, HSLIDER_THUMB, HSPLIT_PANE_DIVIDER,
        INTERNAL_FRAME, INTERNAL_FRAME_TITLE_PANE, IMAGE, LABEL, LIST, MENU,
        MENU_BAR, MENU_ITEM, MENU_ITEM_ACCELERATOR, OPTION_PANE, PANEL,
        PASSWORD_FIELD, POPUP_MENU, POPUP_MENU_SEPARATOR,
        RADIO_BUTTON, RADIO_BUTTON_MENU_ITEM, ROOT_PANE, SCROLL_PANE,
        SPINNER, SPINNER_ARROW_BUTTON, SPINNER_TEXT_FIELD,
        SPLIT_PANE, TABBED_PANE, TABBED_PANE_TAB_AREA, TABBED_PANE_CONTENT,
        TABBED_PANE_TAB, TABLE, TABLE_HEADER, TEXT_AREA, TEXT_FIELD, TEXT_PANE,
        TITLED_BORDER,
        TOGGLE_BUTTON, TOOL_BAR, TOOL_BAR_DRAG_WINDOW, TOOL_BAR_SEPARATOR,
        TOOL_TIP, TREE, TREE_CELL, VIEWPORT, VPROGRESS_BAR,
        VSCROLL_BAR, VSCROLL_BAR_BUTTON_UP, VSCROLL_BAR_BUTTON_DOWN,
        VSCROLL_BAR_TRACK, VSCROLL_BAR_THUMB,
        VSEPARATOR, VSLIDER, VSLIDER_TRACK, VSLIDER_THUMB,
        VSPLIT_PANE_DIVIDER
    }

    /**
     * Representation of GtkSettings properties.
     * When we need more settings we can add them here and
     * to all implementations of getGTKSetting().
     */
    static enum Settings {
        GTK_FONT_NAME,
        GTK_ICON_SIZES
    }

    /* Custom regions are needed for representing regions that don't exist
     * in the original Region class.
     */
    static class CustomRegion extends Region {
        /*
         * TITLED_BORDER Region is mapped to GtkFrame class which can draw
         * titled borders around components.
         */
        static Region TITLED_BORDER = new CustomRegion("TitledBorder");

        private CustomRegion(String name) {
            super(name, null, false);
        }
    }


    private static HashMap regionToWidgetTypeMap;
    private ImageCache cache = new ImageCache(CACHE_SIZE);
    private int x0, y0, w0, h0;
    private Graphics graphics;
    private Object[] cacheArgs;

    private native void native_paint_arrow(
            int widgetType, int state, int shadowType, String detail,
            int x, int y, int width, int height, int arrowType);
    private native void native_paint_box(
            int widgetType, int state, int shadowType, String detail,
            int x, int y, int width, int height, int synthState, int dir);
    private native void native_paint_box_gap(
            int widgetType, int state, int shadowType, String detail,
            int x, int y, int width, int height,
            int gapSide, int gapX, int gapWidth);
    private native void native_paint_check(
            int widgetType, int synthState, String detail,
            int x, int y, int width, int height);
    private native void native_paint_expander(
            int widgetType, int state, String detail,
            int x, int y, int width, int height, int expanderStyle);
    private native void native_paint_extension(
            int widgetType, int state, int shadowType, String detail,
            int x, int y, int width, int height, int placement);
    private native void native_paint_flat_box(
            int widgetType, int state, int shadowType, String detail,
            int x, int y, int width, int height, boolean hasFocus);
    private native void native_paint_focus(
            int widgetType, int state, String detail,
            int x, int y, int width, int height);
    private native void native_paint_handle(
            int widgetType, int state, int shadowType, String detail,
            int x, int y, int width, int height, int orientation);
    private native void native_paint_hline(
            int widgetType, int state, String detail,
            int x, int y, int width, int height);
    private native void native_paint_option(
            int widgetType, int synthState, String detail,
            int x, int y, int width, int height);
    private native void native_paint_shadow(
            int widgetType, int state, int shadowType, String detail,
            int x, int y, int width, int height, int synthState, int dir);
    private native void native_paint_slider(
            int widgetType, int state, int shadowType, String detail,
            int x, int y, int width, int height, int orientation);
    private native void native_paint_vline(
            int widgetType, int state, String detail,
            int x, int y, int width, int height);
    private native void native_paint_background(
            int widgetType, int state, int x, int y, int width, int height);
    private native Object native_get_gtk_setting(int property);
    private native void nativeSetRangeValue(int widgetType, double value,
                                            double min, double max,
                                            double visible);

    private native void nativeStartPainting(int w, int h);
    private native int nativeFinishPainting(int[] buffer, int width, int height);
    private native void native_switch_theme();

    static {
        // Make sure the awt toolkit is loaded so we have access to native
        // methods.
        Toolkit.getDefaultToolkit();

        // Initialize regionToWidgetTypeMap
        regionToWidgetTypeMap = new HashMap(50);
        regionToWidgetTypeMap.put(Region.ARROW_BUTTON, new WidgetType[] {
            WidgetType.SPINNER_ARROW_BUTTON,
            WidgetType.COMBO_BOX_ARROW_BUTTON,
            WidgetType.HSCROLL_BAR_BUTTON_LEFT,
            WidgetType.HSCROLL_BAR_BUTTON_RIGHT,
            WidgetType.VSCROLL_BAR_BUTTON_UP,
            WidgetType.VSCROLL_BAR_BUTTON_DOWN});
        regionToWidgetTypeMap.put(Region.BUTTON, WidgetType.BUTTON);
        regionToWidgetTypeMap.put(Region.CHECK_BOX, WidgetType.CHECK_BOX);
        regionToWidgetTypeMap.put(Region.CHECK_BOX_MENU_ITEM,
                                  WidgetType.CHECK_BOX_MENU_ITEM);
        regionToWidgetTypeMap.put(Region.COLOR_CHOOSER, WidgetType.COLOR_CHOOSER);
        regionToWidgetTypeMap.put(Region.FILE_CHOOSER, WidgetType.OPTION_PANE);
        regionToWidgetTypeMap.put(Region.COMBO_BOX, WidgetType.COMBO_BOX);
        regionToWidgetTypeMap.put(Region.DESKTOP_ICON, WidgetType.DESKTOP_ICON);
        regionToWidgetTypeMap.put(Region.DESKTOP_PANE, WidgetType.DESKTOP_PANE);
        regionToWidgetTypeMap.put(Region.EDITOR_PANE, WidgetType.EDITOR_PANE);
        regionToWidgetTypeMap.put(Region.FORMATTED_TEXT_FIELD, new WidgetType[] {
            WidgetType.FORMATTED_TEXT_FIELD, WidgetType.SPINNER_TEXT_FIELD});
        regionToWidgetTypeMap.put(GTKRegion.HANDLE_BOX, WidgetType.HANDLE_BOX);
        regionToWidgetTypeMap.put(Region.INTERNAL_FRAME,
                                  WidgetType.INTERNAL_FRAME);
        regionToWidgetTypeMap.put(Region.INTERNAL_FRAME_TITLE_PANE,
                                  WidgetType.INTERNAL_FRAME_TITLE_PANE);
        regionToWidgetTypeMap.put(Region.LABEL, new WidgetType[] {
            WidgetType.LABEL, WidgetType.COMBO_BOX_TEXT_FIELD});
        regionToWidgetTypeMap.put(Region.LIST, WidgetType.LIST);
        regionToWidgetTypeMap.put(Region.MENU, WidgetType.MENU);
        regionToWidgetTypeMap.put(Region.MENU_BAR, WidgetType.MENU_BAR);
        regionToWidgetTypeMap.put(Region.MENU_ITEM, WidgetType.MENU_ITEM);
        regionToWidgetTypeMap.put(Region.MENU_ITEM_ACCELERATOR,
                                  WidgetType.MENU_ITEM_ACCELERATOR);
        regionToWidgetTypeMap.put(Region.OPTION_PANE, WidgetType.OPTION_PANE);
        regionToWidgetTypeMap.put(Region.PANEL, WidgetType.PANEL);
        regionToWidgetTypeMap.put(Region.PASSWORD_FIELD,
                                  WidgetType.PASSWORD_FIELD);
        regionToWidgetTypeMap.put(Region.POPUP_MENU, WidgetType.POPUP_MENU);
        regionToWidgetTypeMap.put(Region.POPUP_MENU_SEPARATOR,
                                  WidgetType.POPUP_MENU_SEPARATOR);
        regionToWidgetTypeMap.put(Region.PROGRESS_BAR, new WidgetType[] {
            WidgetType.HPROGRESS_BAR, WidgetType.VPROGRESS_BAR});
        regionToWidgetTypeMap.put(Region.RADIO_BUTTON, WidgetType.RADIO_BUTTON);
        regionToWidgetTypeMap.put(Region.RADIO_BUTTON_MENU_ITEM,
                                  WidgetType.RADIO_BUTTON_MENU_ITEM);
        regionToWidgetTypeMap.put(Region.ROOT_PANE, WidgetType.ROOT_PANE);
        regionToWidgetTypeMap.put(Region.SCROLL_BAR, new WidgetType[] {
            WidgetType.HSCROLL_BAR, WidgetType.VSCROLL_BAR});
        regionToWidgetTypeMap.put(Region.SCROLL_BAR_THUMB, new WidgetType[] {
            WidgetType.HSCROLL_BAR_THUMB, WidgetType.VSCROLL_BAR_THUMB});
        regionToWidgetTypeMap.put(Region.SCROLL_BAR_TRACK, new WidgetType[] {
            WidgetType.HSCROLL_BAR_TRACK, WidgetType.VSCROLL_BAR_TRACK});
        regionToWidgetTypeMap.put(Region.SCROLL_PANE, WidgetType.SCROLL_PANE);
        regionToWidgetTypeMap.put(Region.SEPARATOR, new WidgetType[] {
            WidgetType.HSEPARATOR, WidgetType.VSEPARATOR});
        regionToWidgetTypeMap.put(Region.SLIDER, new WidgetType[] {
            WidgetType.HSLIDER, WidgetType.VSLIDER});
        regionToWidgetTypeMap.put(Region.SLIDER_THUMB, new WidgetType[] {
            WidgetType.HSLIDER_THUMB, WidgetType.VSLIDER_THUMB});
        regionToWidgetTypeMap.put(Region.SLIDER_TRACK, new WidgetType[] {
            WidgetType.HSLIDER_TRACK, WidgetType.VSLIDER_TRACK});
        regionToWidgetTypeMap.put(Region.SPINNER, WidgetType.SPINNER);
        regionToWidgetTypeMap.put(Region.SPLIT_PANE, WidgetType.SPLIT_PANE);
        regionToWidgetTypeMap.put(Region.SPLIT_PANE_DIVIDER, new WidgetType[] {
            WidgetType.HSPLIT_PANE_DIVIDER, WidgetType.VSPLIT_PANE_DIVIDER});
        regionToWidgetTypeMap.put(Region.TABBED_PANE, WidgetType.TABBED_PANE);
        regionToWidgetTypeMap.put(Region.TABBED_PANE_CONTENT,
                                  WidgetType.TABBED_PANE_CONTENT);
        regionToWidgetTypeMap.put(Region.TABBED_PANE_TAB,
                                  WidgetType.TABBED_PANE_TAB);
        regionToWidgetTypeMap.put(Region.TABBED_PANE_TAB_AREA,
                                  WidgetType.TABBED_PANE_TAB_AREA);
        regionToWidgetTypeMap.put(Region.TABLE, WidgetType.TABLE);
        regionToWidgetTypeMap.put(Region.TABLE_HEADER, WidgetType.TABLE_HEADER);
        regionToWidgetTypeMap.put(Region.TEXT_AREA, WidgetType.TEXT_AREA);
        regionToWidgetTypeMap.put(Region.TEXT_FIELD, new WidgetType[] {
            WidgetType.TEXT_FIELD, WidgetType.COMBO_BOX_TEXT_FIELD});
        regionToWidgetTypeMap.put(Region.TEXT_PANE, WidgetType.TEXT_PANE);
        regionToWidgetTypeMap.put(CustomRegion.TITLED_BORDER, WidgetType.TITLED_BORDER);
        regionToWidgetTypeMap.put(Region.TOGGLE_BUTTON, WidgetType.TOGGLE_BUTTON);
        regionToWidgetTypeMap.put(Region.TOOL_BAR, WidgetType.TOOL_BAR);
        regionToWidgetTypeMap.put(Region.TOOL_BAR_CONTENT, WidgetType.TOOL_BAR);
        regionToWidgetTypeMap.put(Region.TOOL_BAR_DRAG_WINDOW,
                                  WidgetType.TOOL_BAR_DRAG_WINDOW);
        regionToWidgetTypeMap.put(Region.TOOL_BAR_SEPARATOR,
                                  WidgetType.TOOL_BAR_SEPARATOR);
        regionToWidgetTypeMap.put(Region.TOOL_TIP, WidgetType.TOOL_TIP);
        regionToWidgetTypeMap.put(Region.TREE, WidgetType.TREE);
        regionToWidgetTypeMap.put(Region.TREE_CELL, WidgetType.TREE_CELL);
        regionToWidgetTypeMap.put(Region.VIEWPORT, WidgetType.VIEWPORT);
    }

    /** Translate Region and JComponent into WidgetType ordinals */
    static WidgetType getWidgetType(JComponent c, Region id) {
        Object value = regionToWidgetTypeMap.get(id);

        if (value instanceof WidgetType) {
            return (WidgetType)value;
        }

        WidgetType[] widgets = (WidgetType[])value;
        if (c == null ) {
            return widgets[0];
        }

        if (c instanceof JScrollBar) {
            return (((JScrollBar)c).getOrientation() == JScrollBar.HORIZONTAL) ?
                widgets[0] : widgets[1];
        } else if (c instanceof JSeparator) {
            JSeparator separator = (JSeparator)c;

            /* We should return correrct WidgetType if the seperator is inserted
             * in Menu/PopupMenu/ToolBar. BugID: 6465603
             */
            if (separator.getParent() instanceof JPopupMenu) {
                return WidgetType.POPUP_MENU_SEPARATOR;
            } else if (separator.getParent() instanceof JToolBar) {
                return WidgetType.TOOL_BAR_SEPARATOR;
            }

            return (separator.getOrientation() == JSeparator.HORIZONTAL) ?
                widgets[0] : widgets[1];
        } else if (c instanceof JSlider) {
            return (((JSlider)c).getOrientation() == JSlider.HORIZONTAL) ?
                widgets[0] : widgets[1];
        } else if (c instanceof JProgressBar) {
            return (((JProgressBar)c).getOrientation() == JProgressBar.HORIZONTAL) ?
                widgets[0] : widgets[1];
        } else if (c instanceof JSplitPane) {
            return (((JSplitPane)c).getOrientation() == JSplitPane.HORIZONTAL_SPLIT) ?
                widgets[1] : widgets[0];
        } else if (id == Region.LABEL) {
            /*
             * For all ListCellRenderers we will use COMBO_BOX_TEXT_FIELD widget
             * type because we can get correct insets. List items however won't be
             * drawn as a text entry (see GTKPainter.paintLabelBackground).
             */
            if (c instanceof ListCellRenderer) {
                return widgets[1];
            } else {
                return widgets[0];
            }
        } else if (id == Region.TEXT_FIELD) {
            String name = c.getName();
            if (name != null && name.startsWith("ComboBox")) {
                return widgets[1];
            } else {
                return widgets[0];
            }
        } else if (id == Region.FORMATTED_TEXT_FIELD) {
            String name = c.getName();
            if (name != null && name.startsWith("Spinner")) {
                return widgets[1];
            } else {
                return widgets[0];
            }
        } else if (id == Region.ARROW_BUTTON) {
            if (c.getParent() instanceof JScrollBar) {
                Integer prop = (Integer)
                    c.getClientProperty("__arrow_direction__");
                int dir = (prop != null) ?
                    prop.intValue() : SwingConstants.WEST;
                switch (dir) {
                case SwingConstants.WEST:
                    return WidgetType.HSCROLL_BAR_BUTTON_LEFT;
                case SwingConstants.EAST:
                    return WidgetType.HSCROLL_BAR_BUTTON_RIGHT;
                case SwingConstants.NORTH:
                    return WidgetType.VSCROLL_BAR_BUTTON_UP;
                case SwingConstants.SOUTH:
                    return WidgetType.VSCROLL_BAR_BUTTON_DOWN;
                default:
                    return null;
                }
            } else if (c.getParent() instanceof JComboBox) {
                return WidgetType.COMBO_BOX_ARROW_BUTTON;
            } else {
                return WidgetType.SPINNER_ARROW_BUTTON;
            }
        }

        return null;
    }

    private static int getTextDirection(SynthContext context) {
        TextDirection dir = TextDirection.NONE;
        JComponent comp = context.getComponent();
        if (comp != null) {
            ComponentOrientation co = comp.getComponentOrientation();
            if (co != null) {
                dir = co.isLeftToRight() ?
                    TextDirection.LTR : TextDirection.RTL;
            }
        }
        return dir.ordinal();
    }

    public void paintArrow(Graphics g, SynthContext context,
            Region id, int state, ShadowType shadowType, ArrowType direction,
            String detail, int x, int y, int w, int h) {

        state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        native_paint_arrow(widget, state, shadowType.ordinal(),
                detail, x - x0, y - y0, w, h, direction.ordinal());
    }

    public void paintBox(Graphics g, SynthContext context,
            Region id, int state, ShadowType shadowType,
            String detail, int x, int y, int w, int h) {

        int gtkState =
            GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
        int synthState = context.getComponentState();
        int dir = getTextDirection(context);
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        native_paint_box(widget, gtkState, shadowType.ordinal(),
                         detail, x - x0, y - y0, w, h, synthState, dir);
    }

    public void paintBoxGap(Graphics g, SynthContext context,
            Region id, int state, ShadowType shadowType,
            String detail, int x, int y, int w, int h,
            PositionType boxGapType, int tabBegin, int size) {

        state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        native_paint_box_gap(widget, state, shadowType.ordinal(), detail,
                x - x0, y - y0, w, h, boxGapType.ordinal(), tabBegin, size);
    }

    public void paintCheck(Graphics g, SynthContext context,
            Region id, String detail, int x, int y, int w, int h) {

        int synthState = context.getComponentState();
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        native_paint_check(widget, synthState, detail, x - x0, y - y0, w, h);
    }

    public void paintExpander(Graphics g, SynthContext context,
            Region id, int state, ExpanderStyle expanderStyle, String detail,
            int x, int y, int w, int h) {

        state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        native_paint_expander(widget, state, detail, x - x0, y - y0, w, h,
                              expanderStyle.ordinal());
    }

    public void paintExtension(Graphics g, SynthContext context,
            Region id, int state, ShadowType shadowType, String detail,
            int x, int y, int w, int h, PositionType placement, int tabIndex) {

        state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        native_paint_extension(widget, state, shadowType.ordinal(), detail,
                               x - x0, y - y0, w, h, placement.ordinal());
    }

    public void paintFlatBox(Graphics g, SynthContext context,
            Region id, int state, ShadowType shadowType, String detail,
            int x, int y, int w, int h, ColorType colorType) {

        state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        native_paint_flat_box(widget, state, shadowType.ordinal(), detail,
                              x - x0, y - y0, w, h,
                              context.getComponent().hasFocus());
    }

    public void paintFocus(Graphics g, SynthContext context,
            Region id, int state, String detail, int x, int y, int w, int h) {

        state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        native_paint_focus(widget, state, detail, x - x0, y - y0, w, h);
    }

    public void paintHandle(Graphics g, SynthContext context,
            Region id, int state, ShadowType shadowType, String detail,
            int x, int y, int w, int h, Orientation orientation) {

        state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        native_paint_handle(widget, state, shadowType.ordinal(), detail,
                            x - x0, y - y0, w, h, orientation.ordinal());
    }

    public void paintHline(Graphics g, SynthContext context,
            Region id, int state, String detail, int x, int y, int w, int h) {

        state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        native_paint_hline(widget, state, detail, x - x0, y - y0, w, h);
    }

    public void paintOption(Graphics g, SynthContext context,
            Region id, String detail, int x, int y, int w, int h) {

        int synthState = context.getComponentState();
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        native_paint_option(widget, synthState, detail, x - x0, y - y0, w, h);
    }

    public void paintShadow(Graphics g, SynthContext context,
            Region id, int state, ShadowType shadowType, String detail,
            int x, int y, int w, int h) {

        int gtkState =
            GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
        int synthState = context.getComponentState();
        int dir = getTextDirection(context);
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        native_paint_shadow(widget, gtkState, shadowType.ordinal(), detail,
                            x - x0, y - y0, w, h, synthState, dir);
    }

    public void paintSlider(Graphics g, SynthContext context,
            Region id, int state, ShadowType shadowType, String detail,
            int x, int y, int w, int h, Orientation orientation) {

        state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        native_paint_slider(widget, state, shadowType.ordinal(), detail,
                            x - x0, y - y0, w, h, orientation.ordinal());
    }

    public void paintVline(Graphics g, SynthContext context,
            Region id, int state, String detail, int x, int y, int w, int h) {

        state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        native_paint_vline(widget, state, detail, x - x0, y - y0, w, h);
    }

    public void paintBackground(Graphics g, SynthContext context,
            Region id, int state, Color color, int x, int y, int w, int h) {

        state = GTKLookAndFeel.synthStateToGTKStateType(state).ordinal();
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        native_paint_background(widget, state, x - x0, y - y0, w, h);
    }

    private final static ColorModel[] COLOR_MODELS = {
        // Transparency.OPAQUE
        new DirectColorModel(24, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000),
        // Transparency.BITMASK
        new DirectColorModel(25, 0x00ff0000, 0x0000ff00, 0x000000ff, 0x01000000),
        // Transparency.TRANSLUCENT
        ColorModel.getRGBdefault(),
    };

    private final static int[][] BAND_OFFSETS = {
        { 0x00ff0000, 0x0000ff00, 0x000000ff },             // OPAQUE
        { 0x00ff0000, 0x0000ff00, 0x000000ff, 0x01000000 }, // BITMASK
        { 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }  // TRANSLUCENT
    };


    /**
     * Paint a cached image identified by its size and a set of additional
     * arguments, if there's one.
     *
     * @return true if a cached image has been painted, false otherwise
     */
    public boolean paintCachedImage(Graphics g,
            int x, int y, int w, int h, Object... args) {
        if (w <= 0 || h <= 0) {
            return true;
        }

        // look for cached image
        Image img = cache.getImage(getClass(), null, w, h, args);
        if (img != null) {
            g.drawImage(img, x, y, null);
            return true;
        }
        return false;
    }

    /*
     * Allocate a native offscreen buffer of the specified size.
     */
    public void startPainting(Graphics g,
            int x, int y, int w, int h, Object... args) {
        nativeStartPainting(w, h);
        x0 = x;
        y0 = y;
        w0 = w;
        h0 = h;
        graphics = g;
        cacheArgs = args;
    }

    /**
     * Convenience method that delegates to finishPainting() with
     * caching enabled.
     */
    public void finishPainting() {
        finishPainting(true);
    }

    /**
     * Called to indicate that painting is finished. We create a new
     * BufferedImage from the offscreen buffer, (optionally) cache it,
     * and paint it.
     */
    public void finishPainting(boolean useCache) {
        DataBufferInt dataBuffer = new DataBufferInt(w0 * h0);
        // Note that stealData() requires a markDirty() afterwards
        // since we modify the data in it.
        int transparency =
            nativeFinishPainting(SunWritableRaster.stealData(dataBuffer, 0),
                                 w0, h0);
        SunWritableRaster.markDirty(dataBuffer);

        int[] bands = BAND_OFFSETS[transparency - 1];
        WritableRaster raster = Raster.createPackedRaster(
                dataBuffer, w0, h0, w0, bands, null);

        ColorModel cm = COLOR_MODELS[transparency - 1];
        Image img = new BufferedImage(cm, raster, false, null);
        if (useCache) {
            cache.setImage(getClass(), null, w0, h0, cacheArgs, img);
        }
        graphics.drawImage(img, x0, y0, null);
    }

    /**
     * Notify native layer of theme change, and flush cache
     */
    public void themeChanged() {
        synchronized(sun.awt.UNIXToolkit.GTK_LOCK) {
            native_switch_theme();
        }
        cache.flush();
    }

    /* GtkSettings enum mirrors that in gtk2_interface.h */
    public Object getSetting(Settings property) {
        synchronized(sun.awt.UNIXToolkit.GTK_LOCK) {
            return native_get_gtk_setting(property.ordinal());
        }
    }

    /**
     * Sets up the GtkAdjustment values for the native GtkRange widget
     * associated with the given region (e.g. SLIDER, SCROLL_BAR).
     */
    void setRangeValue(SynthContext context, Region id,
                       double value, double min, double max, double visible) {
        int widget = getWidgetType(context.getComponent(), id).ordinal();
        nativeSetRangeValue(widget, value, min, max, visible);
    }
}
