/*
 * Copyright 2002-2004 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.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.colorchooser.*;
import javax.swing.event.*;
import javax.swing.plaf.*;

/**
 * A color chooser panel mimicking that of GTK's: a color wheel showing
 * hue and a triangle that varies saturation and brightness.
 *
 * @author Scott Violet
 */
class GTKColorChooserPanel extends AbstractColorChooserPanel implements
              ChangeListener {
    private static final float PI_3 = (float)(Math.PI / 3);

    private ColorTriangle triangle;
    private JLabel lastLabel;
    private JLabel label;

    private JSpinner hueSpinner;
    private JSpinner saturationSpinner;
    private JSpinner valueSpinner;

    private JSpinner redSpinner;
    private JSpinner greenSpinner;
    private JSpinner blueSpinner;

    private JTextField colorNameTF;

    private boolean settingColor;

    // The colors are mirrored to avoid creep in adjusting an individual
    // value.
    private float hue;
    private float saturation;
    private float brightness;



    /**
     * Convenience method to transfer focus to the next child of component.
     */
    // PENDING: remove this when a variant of this is added to awt.
    static void compositeRequestFocus(Component component, boolean direction) {
        if (component instanceof Container) {
            Container container = (Container)component;
            if (container.isFocusCycleRoot()) {
                FocusTraversalPolicy policy = container.
                                              getFocusTraversalPolicy();
                Component comp = policy.getDefaultComponent(container);
                if (comp!=null) {
                    comp.requestFocus();
                    return;
                }
            }
            Container rootAncestor = container.getFocusCycleRootAncestor();
            if (rootAncestor!=null) {
                FocusTraversalPolicy policy = rootAncestor.
                                                  getFocusTraversalPolicy();
                Component comp;

                if (direction) {
                    comp = policy.getComponentAfter(rootAncestor, container);
                }
                else {
                    comp = policy.getComponentBefore(rootAncestor, container);
                }
                if (comp != null) {
                    comp.requestFocus();
                    return;
                }
            }
        }
        component.requestFocus();
    }


    /**
     * Returns a user presentable description of this GTKColorChooserPane.
     */
    public String getDisplayName() {
        return (String)UIManager.get("GTKColorChooserPanel.nameText");
    }

    /**
     * Returns the mnemonic to use with <code>getDisplayName</code>.
     */
    public int getMnemonic() {
        String m = (String)UIManager.get("GTKColorChooserPanel.mnemonic");

        if (m != null) {
            try {
                int value = Integer.parseInt(m);

                return value;
            } catch (NumberFormatException nfe) {}
        }
        return -1;
    }

    /**
     * Character to underline that represents the mnemonic.
     */
    public int getDisplayedMnemonicIndex() {
        String m = (String)UIManager.get(
                           "GTKColorChooserPanel.displayedMnemonicIndex");

        if (m != null) {
            try {
                int value = Integer.parseInt(m);

                return value;
            } catch (NumberFormatException nfe) {}
        }
        return -1;
    }

    public Icon getSmallDisplayIcon() {
        return null;
    }

    public Icon getLargeDisplayIcon() {
        return null;
    }

    public void uninstallChooserPanel(JColorChooser enclosingChooser) {
        super.uninstallChooserPanel(enclosingChooser);
        removeAll();
    }

    /**
     * Builds and configures the widgets for the GTKColorChooserPanel.
     */
    protected void buildChooser() {
        triangle = new ColorTriangle();
        triangle.setName("GTKColorChooserPanel.triangle");

        // PENDING: when we straighten out user setting opacity, this should
        // be changed.
        label = new OpaqueLabel();
        label.setName("GTKColorChooserPanel.colorWell");
        label.setOpaque(true);
        label.setMinimumSize(new Dimension(67, 32));
        label.setPreferredSize(new Dimension(67, 32));
        label.setMaximumSize(new Dimension(67, 32));

        // PENDING: when we straighten out user setting opacity, this should
        // be changed.
        lastLabel = new OpaqueLabel();
        lastLabel.setName("GTKColorChooserPanel.lastColorWell");
        lastLabel.setOpaque(true);
        lastLabel.setMinimumSize(new Dimension(67, 32));
        lastLabel.setPreferredSize(new Dimension(67, 32));
        lastLabel.setMaximumSize(new Dimension(67, 32));

        hueSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 360, 1));
        configureSpinner(hueSpinner, "GTKColorChooserPanel.hueSpinner");
        saturationSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 255, 1));
        configureSpinner(saturationSpinner,
                         "GTKColorChooserPanel.saturationSpinner");
        valueSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 255, 1));
        configureSpinner(valueSpinner, "GTKColorChooserPanel.valueSpinner");
        redSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 255, 1));
        configureSpinner(redSpinner, "GTKColorChooserPanel.redSpinner");
        greenSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 255, 1));
        configureSpinner(greenSpinner, "GTKColorChooserPanel.greenSpinner");
        blueSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 255, 1));
        configureSpinner(blueSpinner, "GTKColorChooserPanel.blueSpinner");

        colorNameTF = new JTextField(8);

        setLayout(new GridBagLayout());

        add(this, "GTKColorChooserPanel.hue", hueSpinner, -1, -1);
        add(this, "GTKColorChooserPanel.red", redSpinner, -1, -1);
        add(this, "GTKColorChooserPanel.saturation", saturationSpinner, -1,-1);
        add(this, "GTKColorChooserPanel.green", greenSpinner, -1, -1);
        add(this, "GTKColorChooserPanel.value", valueSpinner, -1, -1);
        add(this, "GTKColorChooserPanel.blue", blueSpinner, -1, -1);

        add(new JSeparator(SwingConstants.HORIZONTAL), new
                  GridBagConstraints(1, 3, 4, 1, 1, 0,
                  GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL,
                  new Insets(14, 0, 0, 0), 0, 0));

        add(this, "GTKColorChooserPanel.colorName", colorNameTF, 0, 4);

        add(triangle, new GridBagConstraints(0, 0, 1, 5, 0, 0,
                      GridBagConstraints.LINE_START, GridBagConstraints.NONE,
                      new Insets(14, 20, 2, 9), 0, 0));

        Box hBox = Box.createHorizontalBox();
        hBox.add(lastLabel);
        hBox.add(label);
        add(hBox, new GridBagConstraints(0, 5, 1, 1, 0, 0,
                      GridBagConstraints.CENTER, GridBagConstraints.NONE,
                      new Insets(0, 0, 0, 0), 0, 0));

        add(new JSeparator(SwingConstants.HORIZONTAL), new
                  GridBagConstraints(0, 6, 5, 1, 1, 0,
                  GridBagConstraints.LINE_START, GridBagConstraints.HORIZONTAL,
                  new Insets(12, 0, 0, 0), 0, 0));
    }

    /**
     * Configures the spinner.
     */
    private void configureSpinner(JSpinner spinner, String name) {
        spinner.addChangeListener(this);
        spinner.setName(name);
        JComponent editor = spinner.getEditor();
        if (editor instanceof JSpinner.DefaultEditor) {
            JFormattedTextField ftf = ((JSpinner.DefaultEditor)editor).
                                                 getTextField();

            ftf.setFocusLostBehavior(JFormattedTextField.COMMIT_OR_REVERT);
        }
    }

    /**
     * Adds the widget creating a JLabel with the specified name.
     */
    private void add(Container parent, String key, JComponent widget,
                     int x, int y) {
        JLabel label = new JLabel(UIManager.getString(key + "Text",
                                                      getLocale()));
        String mnemonic = (String)UIManager.get(key + "Mnemonic", getLocale());

        if (mnemonic != null) {
            try {
                label.setDisplayedMnemonic(Integer.parseInt(mnemonic));
            } catch (NumberFormatException nfe) {
            }
            String mnemonicIndex = (String)UIManager.get(key + "MnemonicIndex",
                                                    getLocale());

            if (mnemonicIndex != null) {
                try {
                    label.setDisplayedMnemonicIndex(Integer.parseInt(
                                                        mnemonicIndex));
                } catch (NumberFormatException nfe) {
                }
            }
        }
        label.setLabelFor(widget);
        if (x < 0) {
            x = parent.getComponentCount() % 4;
        }
        if (y < 0) {
            y = parent.getComponentCount() / 4;
        }
        GridBagConstraints con = new GridBagConstraints(x + 1, y, 1, 1, 0, 0,
                   GridBagConstraints.FIRST_LINE_END, GridBagConstraints.NONE,
                   new Insets(4, 0, 0, 4), 0, 0);
        if (y == 0) {
            con.insets.top = 14;
        }
        parent.add(label, con);
        con.gridx++;
        parent.add(widget, con);
    }

    /**
     * Refreshes the display from the model.
     */
    public void updateChooser() {
        if (!settingColor) {
            lastLabel.setBackground(getColorFromModel());
            setColor(getColorFromModel(), true, true, false);
        }
    }

    /**
     * Resets the red component of the selected color.
     */
    private void setRed(int red) {
        setRGB(red << 16 | getColor().getGreen() << 8 | getColor().getBlue());
    }

    /**
     * Resets the green component of the selected color.
     */
    private void setGreen(int green) {
        setRGB(getColor().getRed() << 16 | green << 8 | getColor().getBlue());
    }

    /**
     * Resets the blue component of the selected color.
     */
    private void setBlue(int blue) {
        setRGB(getColor().getRed() << 16 | getColor().getGreen() << 8 | blue);
    }

    /**
     * Sets the hue of the selected color and updates the display if
     * necessary.
     */
    private void setHue(float hue, boolean update) {
        setHSB(hue, saturation, brightness);
        if (update) {
            settingColor = true;
            hueSpinner.setValue(new Integer((int)(hue * 360)));
            settingColor = false;
        }
    }

    /**
     * Returns the current amount of hue.
     */
    private float getHue() {
        return hue;
    }

    /**
     * Resets the saturation.
     */
    private void setSaturation(float saturation) {
        setHSB(hue, saturation, brightness);
    }

    /**
     * Returns the saturation.
     */
    private float getSaturation() {
        return saturation;
    }

    /**
     * Sets the brightness.
     */
    private void setBrightness(float brightness) {
        setHSB(hue, saturation, brightness);
    }

    /**
     * Returns the brightness.
     */
    private float getBrightness() {
        return brightness;
    }

    /**
     * Sets the saturation and brightness and updates the display if
     * necessary.
     */
    private void setSaturationAndBrightness(float s, float b, boolean update) {
        setHSB(hue, s, b);
        if (update) {
            settingColor = true;
            saturationSpinner.setValue(new Integer((int)(s * 255)));
            valueSpinner.setValue(new Integer((int)(b * 255)));
            settingColor = false;
        }
    }

    /**
     * Resets the rgb values.
     */
    private void setRGB(int rgb) {
        Color color = new Color(rgb);

        setColor(color, false, true, true);

        settingColor = true;
        hueSpinner.setValue(new Integer((int)(hue * 360)));
        saturationSpinner.setValue(new Integer((int)(saturation * 255)));
        valueSpinner.setValue(new Integer((int)(brightness * 255)));
        settingColor = false;
    }

    /**
     * Resets the hsb values.
     */
    private void setHSB(float h, float s, float b) {
        Color color = Color.getHSBColor(h, s, b);

        this.hue = h;
        this.saturation = s;
        this.brightness = b;
        setColor(color, false, false, true);

        settingColor = true;
        redSpinner.setValue(new Integer(color.getRed()));
        greenSpinner.setValue(new Integer(color.getGreen()));
        blueSpinner.setValue(new Integer(color.getBlue()));
        settingColor = false;
    }


    /**
     * Rests the color.
     *
     * @param color new Color
     * @param updateSpinners whether or not to update the spinners.
     * @param updateHSB if true, the hsb fields are updated based on the
     *                  new color
     * @param updateModel if true, the model is set.
     */
    private void setColor(Color color, boolean updateSpinners,
                          boolean updateHSB, boolean updateModel) {
        if (color == null) {
            color = Color.BLACK;
        }

        settingColor = true;

        if (updateHSB) {
            float[] hsb = Color.RGBtoHSB(color.getRed(), color.getGreen(),
                                         color.getBlue(), null);
            hue = hsb[0];
            saturation = hsb[1];
            brightness = hsb[2];
        }

        if (updateModel) {
            getColorSelectionModel().setSelectedColor(color);
        }

        triangle.setColor(hue, saturation, brightness);
        label.setBackground(color);
        // Force Integer to pad the string with 0's by adding 0x1000000 and
        // then removing the first character.
        String hexString = Integer.toHexString(
                  (color.getRGB() & 0xFFFFFF) | 0x1000000);
        colorNameTF.setText("#" + hexString.substring(1));

        if (updateSpinners) {
            redSpinner.setValue(new Integer(color.getRed()));
            greenSpinner.setValue(new Integer(color.getGreen()));
            blueSpinner.setValue(new Integer(color.getBlue()));

            hueSpinner.setValue(new Integer((int)(hue * 360)));
            saturationSpinner.setValue(new Integer((int)(saturation * 255)));
            valueSpinner.setValue(new Integer((int)(brightness * 255)));
        }
        settingColor = false;
    }

    public Color getColor() {
        return label.getBackground();
    }

    /**
     * ChangeListener method, updates the necessary display widgets.
     */
    public void stateChanged(ChangeEvent e) {
        if (settingColor) {
            return;
        }
        Color color = getColor();

        if (e.getSource() == hueSpinner) {
            setHue(((Number)hueSpinner.getValue()).floatValue() / 360, false);
        }
        else if (e.getSource() == saturationSpinner) {
            setSaturation(((Number)saturationSpinner.getValue()).
                          floatValue() / 255);
        }
        else if (e.getSource() == valueSpinner) {
            setBrightness(((Number)valueSpinner.getValue()).
                          floatValue() / 255);
        }
        else if (e.getSource() == redSpinner) {
            setRed(((Number)redSpinner.getValue()).intValue());
        }
        else if (e.getSource() == greenSpinner) {
            setGreen(((Number)greenSpinner.getValue()).intValue());
        }
        else if (e.getSource() == blueSpinner) {
            setBlue(((Number)blueSpinner.getValue()).intValue());
        }
    }



    /**
     * Flag indicating the angle, or hue, has changed and the triangle
     * needs to be recreated.
     */
    private static final int FLAGS_CHANGED_ANGLE = 1 << 0;
    /**
     * Indicates the wheel is being dragged.
     */
    private static final int FLAGS_DRAGGING = 1 << 1;
    /**
     * Indicates the triangle is being dragged.
     */
    private static final int FLAGS_DRAGGING_TRIANGLE = 1 << 2;
    /**
     * Indicates a color is being set and we should ignore setColor
     */
    private static final int FLAGS_SETTING_COLOR = 1 << 3;
    /**
     * Indicates the wheel has focus.
     */
    private static final int FLAGS_FOCUSED_WHEEL = 1 << 4;
    /**
     * Indicates the triangle has focus.
     */
    private static final int FLAGS_FOCUSED_TRIANGLE = 1 << 5;


    /**
     * Class responsible for rendering a color wheel and color triangle.
     */
    private class ColorTriangle extends JPanel {
        /**
         * Cached image of the wheel.
         */
        private Image wheelImage;

        /**
         * Cached image of the triangle.
         */
        private Image triangleImage;

        /**
         * Angle triangle is rotated by.
         */
        private double angle;

        /**
         * Boolean bitmask.
         */
        private int flags;

        /**
         * X location of selected color indicator.
         */
        private int circleX;
        /**
         * Y location of selected color indicator.
         */
        private int circleY;


        public ColorTriangle() {
            enableEvents(AWTEvent.FOCUS_EVENT_MASK);
            enableEvents(AWTEvent.MOUSE_EVENT_MASK);
            enableEvents(AWTEvent.MOUSE_MOTION_EVENT_MASK);

            setMinimumSize(new Dimension(getWheelRadius() * 2 + 2,
                                         getWheelRadius() * 2 + 2));
            setPreferredSize(new Dimension(getWheelRadius() * 2 + 2,
                                           getWheelRadius() * 2 + 2));

            // We want to handle tab ourself.
            setFocusTraversalKeysEnabled(false);

            // PENDING: this should come from the style.
            getInputMap().put(KeyStroke.getKeyStroke("UP"), "up");
            getInputMap().put(KeyStroke.getKeyStroke("DOWN"), "down");
            getInputMap().put(KeyStroke.getKeyStroke("LEFT"), "left");
            getInputMap().put(KeyStroke.getKeyStroke("RIGHT"), "right");

            getInputMap().put(KeyStroke.getKeyStroke("KP_UP"), "up");
            getInputMap().put(KeyStroke.getKeyStroke("KP_DOWN"), "down");
            getInputMap().put(KeyStroke.getKeyStroke("KP_LEFT"), "left");
            getInputMap().put(KeyStroke.getKeyStroke("KP_RIGHT"), "right");

            getInputMap().put(KeyStroke.getKeyStroke("TAB"), "focusNext");
            getInputMap().put(KeyStroke.getKeyStroke("shift TAB"),"focusLast");

            ActionMap map = (ActionMap)UIManager.get(
                                       "GTKColorChooserPanel.actionMap");

            if (map == null) {
                map = new ActionMapUIResource();
                map.put("left", new ColorAction("left", 2));
                map.put("right", new ColorAction("right", 3));
                map.put("up", new ColorAction("up", 0));
                map.put("down", new ColorAction("down", 1));
                map.put("focusNext", new ColorAction("focusNext", 4));
                map.put("focusLast", new ColorAction("focusLast", 5));
                UIManager.getLookAndFeelDefaults().put(
                             "GTKColorChooserPanel.actionMap", map);
            }
            SwingUtilities.replaceUIActionMap(this, map);
        }

        /**
         * Returns the GTKColorChooserPanel.
         */
        GTKColorChooserPanel getGTKColorChooserPanel() {
            return GTKColorChooserPanel.this;
        }

        /**
         * Gives focus to the wheel.
         */
        void focusWheel() {
            setFocusType(1);
        }

        /**
         * Gives focus to the triangle.
         */
        void focusTriangle() {
            setFocusType(2);
        }

        /**
         * Returns true if the wheel currently has focus.
         */
        boolean isWheelFocused() {
            return isSet(FLAGS_FOCUSED_WHEEL);
        }

        /**
         * Resets the selected color.
         */
        public void setColor(float h, float s, float b) {
            if (isSet(FLAGS_SETTING_COLOR)) {
                return;
            }

            setAngleFromHue(h);
            setSaturationAndBrightness(s, b);
        }

        /**
         * Returns the selected color.
         */
        public Color getColor() {
            return GTKColorChooserPanel.this.getColor();
        }

        /**
         * Returns the x location of the selected color indicator.
         */
        int getColorX() {
            return circleX + getIndicatorSize() / 2 - getWheelXOrigin();
        }

        /**
         * Returns the y location of the selected color indicator.
         */
        int getColorY() {
            return circleY + getIndicatorSize() / 2 - getWheelYOrigin();
        }

        protected void processEvent(AWTEvent e) {
            if (e.getID() == MouseEvent.MOUSE_PRESSED ||
                   ((isSet(FLAGS_DRAGGING) ||isSet(FLAGS_DRAGGING_TRIANGLE)) &&
                   e.getID() == MouseEvent.MOUSE_DRAGGED)) {
                // Assign focus to either the wheel or triangle and attempt
                // to drag either the wheel or triangle.
                int size = getWheelRadius();
                int x = ((MouseEvent)e).getX() - size;
                int y = ((MouseEvent)e).getY() - size;

                if (!hasFocus()) {
                    requestFocus();
                }
                if (!isSet(FLAGS_DRAGGING_TRIANGLE) &&
                      adjustHue(x, y, e.getID() == MouseEvent.MOUSE_PRESSED)) {
                    setFlag(FLAGS_DRAGGING, true);
                    setFocusType(1);
                }
                else if (adjustSB(x, y, e.getID() ==
                                        MouseEvent.MOUSE_PRESSED)) {
                    setFlag(FLAGS_DRAGGING_TRIANGLE, true);
                    setFocusType(2);
                }
                else {
                    setFocusType(2);
                }
            }
            else if (e.getID() == MouseEvent.MOUSE_RELEASED) {
                // Stopped dragging
                setFlag(FLAGS_DRAGGING_TRIANGLE, false);
                setFlag(FLAGS_DRAGGING, false);
            }
            else if (e.getID() == FocusEvent.FOCUS_LOST) {
                // Reset the flags to indicate no one has focus
                setFocusType(0);
            }
            else if (e.getID() == FocusEvent.FOCUS_GAINED) {
                // Gained focus, reassign focus to the wheel if no one
                // currently has focus.
                if (!isSet(FLAGS_FOCUSED_TRIANGLE) &&
                          !isSet(FLAGS_FOCUSED_WHEEL)) {
                    setFlag(FLAGS_FOCUSED_WHEEL, true);
                    setFocusType(1);
                }
                repaint();
            }
            super.processEvent(e);
        }

        public void paintComponent(Graphics g) {
            super.paintComponent(g);

            // Draw the wheel and triangle
            int size = getWheelRadius();
            int width = getWheelWidth();
            Image image = getImage(size);
            g.drawImage(image, getWheelXOrigin() - size,
                        getWheelYOrigin() - size, null);

            // Draw the focus indicator for the wheel
            if (hasFocus() && isSet(FLAGS_FOCUSED_WHEEL)) {
                g.setColor(Color.BLACK);
                g.drawOval(getWheelXOrigin() - size, getWheelYOrigin() - size,
                           2 * size, 2 * size);
                g.drawOval(getWheelXOrigin() - size + width, getWheelYOrigin()-
                           size + width, 2 * (size - width), 2 *
                           (size - width));
            }

            // Draw a line on the wheel indicating the selected hue.
            if (Math.toDegrees(Math.PI * 2 - angle) <= 20 ||
                     Math.toDegrees(Math.PI * 2 - angle) >= 201) {
                g.setColor(Color.WHITE);
            }
            else {
                g.setColor(Color.BLACK);
            }
            int lineX0 = (int)(Math.cos(angle) * size);
            int lineY0 = (int)(Math.sin(angle) * size);
            int lineX1 = (int)(Math.cos(angle) * (size - width));
            int lineY1 = (int)(Math.sin(angle) * (size - width));
            g.drawLine(lineX0 + size, lineY0 + size, lineX1 + size,
                       lineY1 + size);

            // Draw the focus indicator on the triangle
            if (hasFocus() && isSet(FLAGS_FOCUSED_TRIANGLE)) {
                Graphics g2 = g.create();
                int innerR = getTriangleCircumscribedRadius();
                int a = (int)(3 * innerR / Math.sqrt(3));
                g2.translate(getWheelXOrigin(), getWheelYOrigin());
                ((Graphics2D)g2).rotate(angle + Math.PI / 2);
                g2.setColor(Color.BLACK);
                g2.drawLine(0, -innerR, a / 2, innerR / 2);
                g2.drawLine(a / 2, innerR / 2, -a / 2, innerR / 2);
                g2.drawLine(-a / 2, innerR / 2, 0, -innerR);
                g2.dispose();
            }

            // Draw the selected color indicator.
            g.setColor(Color.BLACK);
            g.drawOval(circleX, circleY, getIndicatorSize() - 1,
                       getIndicatorSize() - 1);
            g.setColor(Color.WHITE);
            g.drawOval(circleX + 1, circleY + 1, getIndicatorSize() - 3,
                       getIndicatorSize() - 3);
        }

        /**
         * Returns an image representing the triangle and wheel.
         */
        private Image getImage(int size) {
            if (!isSet(FLAGS_CHANGED_ANGLE) && wheelImage != null &&
                        wheelImage.getWidth(null) == size * 2) {
                return wheelImage;
            }
            if (wheelImage == null || wheelImage.getWidth(null) != size) {
                wheelImage = getWheelImage(size);
            }
            int innerR = getTriangleCircumscribedRadius();
            int triangleSize = (int)(innerR * 3.0 / 2.0);
            int a = (int)(2 * triangleSize / Math.sqrt(3));
            if (triangleImage == null || triangleImage.getWidth(null) != a) {
                triangleImage = new BufferedImage(a, a,
                                                  BufferedImage.TYPE_INT_ARGB);
            }
            Graphics g = triangleImage.getGraphics();
            g.setColor(new Color(0, 0, 0, 0));
            g.fillRect(0, 0, a, a);
            g.translate((int)(a / 2), 0);
            paintTriangle(g, triangleSize, getColor());
            g.translate((int)(-a / 2), 0);
            g.dispose();

            g = wheelImage.getGraphics();
            g.setColor(new Color(0, 0, 0, 0));
            g.fillOval(getWheelWidth(), getWheelWidth(),
                       2 * (size - getWheelWidth()),
                       2 * (size - getWheelWidth()));

            double rotate = Math.toRadians(-30.0) + angle;
            g.translate(size, size);
            ((Graphics2D)g).rotate(rotate);
            g.drawImage(triangleImage, -a / 2,
                        getWheelWidth() - size, null);
            ((Graphics2D)g).rotate(-rotate);
            g.translate(a / 2, size - getWheelWidth());

            setFlag(FLAGS_CHANGED_ANGLE, false);

            return wheelImage;
        }

        private void paintTriangle(Graphics g, int size, Color color) {
            float[] colors = Color.RGBtoHSB(color.getRed(),
                                            color.getGreen(),
                                            color.getBlue(), null);
            float hue = colors[0];
            double dSize = (double)size;
            for (int y = 0; y < size; y++) {
                int maxX = (int)(y * Math.tan(Math.toRadians(30.0)));
                float factor = maxX * 2;
                if (maxX > 0) {
                    float value = (float)(y / dSize);
                    for (int x = -maxX; x <= maxX; x++) {
                        float saturation = (float)x / factor + .5f;
                        g.setColor(Color.getHSBColor(hue, saturation, value));
                        g.fillRect(x, y, 1, 1);
                    }
                }
                else {
                    g.setColor(color);
                    g.fillRect(0, y, 1, 1);
                }
            }
        }

        /**
         * Returns a color wheel image for the specified size.
         *
         * @param size Integer giving size of color wheel.
         * @return Color wheel image
         */
        private Image getWheelImage(int size) {
            int minSize = size - getWheelWidth();
            int doubleSize = size * 2;
            BufferedImage image = new BufferedImage(doubleSize, doubleSize,
                                              BufferedImage.TYPE_INT_ARGB);

            for (int y = -size; y < size; y++) {
                int ySquared = y * y;
                for (int x = -size; x < size; x++) {
                    double rad = Math.sqrt(ySquared + x * x);

                    if (rad < size && rad > minSize) {
                        int rgb = colorWheelLocationToRGB(x, y, rad) |
                              0xFF000000;
                        image.setRGB(x + size, y + size, rgb);
                    }
                }
            }
            wheelImage = image;
            return wheelImage;
        }

        /**
         * Adjusts the saturation and brightness. <code>x</code> and
         * <code>y</code> give the location to adjust to and are relative
         * to the origin of the wheel/triangle.
         *
         * @param x X coordinate on the triangle to adjust to
         * @param y Y coordinate on the triangle to adjust to
         * @param checkLoc if true the location is checked to make sure
         *        it is contained in the triangle, if false the location is
         *        constrained to fit in the triangle.
         * @return true if the location is valid
         */
        boolean adjustSB(int x, int y, boolean checkLoc) {
            int innerR = getWheelRadius() - getWheelWidth();
            boolean resetXY = false;
            // Invert the axis.
            y = -y;
            if (checkLoc && (x < -innerR || x > innerR || y < -innerR ||
                             y > innerR)) {
                return false;
            }
            // Rotate to origin and and verify x is valid.
            int triangleSize = (int)innerR * 3 / 2;
            double x1 = Math.cos(angle) * x - Math.sin(angle) * y;
            double y1 = Math.sin(angle) * x + Math.cos(angle) * y;
            if (x1 < -(innerR / 2)) {
                if (checkLoc) {
                    return false;
                }
                x1 = -innerR / 2;
                resetXY = true;
            }
            else if ((int)x1 > innerR) {
                if (checkLoc) {
                    return false;
                }
                x1 = innerR;
                resetXY = true;
            }
            // Verify y location is valid.
            int maxY = (int)((triangleSize - x1 - innerR / 2.0) *
                             Math.tan(Math.toRadians(30.0)));
            if (y1 <= -maxY) {
                if (checkLoc) {
                    return false;
                }
                y1 = -maxY;
                resetXY = true;
            }
            else if (y1 > maxY) {
                if (checkLoc) {
                    return false;
                }
                y1 = maxY;
                resetXY = true;
            }
            // Rotate again to determine value and scale
            double x2 = Math.cos(Math.toRadians(-30.0)) * x1 -
                 Math.sin(Math.toRadians(-30.0)) * y1;
            double y2 = Math.sin(Math.toRadians(-30.0)) * x1 +
                 Math.cos(Math.toRadians(-30.0)) * y1;
            float value = Math.min(1.0f, (float)((innerR - y2) /
                                                (double)triangleSize));
            float maxX = (float)(Math.tan(Math.toRadians(30)) * (innerR - y2));
            float saturation = Math.min(1.0f, (float)(x2 / maxX / 2 + .5));

            setFlag(FLAGS_SETTING_COLOR, true);
            if (resetXY) {
                setSaturationAndBrightness(saturation, value);
            }
            else {
                setSaturationAndBrightness(saturation, value, x +
                                      getWheelXOrigin(),getWheelYOrigin() - y);
            }
            GTKColorChooserPanel.this.setSaturationAndBrightness(saturation,
                                                                 value, true);
            setFlag(FLAGS_SETTING_COLOR, false);
            return true;
        }

        /**
         * Sets the saturation and brightness.
         */
        private void setSaturationAndBrightness(float s, float b) {
            int innerR = getTriangleCircumscribedRadius();
            int triangleSize = (int)innerR * 3 / 2;
            double x = b * triangleSize;
            double maxY = x * Math.tan(Math.toRadians(30.0));
            double y = 2 * maxY * s - maxY;
            x = x - innerR;
            double x1 = Math.cos(Math.toRadians(-60.0) - angle) *
                        x - Math.sin(Math.toRadians(-60.0) - angle) * y;
            double y1 = Math.sin(Math.toRadians(-60.0) - angle) * x +
                        Math.cos(Math.toRadians(-60.0) - angle) * y;
            int newCircleX = (int)x1 + getWheelXOrigin();
            int newCircleY = getWheelYOrigin() - (int)y1;

            setSaturationAndBrightness(s, b, newCircleX, newCircleY);
        }


        /**
         * Sets the saturation and brightness.
         */
        private void setSaturationAndBrightness(float s, float b,
                                             int newCircleX, int newCircleY) {
            newCircleX -= getIndicatorSize() / 2;
            newCircleY -= getIndicatorSize() / 2;

            int minX = Math.min(newCircleX, circleX);
            int minY = Math.min(newCircleY, circleY);

            repaint(minX, minY, Math.max(circleX, newCircleX) - minX +
                    getIndicatorSize() + 1, Math.max(circleY, newCircleY) -
                    minY + getIndicatorSize() + 1);
            circleX = newCircleX;
            circleY = newCircleY;
        }

        /**
         * Adjusts the hue based on the passed in location.
         *
         * @param x X location to adjust to, relative to the origin of the
         *        wheel
         * @param y Y location to adjust to, relative to the origin of the
         *        wheel
         * @param check if true the location is checked to make sure
         *        it is contained in the wheel, if false the location is
         *        constrained to fit in the wheel
         * @return true if the location is valid.
         */
        private boolean adjustHue(int x, int y, boolean check) {
            double rad = Math.sqrt(x * x + y * y);
            int size = getWheelRadius();

            if (!check || (rad >= size - getWheelWidth() && rad < size)) {
                // Map the location to an angle and reset hue
                double angle;
                if (x == 0) {
                    if (y > 0) {
                        angle = Math.PI / 2.0;
                    }
                    else {
                        angle = Math.PI + Math.PI / 2.0;
                    }
                }
                else {
                    angle = Math.atan((double)y / (double)x);
                    if (x < 0) {
                        angle += Math.PI;
                    }
                    else if (angle < 0) {
                        angle += 2 * Math.PI;
                    }
                }
                setFlag(FLAGS_SETTING_COLOR, true);
                setHue((float)(1.0 - angle / Math.PI / 2), true);
                setFlag(FLAGS_SETTING_COLOR, false);
                setHueAngle(angle);
                setSaturationAndBrightness(getSaturation(), getBrightness());
                return true;
            }
            return false;
        }

        /**
         * Rotates the triangle to accomodate the passed in hue.
         */
        private void setAngleFromHue(float hue) {
            setHueAngle((1.0 - hue) * Math.PI * 2);
        }

        /**
         * Sets the angle representing the hue.
         */
        private void setHueAngle(double angle) {
            double oldAngle = this.angle;

            this.angle = angle;
            if (angle != oldAngle) {
                setFlag(FLAGS_CHANGED_ANGLE, true);
                repaint();
            }
        }

        /**
         * Returns the size of the color indicator.
         */
        private int getIndicatorSize() {
            return 8;
        }

        /**
         * Returns the circumscribed radius of the triangle.
         */
        private int getTriangleCircumscribedRadius() {
            return 72;
        }

        /**
         * Returns the x origin of the wheel and triangle.
         */
        private int getWheelXOrigin() {
            return 85;
        }

        /**
         * Returns y origin of the wheel and triangle.
         */
        private int getWheelYOrigin() {
            return 85;
        }

        /**
         * Returns the width of the wheel.
         */
        private int getWheelWidth() {
            return 13;
        }

        /**
         * Sets the focus to one of: 0 no one, 1 the wheel or 2 the triangle.
         */
        private void setFocusType(int type) {
            if (type == 0) {
                setFlag(FLAGS_FOCUSED_WHEEL, false);
                setFlag(FLAGS_FOCUSED_TRIANGLE, false);
                repaint();
            }
            else {
                int toSet = FLAGS_FOCUSED_WHEEL;
                int toUnset = FLAGS_FOCUSED_TRIANGLE;

                if (type == 2) {
                    toSet = FLAGS_FOCUSED_TRIANGLE;
                    toUnset = FLAGS_FOCUSED_WHEEL;
                }
                if (!isSet(toSet)) {
                    setFlag(toSet, true);
                    repaint();
                    setFlag(toUnset, false);
                }
            }
        }

        /**
         * Returns the radius of the wheel.
         */
        private int getWheelRadius() {
            // As far as I can tell, GTK doesn't allow stretching this
            // widget
            return 85;
        }

        /**
         * Updates the flags bitmask.
         */
        private void setFlag(int flag, boolean value) {
            if (value) {
                flags |= flag;
            }
            else {
                flags &= ~flag;
            }
        }

        /**
         * Returns true if a particular flag has been set.
         */
        private boolean isSet(int flag) {
            return ((flags & flag) == flag);
        }

        /**
         * Returns the RGB color to use for the specified location. The
         * passed in point must be on the color wheel and be relative to the
         * origin of the color wheel.
         *
         * @param x X location to get color for
         * @param y Y location to get color for
         * @param rad Radius from center of color wheel
         * @param integer with red, green and blue components
         */
        private int colorWheelLocationToRGB(int x, int y, double rad) {
            double angle = Math.acos((double)x / rad);
            int rgb;

            if (angle < PI_3) {
                if (y < 0) {
                    // FFFF00 - FF0000
                    rgb = 0xFF0000 | (int)Math.min(255,
                                           (int)(255 * angle / PI_3)) << 8;
                }
                else {
                    // FF0000 - FF00FF
                    rgb = 0xFF0000 | (int)Math.min(255,
                                           (int)(255 * angle / PI_3));
                }
            }
            else if (angle < 2 * PI_3) {
                angle -= PI_3;
                if (y < 0) {
                    // 00FF00 - FFFF00
                    rgb = 0x00FF00 | (int)Math.max(0, 255 -
                                           (int)(255 * angle / PI_3)) << 16;
                }
                else {
                    // FF00FF - 0000FF
                    rgb = 0x0000FF | (int)Math.max(0, 255 -
                                           (int)(255 * angle / PI_3)) << 16;
                }
            }
            else {
                angle -= 2 * PI_3;
                if (y < 0) {
                    // 00FFFF - 00FF00
                    rgb = 0x00FF00 | (int)Math.min(255,
                                           (int)(255 * angle / PI_3));
                }
                else {
                    // 0000FF - 00FFFF
                    rgb = 0x0000FF | (int)Math.min(255,
                                           (int)(255 * angle / PI_3)) << 8;
                }
            }
            return rgb;
        }

        /**
         * Increments the hue.
         */
        void incrementHue(boolean positive) {
            float hue = triangle.getGTKColorChooserPanel().getHue();

            if (positive) {
                hue += 1.0f / 360.0f;
            }
            else {
                hue -= 1.0f / 360.0f;
            }
            if (hue > 1) {
                hue -= 1;
            }
            else if (hue < 0) {
                hue += 1;
            }
            getGTKColorChooserPanel().setHue(hue, true);
        }
    }


    /**
     * Action class used for colors.
     */
    private static class ColorAction extends AbstractAction {
        private int type;

        ColorAction(String name, int type) {
            super(name);
            this.type = type;
        }

        public void actionPerformed(ActionEvent e) {
            ColorTriangle triangle = (ColorTriangle)e.getSource();

            if (triangle.isWheelFocused()) {
                float hue = triangle.getGTKColorChooserPanel().getHue();

                switch (type) {
                case 0:
                case 2:
                    triangle.incrementHue(true);
                    break;
                case 1:
                case 3:
                    triangle.incrementHue(false);
                    break;
                case 4:
                    triangle.focusTriangle();
                    break;
                case 5:
                    compositeRequestFocus(triangle, false);
                    break;
                }
            }
            else {
                int xDelta = 0;
                int yDelta = 0;

                switch (type) {
                case 0:
                    // up
                    yDelta--;
                    break;
                case 1:
                    // down
                    yDelta++;
                    break;
                case 2:
                    // left
                    xDelta--;
                    break;
                case 3:
                    // right
                    xDelta++;
                    break;
                case 4:
                    compositeRequestFocus(triangle, true);
                    return;
                case 5:
                    triangle.focusWheel();
                    return;
                }
                triangle.adjustSB(triangle.getColorX() + xDelta,
                                  triangle.getColorY() + yDelta, true);
            }
        }
    }


    private class OpaqueLabel extends JLabel {
        public boolean isOpaque() {
            return true;
        }
    }
}
