/*
 * Copyright 2002-2006 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 sun.swing.SwingUtilities2;
import com.sun.java.swing.plaf.gtk.GTKConstants.ArrowType;
import com.sun.java.swing.plaf.gtk.GTKConstants.ShadowType;

import javax.swing.plaf.ColorUIResource;
import javax.swing.plaf.synth.*;

import java.awt.*;
import java.awt.geom.*;
import java.awt.image.*;
import java.io.*;
import java.net.*;
import java.security.*;
import java.util.*;

import javax.swing.*;
import javax.swing.border.*;

import javax.xml.parsers.*;
import org.xml.sax.SAXException;
import org.w3c.dom.*;

/**
 */
class Metacity implements SynthConstants {
    // Tutorial:
    // http://developer.gnome.org/doc/tutorials/metacity/metacity-themes.html

    // Themes:
    // http://art.gnome.org/theme_list.php?category=metacity

    static Metacity INSTANCE;

    private static final String[] themeNames = {
        getUserTheme(),
        "blueprint",
        "Bluecurve",
        "Crux",
        "SwingFallbackTheme"
    };

    static {
        for (String themeName : themeNames) {
            if (themeName != null) {
            try {
                INSTANCE = new Metacity(themeName);
            } catch (FileNotFoundException ex) {
            } catch (IOException ex) {
                logError(themeName, ex);
            } catch (ParserConfigurationException ex) {
                logError(themeName, ex);
            } catch (SAXException ex) {
                logError(themeName, ex);
            }
            }
            if (INSTANCE != null) {
            break;
            }
        }
        if (INSTANCE == null) {
            throw new Error("Could not find any installed metacity theme, and fallback failed");
        }
    }

    private static boolean errorLogged = false;
    private static DocumentBuilder documentBuilder;
    private static Document xmlDoc;
    private static String userHome;

    private Node frame_style_set;
    private Map<String, Object> frameGeometry;
    private Map<String, Map<String, Object>> frameGeometries;

    private LayoutManager titlePaneLayout = new TitlePaneLayout();

    private ColorizeImageFilter imageFilter = new ColorizeImageFilter();
    private URL themeDir = null;
    private SynthContext context;
    private String themeName;

    private ArithmeticExpressionEvaluator aee = new ArithmeticExpressionEvaluator();
    private Map<String, Integer> variables;

    // Reusable clip shape object
    private RoundRectClipShape roundedClipShape;

    protected Metacity(String themeName) throws IOException, ParserConfigurationException, SAXException {
        this.themeName = themeName;
        themeDir = getThemeDir(themeName);
        if (themeDir != null) {
            URL themeURL = new URL(themeDir, "metacity-theme-1.xml");
            xmlDoc = getXMLDoc(themeURL);
            if (xmlDoc == null) {
                throw new IOException(themeURL.toString());
            }
        } else {
            throw new FileNotFoundException(themeName);
        }

        // Initialize constants
        variables = new HashMap();
        NodeList nodes = xmlDoc.getElementsByTagName("constant");
        int n = nodes.getLength();
        for (int i = 0; i < n; i++) {
            Node node = nodes.item(i);
            String name = getStringAttr(node, "name");
            if (name != null) {
                String value = getStringAttr(node, "value");
                if (value != null) {
                    try {
                        variables.put(name, Integer.parseInt(value));
                    } catch (NumberFormatException ex) {
                        logError(themeName, ex);
                        // Ignore bad value
                    }
                }
            }
        }

        // Cache frame geometries
        frameGeometries = new HashMap();
        nodes = xmlDoc.getElementsByTagName("frame_geometry");
        n = nodes.getLength();
        for (int i = 0; i < n; i++) {
            Node node = nodes.item(i);
            String name = getStringAttr(node, "name");
            if (name != null) {
                HashMap<String, Object> gm = new HashMap();
                frameGeometries.put(name, gm);

                String parentGM = getStringAttr(node, "parent");
                if (parentGM != null) {
                    gm.putAll(frameGeometries.get(parentGM));
                }

                gm.put("has_title",
                       Boolean.valueOf(getBooleanAttr(node, "has_title",            true)));
                gm.put("rounded_top_left",
                       Boolean.valueOf(getBooleanAttr(node, "rounded_top_left",     false)));
                gm.put("rounded_top_right",
                       Boolean.valueOf(getBooleanAttr(node, "rounded_top_right",    false)));
                gm.put("rounded_bottom_left",
                       Boolean.valueOf(getBooleanAttr(node, "rounded_bottom_left",  false)));
                gm.put("rounded_bottom_right",
                       Boolean.valueOf(getBooleanAttr(node, "rounded_bottom_right", false)));

                NodeList childNodes = node.getChildNodes();
                int nc = childNodes.getLength();
                for (int j = 0; j < nc; j++) {
                    Node child = childNodes.item(j);
                    if (child.getNodeType() == Node.ELEMENT_NODE) {
                        name = child.getNodeName();
                        Object value = null;
                        if ("distance".equals(name)) {
                            value = new Integer(getIntAttr(child, "value", 0));
                        } else if ("border".equals(name)) {
                            value = new Insets(getIntAttr(child, "top", 0),
                                               getIntAttr(child, "left", 0),
                                               getIntAttr(child, "bottom", 0),
                                               getIntAttr(child, "right", 0));
                        } else if ("aspect_ratio".equals(name)) {
                            value = new Float(getFloatAttr(child, "value", 1.0F));
                        } else {
                            logError(themeName, "Unknown Metacity frame geometry value type: "+name);
                        }
                        String childName = getStringAttr(child, "name");
                        if (childName != null && value != null) {
                            gm.put(childName, value);
                        }
                    }
                }
            }
        }
        frameGeometry = frameGeometries.get("normal");
    }


    public static LayoutManager getTitlePaneLayout() {
        return INSTANCE.titlePaneLayout;
    }

    private Shape getRoundedClipShape(int x, int y, int w, int h,
                                      int arcw, int arch, int corners) {
        if (roundedClipShape == null) {
            roundedClipShape = new RoundRectClipShape();
        }
        roundedClipShape.setRoundedRect(x, y, w, h, arcw, arch, corners);

        return roundedClipShape;
    }

    void paintButtonBackground(SynthContext context, Graphics g, int x, int y, int w, int h) {
        updateFrameGeometry(context);

        this.context = context;
        JButton button = (JButton)context.getComponent();
        String buttonName = button.getName();
        int buttonState = context.getComponentState();

        JComponent titlePane = (JComponent)button.getParent();
        Container titlePaneParent = titlePane.getParent();

        JInternalFrame jif;
        if (titlePaneParent instanceof JInternalFrame) {
            jif = (JInternalFrame)titlePaneParent;
        } else if (titlePaneParent instanceof JInternalFrame.JDesktopIcon) {
            jif = ((JInternalFrame.JDesktopIcon)titlePaneParent).getInternalFrame();
        } else {
            return;
        }

        boolean active = jif.isSelected();
        button.setOpaque(false);

        String state = "normal";
        if ((buttonState & PRESSED) != 0) {
            state = "pressed";
        } else if ((buttonState & MOUSE_OVER) != 0) {
            state = "prelight";
        }

        String function = null;
        String location = null;
        boolean left_corner  = false;
        boolean right_corner = false;


        if (buttonName == "InternalFrameTitlePane.menuButton") {
            function = "menu";
            location = "left_left";
            left_corner = true;
        } else if (buttonName == "InternalFrameTitlePane.iconifyButton") {
            function = "minimize";
            int nButtons = ((jif.isIconifiable() ? 1 : 0) +
                            (jif.isMaximizable() ? 1 : 0) +
                            (jif.isClosable() ? 1 : 0));
            right_corner = (nButtons == 1);
            switch (nButtons) {
              case 1: location = "right_right"; break;
              case 2: location = "right_middle"; break;
              case 3: location = "right_left"; break;
            }
        } else if (buttonName == "InternalFrameTitlePane.maximizeButton") {
            function = "maximize";
            right_corner = !jif.isClosable();
            location = jif.isClosable() ? "right_middle" : "right_right";
        } else if (buttonName == "InternalFrameTitlePane.closeButton") {
            function = "close";
            right_corner = true;
            location = "right_right";
        }

        Node frame = getNode(frame_style_set, "frame", new String[] {
            "focus", (active ? "yes" : "no"),
            "state", (jif.isMaximum() ? "maximized" : "normal")
        });

        if (function != null && frame != null) {
            Node frame_style = getNode("frame_style", new String[] {
                "name", getStringAttr(frame, "style")
            });
            if (frame_style != null) {
                Shape oldClip = g.getClip();
                if ((right_corner && getBoolean("rounded_top_right", false)) ||
                    (left_corner  && getBoolean("rounded_top_left", false))) {

                    Point buttonLoc = button.getLocation();
                    if (right_corner) {
                        g.setClip(getRoundedClipShape(0, 0, w, h,
                                                      12, 12, RoundRectClipShape.TOP_RIGHT));
                    } else {
                        g.setClip(getRoundedClipShape(0, 0, w, h,
                                                      11, 11, RoundRectClipShape.TOP_LEFT));
                    }

                    Rectangle clipBounds = oldClip.getBounds();
                    g.clipRect(clipBounds.x, clipBounds.y,
                               clipBounds.width, clipBounds.height);
                }
                drawButton(frame_style, location+"_background", state, g, w, h, jif);
                drawButton(frame_style, function, state, g, w, h, jif);
                g.setClip(oldClip);
            }
        }
    }

    protected void drawButton(Node frame_style, String function, String state,
                            Graphics g, int w, int h, JInternalFrame jif) {
        Node buttonNode = getNode(frame_style, "button",
                                  new String[] { "function", function, "state", state });
        if (buttonNode == null && !state.equals("normal")) {
            buttonNode = getNode(frame_style, "button",
                                 new String[] { "function", function, "state", "normal" });
        }
        if (buttonNode != null) {
            Node draw_ops;
            String draw_ops_name = getStringAttr(buttonNode, "draw_ops");
            if (draw_ops_name != null) {
                draw_ops = getNode("draw_ops", new String[] { "name", draw_ops_name });
            } else {
                draw_ops = getNode(buttonNode, "draw_ops", null);
            }
            variables.put("width",  w);
            variables.put("height", h);
            draw(draw_ops, g, jif);
        }
    }

    void paintFrameBorder(SynthContext context, Graphics g, int x0, int y0, int width, int height) {
        updateFrameGeometry(context);

        this.context = context;
        JComponent comp = context.getComponent();
        JComponent titlePane = findChild(comp, "InternalFrame.northPane");

        if (titlePane == null) {
            return;
        }

        JInternalFrame jif = null;
        if (comp instanceof JInternalFrame) {
            jif = (JInternalFrame)comp;
        } else if (comp instanceof JInternalFrame.JDesktopIcon) {
            jif = ((JInternalFrame.JDesktopIcon)comp).getInternalFrame();
        } else {
            assert false : "component is not JInternalFrame or JInternalFrame.JDesktopIcon";
            return;
        }

        boolean active = jif.isSelected();
        Font oldFont = g.getFont();
        g.setFont(titlePane.getFont());
        g.translate(x0, y0);

        Rectangle titleRect = calculateTitleArea(jif);
        JComponent menuButton = findChild(titlePane, "InternalFrameTitlePane.menuButton");

        Icon frameIcon = jif.getFrameIcon();
        variables.put("mini_icon_width",
                      (frameIcon != null) ? frameIcon.getIconWidth()  : 0);
        variables.put("mini_icon_height",
                      (frameIcon != null) ? frameIcon.getIconHeight() : 0);
        variables.put("title_width",  calculateTitleTextWidth(g, jif));
        FontMetrics fm = SwingUtilities2.getFontMetrics(jif, g);
        variables.put("title_height", fm.getAscent() + fm.getDescent());

        // These don't seem to apply here, but the Galaxy theme uses them. Not sure why.
        variables.put("icon_width",  32);
        variables.put("icon_height", 32);

        if (frame_style_set != null) {
            Node frame = getNode(frame_style_set, "frame", new String[] {
                "focus", (active ? "yes" : "no"),
                "state", (jif.isMaximum() ? "maximized" : "normal")
            });

            if (frame != null) {
                Node frame_style = getNode("frame_style", new String[] {
                    "name", getStringAttr(frame, "style")
                });
                if (frame_style != null) {
                    Shape oldClip = g.getClip();
                    boolean roundTopLeft     = getBoolean("rounded_top_left",     false);
                    boolean roundTopRight    = getBoolean("rounded_top_right",    false);
                    boolean roundBottomLeft  = getBoolean("rounded_bottom_left",  false);
                    boolean roundBottomRight = getBoolean("rounded_bottom_right", false);

                    if (roundTopLeft || roundTopRight || roundBottomLeft || roundBottomRight) {
                        jif.setOpaque(false);

                        g.setClip(getRoundedClipShape(0, 0, width, height, 12, 12,
                                        (roundTopLeft     ? RoundRectClipShape.TOP_LEFT     : 0) |
                                        (roundTopRight    ? RoundRectClipShape.TOP_RIGHT    : 0) |
                                        (roundBottomLeft  ? RoundRectClipShape.BOTTOM_LEFT  : 0) |
                                        (roundBottomRight ? RoundRectClipShape.BOTTOM_RIGHT : 0)));
                    }

                    Rectangle clipBounds = oldClip.getBounds();
                    g.clipRect(clipBounds.x, clipBounds.y,
                               clipBounds.width, clipBounds.height);

                    int titleHeight = titlePane.getHeight();

                    boolean minimized = jif.isIcon();
                    Insets insets = getBorderInsets(context, null);

                    int leftTitlebarEdge   = getInt("left_titlebar_edge");
                    int rightTitlebarEdge  = getInt("right_titlebar_edge");
                    int topTitlebarEdge    = getInt("top_titlebar_edge");
                    int bottomTitlebarEdge = getInt("bottom_titlebar_edge");

                    if (!minimized) {
                        drawPiece(frame_style, g, "entire_background",
                                  0, 0, width, height, jif);
                    }
                    drawPiece(frame_style, g, "titlebar",
                              0, 0, width, titleHeight, jif);
                    drawPiece(frame_style, g, "titlebar_middle",
                              leftTitlebarEdge, topTitlebarEdge,
                              width - leftTitlebarEdge - rightTitlebarEdge,
                              titleHeight - topTitlebarEdge - bottomTitlebarEdge,
                              jif);
                    drawPiece(frame_style, g, "left_titlebar_edge",
                              0, 0, leftTitlebarEdge, titleHeight, jif);
                    drawPiece(frame_style, g, "right_titlebar_edge",
                              width - rightTitlebarEdge, 0,
                              rightTitlebarEdge, titleHeight, jif);
                    drawPiece(frame_style, g, "top_titlebar_edge",
                              0, 0, width, topTitlebarEdge, jif);
                    drawPiece(frame_style, g, "bottom_titlebar_edge",
                              0, titleHeight - bottomTitlebarEdge,
                              width, bottomTitlebarEdge, jif);
                    drawPiece(frame_style, g, "title",
                              titleRect.x, titleRect.y, titleRect.width, titleRect.height, jif);
                    if (!minimized) {
                        drawPiece(frame_style, g, "left_edge",
                                  0, titleHeight, insets.left, height-titleHeight, jif);
                        drawPiece(frame_style, g, "right_edge",
                                  width-insets.right, titleHeight, insets.right, height-titleHeight, jif);
                        drawPiece(frame_style, g, "bottom_edge",
                                  0, height - insets.bottom, width, insets.bottom, jif);
                        drawPiece(frame_style, g, "overlay",
                                  0, 0, width, height, jif);
                    }
                    g.setClip(oldClip);
                }
            }
        }
        g.translate(-x0, -y0);
        g.setFont(oldFont);
    }



    private static class Privileged implements PrivilegedAction {
        private static int GET_THEME_DIR  = 0;
        private static int GET_USER_THEME = 1;
        private static int GET_IMAGE      = 2;
        private int type;
        private Object arg;

        public Object doPrivileged(int type, Object arg) {
            this.type = type;
            this.arg = arg;
            return AccessController.doPrivileged(this);
        }

        public Object run() {
            if (type == GET_THEME_DIR) {
                String sep = File.separator;
                String[] dirs = new String[] {
                    userHome + sep + ".themes",
                    System.getProperty("swing.metacitythemedir"),
                    "/usr/share/themes",
                    "/usr/gnome/share/themes",  // Debian/Redhat/Solaris
                    "/opt/gnome2/share/themes"  // SuSE
                };

                URL themeDir = null;
                for (int i = 0; i < dirs.length; i++) {
                    // System property may not be set so skip null directories.
                    if (dirs[i] == null) {
                        continue;
                    }
                    File dir =
                        new File(dirs[i] + sep + arg + sep + "metacity-1");
                    if (new File(dir, "metacity-theme-1.xml").canRead()) {
                        try {
                            themeDir = dir.toURI().toURL();
                        } catch (MalformedURLException ex) {
                            themeDir = null;
                        }
                        break;
                    }
                }
                if (themeDir == null) {
                    String filename = "resources/metacity/" + arg +
                        "/metacity-1/metacity-theme-1.xml";
                    URL url = getClass().getResource(filename);
                    if (url != null) {
                        String str = url.toString();
                        try {
                            themeDir = new URL(str.substring(0, str.lastIndexOf('/'))+"/");
                        } catch (MalformedURLException ex) {
                            themeDir = null;
                        }
                    }
                }
                return themeDir;
            } else if (type == GET_USER_THEME) {
                try {
                    // Set userHome here because we need the privilege
                    userHome = System.getProperty("user.home");

                    String theme = System.getProperty("swing.metacitythemename");
                    if (theme != null) {
                        return theme;
                    }
                    // Note: this is a small file (< 1024 bytes) so it's not worth
                    // starting an XML parser or even to use a buffered reader.
                    URL url = new URL(new File(userHome).toURI().toURL(),
                                      ".gconf/apps/metacity/general/%25gconf.xml");
                    // Pending: verify character encoding spec for gconf
                    Reader reader = new InputStreamReader(url.openStream(), "ISO-8859-1");
                    char[] buf = new char[1024];
                    StringBuffer strBuf = new StringBuffer();
                    int n;
                    while ((n = reader.read(buf)) >= 0) {
                        strBuf.append(buf, 0, n);
                    }
                    reader.close();
                    String str = strBuf.toString();
                    if (str != null) {
                        String strLowerCase = str.toLowerCase();
                        int i = strLowerCase.indexOf("<entry name=\"theme\"");
                        if (i >= 0) {
                            i = strLowerCase.indexOf("<stringvalue>", i);
                            if (i > 0) {
                                i += "<stringvalue>".length();
                                int i2 = str.indexOf("<", i);
                                return str.substring(i, i2);
                            }
                        }
                    }
                } catch (MalformedURLException ex) {
                    // OK to just ignore. We'll use a fallback theme.
                } catch (IOException ex) {
                    // OK to just ignore. We'll use a fallback theme.
                }
                return null;
            } else if (type == GET_IMAGE) {
                return new ImageIcon((URL)arg).getImage();
            } else {
                return null;
            }
        }
    }

    private static URL getThemeDir(String themeName) {
        return (URL)new Privileged().doPrivileged(Privileged.GET_THEME_DIR, themeName);
    }

    private static String getUserTheme() {
        return (String)new Privileged().doPrivileged(Privileged.GET_USER_THEME, null);
    }

    protected void tileImage(Graphics g, Image image, int x0, int y0, int w, int h, float[] alphas) {
        Graphics2D g2 = (Graphics2D)g;
        Composite oldComp = g2.getComposite();

        int sw = image.getWidth(null);
        int sh = image.getHeight(null);
        int y = y0;
        while (y < y0 + h) {
            sh = Math.min(sh, y0 + h - y);
            int x = x0;
            while (x < x0 + w) {
                float f = (alphas.length - 1.0F) * x / (x0 + w);
                int i = (int)f;
                f -= (int)f;
                float alpha = (1-f) * alphas[i];
                if (i+1 < alphas.length) {
                    alpha += f * alphas[i+1];
                }
                g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
                int swm = Math.min(sw, x0 + w - x);
                g.drawImage(image, x, y, x+swm, y+sh, 0, 0, swm, sh, null);
                x += swm;
            }
            y += sh;
        }
        g2.setComposite(oldComp);
    }

    private HashMap<String, Image> images = new HashMap();

    protected Image getImage(String key, Color c) {
        Image image = images.get(key+"-"+c.getRGB());
        if (image == null) {
            image = imageFilter.colorize(getImage(key), c);
            if (image != null) {
                images.put(key+"-"+c.getRGB(), image);
            }
        }
        return image;
    }

    protected Image getImage(String key) {
        Image image = images.get(key);
        if (image == null) {
            if (themeDir != null) {
                try {
                    URL url = new URL(themeDir, key);
                    image = (Image)new Privileged().doPrivileged(Privileged.GET_IMAGE, url);
                } catch (MalformedURLException ex) {
                    //log("Bad image url: "+ themeDir + "/" + key);
                }
            }
            if (image != null) {
                images.put(key, image);
            }
        }
        return image;
    }

    private class ColorizeImageFilter extends RGBImageFilter {
        double cr, cg, cb;

        public ColorizeImageFilter() {
            canFilterIndexColorModel = true;
        }

        public void setColor(Color color) {
            cr = color.getRed()   / 255.0;
            cg = color.getGreen() / 255.0;
            cb = color.getBlue()  / 255.0;
        }

        public Image colorize(Image fromImage, Color c) {
            setColor(c);
            ImageProducer producer = new FilteredImageSource(fromImage.getSource(), this);
            return new ImageIcon(context.getComponent().createImage(producer)).getImage();
        }

        public int filterRGB(int x, int y, int rgb) {
            // Assume all rgb values are shades of gray
            double grayLevel = 2 * (rgb & 0xff) / 255.0;
            double r, g, b;

            if (grayLevel <= 1.0) {
                r = cr * grayLevel;
                g = cg * grayLevel;
                b = cb * grayLevel;
            } else {
                grayLevel -= 1.0;
                r = cr + (1.0 - cr) * grayLevel;
                g = cg + (1.0 - cg) * grayLevel;
                b = cb + (1.0 - cb) * grayLevel;
            }

            return ((rgb & 0xff000000) +
                    (((int)(r * 255)) << 16) +
                    (((int)(g * 255)) << 8) +
                    (int)(b * 255));
        }
    }

    protected static JComponent findChild(JComponent parent, String name) {
        int n = parent.getComponentCount();
        for (int i = 0; i < n; i++) {
            JComponent c = (JComponent)parent.getComponent(i);
            if (name.equals(c.getName())) {
                return c;
            }
        }
        return null;
    }


    protected class TitlePaneLayout implements LayoutManager {
        public void addLayoutComponent(String name, Component c) {}
        public void removeLayoutComponent(Component c) {}
        public Dimension preferredLayoutSize(Container c)  {
            return minimumLayoutSize(c);
        }

        public Dimension minimumLayoutSize(Container c) {
            JComponent titlePane = (JComponent)c;
            Container titlePaneParent = titlePane.getParent();
            JInternalFrame frame;
            if (titlePaneParent instanceof JInternalFrame) {
                frame = (JInternalFrame)titlePaneParent;
            } else if (titlePaneParent instanceof JInternalFrame.JDesktopIcon) {
                frame = ((JInternalFrame.JDesktopIcon)titlePaneParent).getInternalFrame();
            } else {
                return null;
            }

            Dimension buttonDim = calculateButtonSize(titlePane);
            Insets title_border  = (Insets)getFrameGeometry().get("title_border");
            Insets button_border = (Insets)getFrameGeometry().get("button_border");

            // Calculate width.
            int width = getInt("left_titlebar_edge") + buttonDim.width + getInt("right_titlebar_edge");
            if (title_border != null) {
                width += title_border.left + title_border.right;
            }
            if (frame.isClosable()) {
                width += buttonDim.width;
            }
            if (frame.isMaximizable()) {
                width += buttonDim.width;
            }
            if (frame.isIconifiable()) {
                width += buttonDim.width;
            }
            FontMetrics fm = frame.getFontMetrics(titlePane.getFont());
            String frameTitle = frame.getTitle();
            int title_w = frameTitle != null ? SwingUtilities2.stringWidth(
                               frame, fm, frameTitle) : 0;
            int title_length = frameTitle != null ? frameTitle.length() : 0;

            // Leave room for three characters in the title.
            if (title_length > 3) {
                int subtitle_w = SwingUtilities2.stringWidth(
                    frame, fm, frameTitle.substring(0, 3) + "...");
                width += (title_w < subtitle_w) ? title_w : subtitle_w;
            } else {
                width += title_w;
            }

            // Calculate height.
            int titleHeight = fm.getHeight() + getInt("title_vertical_pad");
            if (title_border != null) {
                titleHeight += title_border.top + title_border.bottom;
            }
            int buttonHeight = buttonDim.height;
            if (button_border != null) {
                buttonHeight += button_border.top + button_border.bottom;
            }
            int height = Math.max(buttonHeight, titleHeight);

            return new Dimension(width, height);
        }

        public void layoutContainer(Container c) {
            JComponent titlePane = (JComponent)c;
            Container titlePaneParent = titlePane.getParent();
            JInternalFrame frame;
            if (titlePaneParent instanceof JInternalFrame) {
                frame = (JInternalFrame)titlePaneParent;
            } else if (titlePaneParent instanceof JInternalFrame.JDesktopIcon) {
                frame = ((JInternalFrame.JDesktopIcon)titlePaneParent).getInternalFrame();
            } else {
                return;
            }
            Map gm = getFrameGeometry();

            int w = titlePane.getWidth();
            int h = titlePane.getHeight();

            JComponent menuButton     = findChild(titlePane, "InternalFrameTitlePane.menuButton");
            JComponent minimizeButton = findChild(titlePane, "InternalFrameTitlePane.iconifyButton");
            JComponent maximizeButton = findChild(titlePane, "InternalFrameTitlePane.maximizeButton");
            JComponent closeButton    = findChild(titlePane, "InternalFrameTitlePane.closeButton");

            int buttonGap = 0;

            Insets button_border = (Insets)gm.get("button_border");
            Dimension buttonDim = calculateButtonSize(titlePane);

            int x = getInt("left_titlebar_edge");
            int y = (button_border != null) ? button_border.top : 0;

            menuButton.setBounds(x, y, buttonDim.width, buttonDim.height);

            x = w - buttonDim.width - getInt("right_titlebar_edge");
            if (button_border != null) {
                x -= button_border.right;
            }

            if (frame.isClosable()) {
                closeButton.setBounds(x, y, buttonDim.width, buttonDim.height);
                x -= (buttonDim.width + buttonGap);
            }

            if (frame.isMaximizable()) {
                maximizeButton.setBounds(x, y, buttonDim.width, buttonDim.height);
                x -= (buttonDim.width + buttonGap);
            }

            if (frame.isIconifiable()) {
                minimizeButton.setBounds(x, y, buttonDim.width, buttonDim.height);
            }
        }
    } // end TitlePaneLayout

    protected Map getFrameGeometry() {
        return frameGeometry;
    }

    protected void setFrameGeometry(JComponent titlePane, Map gm) {
        this.frameGeometry = gm;
        if (getInt("top_height") == 0 && titlePane != null) {
            gm.put("top_height", new Integer(titlePane.getHeight()));
        }
    }

    protected int getInt(String key) {
        Integer i = (Integer)frameGeometry.get(key);
        if (i == null) {
            i = variables.get(key);
        }
        return (i != null) ? i.intValue() : 0;
    }

    protected boolean getBoolean(String key, boolean fallback) {
        Boolean b = (Boolean)frameGeometry.get(key);
        return (b != null) ? b.booleanValue() : fallback;
    }


    protected void drawArc(Node node, Graphics g) {
        NamedNodeMap attrs = node.getAttributes();
        Color color = parseColor(getStringAttr(attrs, "color"));
        int x = aee.evaluate(getStringAttr(attrs, "x"));
        int y = aee.evaluate(getStringAttr(attrs, "y"));
        int w = aee.evaluate(getStringAttr(attrs, "width"));
        int h = aee.evaluate(getStringAttr(attrs, "height"));
        int start_angle = aee.evaluate(getStringAttr(attrs, "start_angle"));
        int extent_angle = aee.evaluate(getStringAttr(attrs, "extent_angle"));
        boolean filled = getBooleanAttr(node, "filled", false);
        if (getInt("width") == -1) {
            x -= w;
        }
        if (getInt("height") == -1) {
            y -= h;
        }
        g.setColor(color);
        if (filled) {
            g.fillArc(x, y, w, h, start_angle, extent_angle);
        } else {
            g.drawArc(x, y, w, h, start_angle, extent_angle);
        }
    }

    protected void drawLine(Node node, Graphics g) {
        NamedNodeMap attrs = node.getAttributes();
        Color color = parseColor(getStringAttr(attrs, "color"));
        int x1 = aee.evaluate(getStringAttr(attrs, "x1"));
        int y1 = aee.evaluate(getStringAttr(attrs, "y1"));
        int x2 = aee.evaluate(getStringAttr(attrs, "x2"));
        int y2 = aee.evaluate(getStringAttr(attrs, "y2"));
        int lineWidth = aee.evaluate(getStringAttr(attrs, "width"), 1);
        g.setColor(color);
        if (lineWidth != 1) {
            Graphics2D g2d = (Graphics2D)g;
            Stroke stroke = g2d.getStroke();
            g2d.setStroke(new BasicStroke((float)lineWidth));
            g2d.drawLine(x1, y1, x2, y2);
            g2d.setStroke(stroke);
        } else {
            g.drawLine(x1, y1, x2, y2);
        }
    }

    protected void drawRectangle(Node node, Graphics g) {
        NamedNodeMap attrs = node.getAttributes();
        Color color = parseColor(getStringAttr(attrs, "color"));
        boolean filled = getBooleanAttr(node, "filled", false);
        int x = aee.evaluate(getStringAttr(attrs, "x"));
        int y = aee.evaluate(getStringAttr(attrs, "y"));
        int w = aee.evaluate(getStringAttr(attrs, "width"));
        int h = aee.evaluate(getStringAttr(attrs, "height"));
        g.setColor(color);
        if (getInt("width") == -1) {
            x -= w;
        }
        if (getInt("height") == -1) {
            y -= h;
        }
        if (filled) {
            g.fillRect(x, y, w, h);
        } else {
            g.drawRect(x, y, w, h);
        }
    }

    protected void drawTile(Node node, Graphics g, JInternalFrame jif) {
        NamedNodeMap attrs = node.getAttributes();
        int x0 = aee.evaluate(getStringAttr(attrs, "x"));
        int y0 = aee.evaluate(getStringAttr(attrs, "y"));
        int w = aee.evaluate(getStringAttr(attrs, "width"));
        int h = aee.evaluate(getStringAttr(attrs, "height"));
        int tw = aee.evaluate(getStringAttr(attrs, "tile_width"));
        int th = aee.evaluate(getStringAttr(attrs, "tile_height"));
        int width  = getInt("width");
        int height = getInt("height");
        if (width == -1) {
            x0 -= w;
        }
        if (height == -1) {
            y0 -= h;
        }
        Shape oldClip = g.getClip();
        if (g instanceof Graphics2D) {
            ((Graphics2D)g).clip(new Rectangle(x0, y0, w, h));
        }
        variables.put("width",  tw);
        variables.put("height", th);

        Node draw_ops = getNode("draw_ops", new String[] { "name", getStringAttr(node, "name") });

        int y = y0;
        while (y < y0 + h) {
            int x = x0;
            while (x < x0 + w) {
                g.translate(x, y);
                draw(draw_ops, g, jif);
                g.translate(-x, -y);
                x += tw;
            }
            y += th;
        }

        variables.put("width",  width);
        variables.put("height", height);
        g.setClip(oldClip);
    }

    protected void drawTint(Node node, Graphics g) {
        NamedNodeMap attrs = node.getAttributes();
        Color color = parseColor(getStringAttr(attrs, "color"));
        float alpha = Float.parseFloat(getStringAttr(attrs, "alpha"));
        int x = aee.evaluate(getStringAttr(attrs, "x"));
        int y = aee.evaluate(getStringAttr(attrs, "y"));
        int w = aee.evaluate(getStringAttr(attrs, "width"));
        int h = aee.evaluate(getStringAttr(attrs, "height"));
        if (getInt("width") == -1) {
            x -= w;
        }
        if (getInt("height") == -1) {
            y -= h;
        }
        if (g instanceof Graphics2D) {
            Graphics2D g2 = (Graphics2D)g;
            Composite oldComp = g2.getComposite();
            AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
            g2.setComposite(ac);
            g2.setColor(color);
            g2.fillRect(x, y, w, h);
            g2.setComposite(oldComp);
        }
    }

    protected void drawTitle(Node node, Graphics g, JInternalFrame jif) {
        NamedNodeMap attrs = node.getAttributes();
        String colorStr = getStringAttr(attrs, "color");
        int i = colorStr.indexOf("gtk:fg[");
        if (i > 0) {
            colorStr = colorStr.substring(0, i) + "gtk:text[" + colorStr.substring(i+7);
        }
        Color color = parseColor(colorStr);
        int x = aee.evaluate(getStringAttr(attrs, "x"));
        int y = aee.evaluate(getStringAttr(attrs, "y"));

        String title = jif.getTitle();
        if (title != null) {
            FontMetrics fm = SwingUtilities2.getFontMetrics(jif, g);
            if (jif.getComponentOrientation().isLeftToRight()) {
                title = SwingUtilities2.clipStringIfNecessary(jif, fm, title,
                             calculateTitleTextWidth(g, jif));
            }
            g.setColor(color);
            SwingUtilities2.drawString(jif, g, title, x, y + fm.getAscent());
        }
    }

    protected Dimension calculateButtonSize(JComponent titlePane) {
        int buttonHeight = getInt("button_height");
        if (buttonHeight == 0) {
            buttonHeight = titlePane.getHeight();
            if (buttonHeight == 0) {
                buttonHeight = 13;
            } else {
                Insets button_border = (Insets)frameGeometry.get("button_border");
                if (button_border != null) {
                    buttonHeight -= (button_border.top + button_border.bottom);
                }
            }
        }
        int buttonWidth = getInt("button_width");
        if (buttonWidth == 0) {
            buttonWidth = buttonHeight;
            Float aspect_ratio = (Float)frameGeometry.get("aspect_ratio");
            if (aspect_ratio != null) {
                buttonWidth = (int)(buttonHeight / aspect_ratio.floatValue());
            }
        }
        return new Dimension(buttonWidth, buttonHeight);
    }

    protected Rectangle calculateTitleArea(JInternalFrame jif) {
        JComponent titlePane = findChild(jif, "InternalFrame.northPane");
        Dimension buttonDim = calculateButtonSize(titlePane);
        Insets title_border = (Insets)frameGeometry.get("title_border");
        Rectangle r = new Rectangle();

        r.x = getInt("left_titlebar_edge") + buttonDim.width;
        r.y = 0;
        r.height = titlePane.getHeight();
        if (title_border != null) {
            r.x += title_border.left;
            r.y += title_border.top;
            r.height -= (title_border.top + title_border.bottom);
        }

        r.width = titlePane.getWidth() - r.x - getInt("right_titlebar_edge");
        if (jif.isClosable()) {
            r.width -= buttonDim.width;
        }
        if (jif.isMaximizable()) {
            r.width -= buttonDim.width;
        }
        if (jif.isIconifiable()) {
            r.width -= buttonDim.width;
        }
        if (title_border != null) {
            r.width -= title_border.right;
        }
        return r;
    }


    protected int calculateTitleTextWidth(Graphics g, JInternalFrame jif) {
        String title = jif.getTitle();
        if (title != null) {
            Rectangle r = calculateTitleArea(jif);
            return Math.min(SwingUtilities2.stringWidth(jif,
                     SwingUtilities2.getFontMetrics(jif, g), title), r.width);
        }
        return 0;
    }

    protected void setClip(Node node, Graphics g) {
        NamedNodeMap attrs = node.getAttributes();
        int x = aee.evaluate(getStringAttr(attrs, "x"));
        int y = aee.evaluate(getStringAttr(attrs, "y"));
        int w = aee.evaluate(getStringAttr(attrs, "width"));
        int h = aee.evaluate(getStringAttr(attrs, "height"));
        if (getInt("width") == -1) {
            x -= w;
        }
        if (getInt("height") == -1) {
            y -= h;
        }
        if (g instanceof Graphics2D) {
            ((Graphics2D)g).clip(new Rectangle(x, y, w, h));
        }
    }

    protected void drawGTKArrow(Node node, Graphics g) {
        NamedNodeMap attrs = node.getAttributes();
        String arrow    = getStringAttr(attrs, "arrow");
        String shadow   = getStringAttr(attrs, "shadow");
        String stateStr = getStringAttr(attrs, "state").toUpperCase();
        int x = aee.evaluate(getStringAttr(attrs, "x"));
        int y = aee.evaluate(getStringAttr(attrs, "y"));
        int w = aee.evaluate(getStringAttr(attrs, "width"));
        int h = aee.evaluate(getStringAttr(attrs, "height"));

        int state = -1;
        if ("NORMAL".equals(stateStr)) {
            state = ENABLED;
        } else if ("SELECTED".equals(stateStr)) {
            state = SELECTED;
        } else if ("INSENSITIVE".equals(stateStr)) {
            state = DISABLED;
        } else if ("PRELIGHT".equals(stateStr)) {
            state = MOUSE_OVER;
        }

        ShadowType shadowType = null;
        if ("in".equals(shadow)) {
            shadowType = ShadowType.IN;
        } else if ("out".equals(shadow)) {
            shadowType = ShadowType.OUT;
        } else if ("etched_in".equals(shadow)) {
            shadowType = ShadowType.ETCHED_IN;
        } else if ("etched_out".equals(shadow)) {
            shadowType = ShadowType.ETCHED_OUT;
        } else if ("none".equals(shadow)) {
            shadowType = ShadowType.NONE;
        }

        ArrowType direction = null;
        if ("up".equals(arrow)) {
            direction = ArrowType.UP;
        } else if ("down".equals(arrow)) {
            direction = ArrowType.DOWN;
        } else if ("left".equals(arrow)) {
            direction = ArrowType.LEFT;
        } else if ("right".equals(arrow)) {
            direction = ArrowType.RIGHT;
        }

        GTKPainter.INSTANCE.paintMetacityElement(context, g, state,
                "metacity-arrow", x, y, w, h, shadowType, direction);
    }

    protected void drawGTKBox(Node node, Graphics g) {
        NamedNodeMap attrs = node.getAttributes();
        String shadow   = getStringAttr(attrs, "shadow");
        String stateStr = getStringAttr(attrs, "state").toUpperCase();
        int x = aee.evaluate(getStringAttr(attrs, "x"));
        int y = aee.evaluate(getStringAttr(attrs, "y"));
        int w = aee.evaluate(getStringAttr(attrs, "width"));
        int h = aee.evaluate(getStringAttr(attrs, "height"));

        int state = -1;
        if ("NORMAL".equals(stateStr)) {
            state = ENABLED;
        } else if ("SELECTED".equals(stateStr)) {
            state = SELECTED;
        } else if ("INSENSITIVE".equals(stateStr)) {
            state = DISABLED;
        } else if ("PRELIGHT".equals(stateStr)) {
            state = MOUSE_OVER;
        }

        ShadowType shadowType = null;
        if ("in".equals(shadow)) {
            shadowType = ShadowType.IN;
        } else if ("out".equals(shadow)) {
            shadowType = ShadowType.OUT;
        } else if ("etched_in".equals(shadow)) {
            shadowType = ShadowType.ETCHED_IN;
        } else if ("etched_out".equals(shadow)) {
            shadowType = ShadowType.ETCHED_OUT;
        } else if ("none".equals(shadow)) {
            shadowType = ShadowType.NONE;
        }
        GTKPainter.INSTANCE.paintMetacityElement(context, g, state,
                "metacity-box", x, y, w, h, shadowType, null);
    }

    protected void drawGTKVLine(Node node, Graphics g) {
        NamedNodeMap attrs = node.getAttributes();
        String stateStr = getStringAttr(attrs, "state").toUpperCase();

        int x  = aee.evaluate(getStringAttr(attrs, "x"));
        int y1 = aee.evaluate(getStringAttr(attrs, "y1"));
        int y2 = aee.evaluate(getStringAttr(attrs, "y2"));

        int state = -1;
        if ("NORMAL".equals(stateStr)) {
            state = ENABLED;
        } else if ("SELECTED".equals(stateStr)) {
            state = SELECTED;
        } else if ("INSENSITIVE".equals(stateStr)) {
            state = DISABLED;
        } else if ("PRELIGHT".equals(stateStr)) {
            state = MOUSE_OVER;
        }

        GTKPainter.INSTANCE.paintMetacityElement(context, g, state,
                "metacity-vline", x, y1, 1, y2 - y1, null, null);
    }

    protected void drawGradient(Node node, Graphics g) {
        NamedNodeMap attrs = node.getAttributes();
        String type = getStringAttr(attrs, "type");
        float alpha = getFloatAttr(node, "alpha", -1F);
        int x = aee.evaluate(getStringAttr(attrs, "x"));
        int y = aee.evaluate(getStringAttr(attrs, "y"));
        int w = aee.evaluate(getStringAttr(attrs, "width"));
        int h = aee.evaluate(getStringAttr(attrs, "height"));
        if (getInt("width") == -1) {
            x -= w;
        }
        if (getInt("height") == -1) {
            y -= h;
        }

        // Get colors from child nodes
        Node[] colorNodes = getNodesByName(node, "color");
        Color[] colors = new Color[colorNodes.length];
        for (int i = 0; i < colorNodes.length; i++) {
            colors[i] = parseColor(getStringAttr(colorNodes[i], "value"));
        }

        boolean horizontal = ("diagonal".equals(type) || "horizontal".equals(type));
        boolean vertical   = ("diagonal".equals(type) || "vertical".equals(type));

        if (g instanceof Graphics2D) {
            Graphics2D g2 = (Graphics2D)g;
            Composite oldComp = g2.getComposite();
            if (alpha >= 0F) {
                g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
            }
            int n = colors.length - 1;
            for (int i = 0; i < n; i++) {
                g2.setPaint(new GradientPaint(x + (horizontal ? (i*w/n) : 0),
                                              y + (vertical   ? (i*h/n) : 0),
                                              colors[i],
                                              x + (horizontal ? ((i+1)*w/n) : 0),
                                              y + (vertical   ? ((i+1)*h/n) : 0),
                                              colors[i+1]));
                g2.fillRect(x + (horizontal ? (i*w/n) : 0),
                            y + (vertical   ? (i*h/n) : 0),
                            (horizontal ? (w/n) : w),
                            (vertical   ? (h/n) : h));
            }
            g2.setComposite(oldComp);
        }
    }

    protected void drawImage(Node node, Graphics g) {
        NamedNodeMap attrs = node.getAttributes();
        String filename = getStringAttr(attrs, "filename");
        String colorizeStr = getStringAttr(attrs, "colorize");
        Color colorize = (colorizeStr != null) ? parseColor(colorizeStr) : null;
        String alpha = getStringAttr(attrs, "alpha");
        Image object = (colorize != null) ? getImage(filename, colorize) : getImage(filename);
        variables.put("object_width",  object.getWidth(null));
        variables.put("object_height", object.getHeight(null));
        String fill_type = getStringAttr(attrs, "fill_type");
        int x = aee.evaluate(getStringAttr(attrs, "x"));
        int y = aee.evaluate(getStringAttr(attrs, "y"));
        int w = aee.evaluate(getStringAttr(attrs, "width"));
        int h = aee.evaluate(getStringAttr(attrs, "height"));
        if (getInt("width") == -1) {
            x -= w;
        }
        if (getInt("height") == -1) {
            y -= h;
        }

        if (alpha != null) {
            if ("tile".equals(fill_type)) {
                StringTokenizer tokenizer = new StringTokenizer(alpha, ":");
                float[] alphas = new float[tokenizer.countTokens()];
                for (int i = 0; i < alphas.length; i++) {
                    alphas[i] = Float.parseFloat(tokenizer.nextToken());
                }
                tileImage(g, object, x, y, w, h, alphas);
            } else {
                float a = Float.parseFloat(alpha);
                if (g instanceof Graphics2D) {
                    Graphics2D g2 = (Graphics2D)g;
                    Composite oldComp = g2.getComposite();
                    g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, a));
                    g2.drawImage(object, x, y, w, h, null);
                    g2.setComposite(oldComp);
                }
            }
        } else {
            g.drawImage(object, x, y, w, h, null);
        }
    }

    protected void drawIcon(Node node, Graphics g, JInternalFrame jif) {
        Icon icon = jif.getFrameIcon();
        if (icon == null) {
            return;
        }

        NamedNodeMap attrs = node.getAttributes();
        String alpha = getStringAttr(attrs, "alpha");
        int x = aee.evaluate(getStringAttr(attrs, "x"));
        int y = aee.evaluate(getStringAttr(attrs, "y"));
        int w = aee.evaluate(getStringAttr(attrs, "width"));
        int h = aee.evaluate(getStringAttr(attrs, "height"));
        if (getInt("width") == -1) {
            x -= w;
        }
        if (getInt("height") == -1) {
            y -= h;
        }

        if (alpha != null) {
            float a = Float.parseFloat(alpha);
            if (g instanceof Graphics2D) {
                Graphics2D g2 = (Graphics2D)g;
                Composite oldComp = g2.getComposite();
                g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, a));
                icon.paintIcon(jif, g, x, y);
                g2.setComposite(oldComp);
            }
        } else {
            icon.paintIcon(jif, g, x, y);
        }
    }

    protected void drawInclude(Node node, Graphics g, JInternalFrame jif) {
        int oldWidth  = getInt("width");
        int oldHeight = getInt("height");

        NamedNodeMap attrs = node.getAttributes();
        int x = aee.evaluate(getStringAttr(attrs, "x"),       0);
        int y = aee.evaluate(getStringAttr(attrs, "y"),       0);
        int w = aee.evaluate(getStringAttr(attrs, "width"),  -1);
        int h = aee.evaluate(getStringAttr(attrs, "height"), -1);

        if (w != -1) {
            variables.put("width",  w);
        }
        if (h != -1) {
            variables.put("height", h);
        }

        Node draw_ops = getNode("draw_ops", new String[] {
            "name", getStringAttr(node, "name")
        });
        g.translate(x, y);
        draw(draw_ops, g, jif);
        g.translate(-x, -y);

        if (w != -1) {
            variables.put("width",  oldWidth);
        }
        if (h != -1) {
            variables.put("height", oldHeight);
        }
    }

    protected void draw(Node draw_ops, Graphics g, JInternalFrame jif) {
        if (draw_ops != null) {
            NodeList nodes = draw_ops.getChildNodes();
            if (nodes != null) {
                Shape oldClip = g.getClip();
                for (int i = 0; i < nodes.getLength(); i++) {
                    Node child = nodes.item(i);
                    if (child.getNodeType() == Node.ELEMENT_NODE) {
                        try {
                            String name = child.getNodeName();
                            if ("include".equals(name)) {
                                drawInclude(child, g, jif);
                            } else if ("arc".equals(name)) {
                                drawArc(child, g);
                            } else if ("clip".equals(name)) {
                                setClip(child, g);
                            } else if ("gradient".equals(name)) {
                                drawGradient(child, g);
                            } else if ("gtk_arrow".equals(name)) {
                                drawGTKArrow(child, g);
                            } else if ("gtk_box".equals(name)) {
                                drawGTKBox(child, g);
                            } else if ("gtk_vline".equals(name)) {
                                drawGTKVLine(child, g);
                            } else if ("image".equals(name)) {
                                drawImage(child, g);
                            } else if ("icon".equals(name)) {
                                drawIcon(child, g, jif);
                            } else if ("line".equals(name)) {
                                drawLine(child, g);
                            } else if ("rectangle".equals(name)) {
                                drawRectangle(child, g);
                            } else if ("tint".equals(name)) {
                                drawTint(child, g);
                            } else if ("tile".equals(name)) {
                                drawTile(child, g, jif);
                            } else if ("title".equals(name)) {
                                drawTitle(child, g, jif);
                            } else {
                                System.err.println("Unknown Metacity drawing op: "+child);
                            }
                        } catch (NumberFormatException ex) {
                            logError(themeName, ex);
                        }
                    }
                }
                g.setClip(oldClip);
            }
        }
    }

    protected void drawPiece(Node frame_style, Graphics g, String position, int x, int y,
                             int width, int height, JInternalFrame jif) {
        Node piece = getNode(frame_style, "piece", new String[] { "position", position });
        if (piece != null) {
            Node draw_ops;
            String draw_ops_name = getStringAttr(piece, "draw_ops");
            if (draw_ops_name != null) {
                draw_ops = getNode("draw_ops", new String[] { "name", draw_ops_name });
            } else {
                draw_ops = getNode(piece, "draw_ops", null);
            }
            variables.put("width",  width);
            variables.put("height", height);
            g.translate(x, y);
            draw(draw_ops, g, jif);
            g.translate(-x, -y);
        }
    }


    Insets getBorderInsets(SynthContext context, Insets insets) {
        updateFrameGeometry(context);

        if (insets == null) {
            insets = new Insets(0, 0, 0, 0);
        }
        insets.top    = ((Insets)frameGeometry.get("title_border")).top;
        insets.bottom = getInt("bottom_height");
        insets.left   = getInt("left_width");
        insets.right  = getInt("right_width");
        return insets;
    }


    private void updateFrameGeometry(SynthContext context) {
        this.context = context;
        JComponent comp = context.getComponent();
        JComponent titlePane = findChild(comp, "InternalFrame.northPane");

        JInternalFrame jif = null;
        if (comp instanceof JInternalFrame) {
            jif = (JInternalFrame)comp;
        } else if (comp instanceof JInternalFrame.JDesktopIcon) {
            jif = ((JInternalFrame.JDesktopIcon)comp).getInternalFrame();
        } else {
            assert false : "component is not JInternalFrame or JInternalFrame.JDesktopIcon";
            return;
        }

        if (frame_style_set == null) {
            Node window = getNode("window", new String[]{"type", "normal"});

            if (window != null) {
                frame_style_set = getNode("frame_style_set",
                        new String[] {"name", getStringAttr(window, "style_set")});
            }

            if (frame_style_set == null) {
                frame_style_set = getNode("frame_style_set", new String[] {"name", "normal"});
            }
        }

        if (frame_style_set != null) {
            Node frame = getNode(frame_style_set, "frame", new String[] {
                "focus", (jif.isSelected() ? "yes" : "no"),
                "state", (jif.isMaximum() ? "maximized" : "normal")
            });

            if (frame != null) {
                Node frame_style = getNode("frame_style", new String[] {
                    "name", getStringAttr(frame, "style")
                });
                if (frame_style != null) {
                    Map gm = frameGeometries.get(getStringAttr(frame_style, "geometry"));

                    setFrameGeometry(titlePane, gm);
                }
            }
        }
    }


    protected static void logError(String themeName, Exception ex) {
        logError(themeName, ex.toString());
    }

    protected static void logError(String themeName, String msg) {
        if (!errorLogged) {
            System.err.println("Exception in Metacity for theme \""+themeName+"\": "+msg);
            errorLogged = true;
        }
    }


    // XML Parsing


    protected static Document getXMLDoc(final URL xmlFile)
                                throws IOException,
                                       ParserConfigurationException,
                                       SAXException {
        if (documentBuilder == null) {
            documentBuilder =
                DocumentBuilderFactory.newInstance().newDocumentBuilder();
        }
        InputStream inputStream =
            (InputStream)AccessController.doPrivileged(new PrivilegedAction() {
                public Object run() {
                    try {
                        return new BufferedInputStream(xmlFile.openStream());
                    } catch (IOException ex) {
                        return null;
                    }
                }
            });

        Document doc = null;
        if (inputStream != null) {
            doc = documentBuilder.parse(inputStream);
        }
        return doc;
    }


    protected Node[] getNodesByName(Node parent, String name) {
        NodeList nodes = parent.getChildNodes(); // ElementNode
        int n = nodes.getLength();
        ArrayList<Node> list = new ArrayList();
        for (int i=0; i < n; i++) {
            Node node = nodes.item(i);
            if (name.equals(node.getNodeName())) {
                list.add(node);
            }
        }
        return list.toArray(new Node[list.size()]);
    }



    protected Node getNode(String tagName, String[] attrs) {
        NodeList nodes = xmlDoc.getElementsByTagName(tagName);
        return (nodes != null) ? getNode(nodes, tagName, attrs) : null;
    }

    protected Node getNode(Node parent, String name, String[] attrs) {
        Node node = null;
        NodeList nodes = parent.getChildNodes();
        if (nodes != null) {
            node = getNode(nodes, name, attrs);
        }
        if (node == null) {
            String inheritFrom = getStringAttr(parent, "parent");
            if (inheritFrom != null) {
                Node inheritFromNode = getNode(parent.getParentNode(),
                                               parent.getNodeName(),
                                               new String[] { "name", inheritFrom });
                if (inheritFromNode != null) {
                    node = getNode(inheritFromNode, name, attrs);
                }
            }
        }
        return node;
    }

    protected Node getNode(NodeList nodes, String name, String[] attrs) {
        int n = nodes.getLength();
        for (int i=0; i < n; i++) {
            Node node = nodes.item(i);
            if (name.equals(node.getNodeName())) {
                if (attrs != null) {
                    NamedNodeMap nodeAttrs = node.getAttributes();
                    if (nodeAttrs != null) {
                        boolean matches = true;
                        int nAttrs = attrs.length / 2;
                        for (int a = 0; a < nAttrs; a++) {
                            String aName  = attrs[a * 2];
                            String aValue = attrs[a * 2 + 1];
                            Node attr = nodeAttrs.getNamedItem(aName);
                            if (attr == null ||
                                aValue != null && !aValue.equals((String)attr.getNodeValue())) {
                                matches = false;
                                break;
                            }
                        }
                        if (matches) {
                            return node;
                        }
                    }
                } else {
                    return node;
                }
            }
        }
        return null;
    }

    protected String getStringAttr(Node node, String name) {
        String value = null;
        NamedNodeMap attrs = node.getAttributes();
        if (attrs != null) {
            value = getStringAttr(attrs, name);
            if (value == null) {
                String inheritFrom = getStringAttr(attrs, "parent");
                if (inheritFrom != null) {
                    Node inheritFromNode = getNode(node.getParentNode(),
                                                   node.getNodeName(),
                                                   new String[] { "name", inheritFrom });
                    if (inheritFromNode != null) {
                        value = getStringAttr(inheritFromNode, name);
                    }
                }
            }
        }
        return value;
    }

    protected String getStringAttr(NamedNodeMap attrs, String name) {
        Node item = attrs.getNamedItem(name);
        return (item != null) ? (String)item.getNodeValue() : null;
    }

    protected boolean getBooleanAttr(Node node, String name, boolean fallback) {
        String str = getStringAttr(node, name);
        if (str != null) {
            return Boolean.valueOf(str).booleanValue();
        }
        return fallback;
    }

    protected int getIntAttr(Node node, String name, int fallback) {
        String str = getStringAttr(node, name);
        int value = fallback;
        if (str != null) {
            try {
                value = Integer.parseInt(str);
            } catch (NumberFormatException ex) {
                logError(themeName, ex);
            }
        }
        return value;
    }

    protected float getFloatAttr(Node node, String name, float fallback) {
        String str = getStringAttr(node, name);
        float value = fallback;
        if (str != null) {
            try {
                value = Float.parseFloat(str);
            } catch (NumberFormatException ex) {
                logError(themeName, ex);
            }
        }
        return value;
    }



    protected Color parseColor(String str) {
        StringTokenizer tokenizer = new StringTokenizer(str, "/");
        int n = tokenizer.countTokens();
        if (n > 1) {
            String function = tokenizer.nextToken();
            if ("shade".equals(function)) {
                assert (n == 3);
                Color c = parseColor2(tokenizer.nextToken());
                float alpha = Float.parseFloat(tokenizer.nextToken());
                return GTKColorType.adjustColor(c, 1.0F, alpha, alpha);
            } else if ("blend".equals(function)) {
                assert (n == 4);
                Color  bg = parseColor2(tokenizer.nextToken());
                Color  fg = parseColor2(tokenizer.nextToken());
                float alpha = Float.parseFloat(tokenizer.nextToken());
                if (alpha > 1.0f) {
                    alpha = 1.0f / alpha;
                }

                return new Color((int)(bg.getRed() + ((fg.getRed() - bg.getRed()) * alpha)),
                                 (int)(bg.getRed() + ((fg.getRed() - bg.getRed()) * alpha)),
                                 (int)(bg.getRed() + ((fg.getRed() - bg.getRed()) * alpha)));
            } else {
                System.err.println("Unknown Metacity color function="+str);
                return null;
            }
        } else {
            return parseColor2(str);
        }
    }

    protected Color parseColor2(String str) {
        Color c = null;
        if (str.startsWith("gtk:")) {
            int i1 = str.indexOf('[');
            if (i1 > 3) {
                String typeStr = str.substring(4, i1).toLowerCase();
                int i2 = str.indexOf(']');
                if (i2 > i1+1) {
                    String stateStr = str.substring(i1+1, i2).toUpperCase();
                    int state = -1;
                    if ("ACTIVE".equals(stateStr)) {
                        state = PRESSED;
                    } else if ("INSENSITIVE".equals(stateStr)) {
                        state = DISABLED;
                    } else if ("NORMAL".equals(stateStr)) {
                        state = ENABLED;
                    } else if ("PRELIGHT".equals(stateStr)) {
                        state = MOUSE_OVER;
                    } else if ("SELECTED".equals(stateStr)) {
                        state = SELECTED;
                    }
                    ColorType type = null;
                    if ("fg".equals(typeStr)) {
                        type = GTKColorType.FOREGROUND;
                    } else if ("bg".equals(typeStr)) {
                        type = GTKColorType.BACKGROUND;
                    } else if ("base".equals(typeStr)) {
                        type = GTKColorType.TEXT_BACKGROUND;
                    } else if ("text".equals(typeStr)) {
                        type = GTKColorType.TEXT_FOREGROUND;
                    } else if ("dark".equals(typeStr)) {
                        type = GTKColorType.DARK;
                    } else if ("light".equals(typeStr)) {
                        type = GTKColorType.LIGHT;
                    }
                    if (state >= 0 && type != null) {
                        c = ((GTKStyle)context.getStyle()).getGTKColor(context, state, type);
                    }
                }
            }
        }
        if (c == null) {
            c = parseColorString(str);
        }
        return c;
    }

    private static Color parseColorString(String str) {
        if (str.charAt(0) == '#') {
            str = str.substring(1);

            int i = str.length();

            if (i < 3 || i > 12 || (i % 3) != 0) {
                return null;
            }

            i /= 3;

            int r;
            int g;
            int b;

            try {
                r = Integer.parseInt(str.substring(0, i), 16);
                g = Integer.parseInt(str.substring(i, i * 2), 16);
                b = Integer.parseInt(str.substring(i * 2, i * 3), 16);
            } catch (NumberFormatException nfe) {
                return null;
            }

            if (i == 4) {
                return new ColorUIResource(r / 65535.0f, g / 65535.0f, b / 65535.0f);
            } else if (i == 1) {
                return new ColorUIResource(r / 15.0f, g / 15.0f, b / 15.0f);
            } else if (i == 2) {
                return new ColorUIResource(r, g, b);
            } else {
                return new ColorUIResource(r / 4095.0f, g / 4095.0f, b / 4095.0f);
            }
        } else {
            return XColors.lookupColor(str);
        }
    }

    class ArithmeticExpressionEvaluator {
        private PeekableStringTokenizer tokenizer;

        int evaluate(String expr) {
            tokenizer = new PeekableStringTokenizer(expr, " \t+-*/%()", true);
            return Math.round(expression());
        }

        int evaluate(String expr, int fallback) {
            return (expr != null) ? evaluate(expr) : fallback;
        }

        public float expression() {
            float value = getTermValue();
            boolean done = false;
            while (!done && tokenizer.hasMoreTokens()) {
                String next = tokenizer.peek();
                if ("+".equals(next) ||
                    "-".equals(next) ||
                    "`max`".equals(next) ||
                    "`min`".equals(next)) {
                    tokenizer.nextToken();
                    float value2 = getTermValue();
                    if ("+".equals(next)) {
                        value += value2;
                    } else if ("-".equals(next)) {
                        value -= value2;
                    } else if ("`max`".equals(next)) {
                        value = Math.max(value, value2);
                    } else if ("`min`".equals(next)) {
                        value = Math.min(value, value2);
                    }
                } else {
                    done = true;
                }
            }
            return value;
        }

        public float getTermValue() {
            float value = getFactorValue();
            boolean done = false;
            while (!done && tokenizer.hasMoreTokens()) {
                String next = tokenizer.peek();
                if ("*".equals(next) || "/".equals(next) || "%".equals(next)) {
                    tokenizer.nextToken();
                    float value2 = getFactorValue();
                    if ("*".equals(next)) {
                        value *= value2;
                    } else if ("/".equals(next)) {
                        value /= value2;
                    } else {
                        value %= value2;
                    }
                } else {
                    done = true;
                }
            }
            return value;
        }

        public float getFactorValue() {
            float value;
            if ("(".equals(tokenizer.peek())) {
                tokenizer.nextToken();
                value = expression();
                tokenizer.nextToken(); // skip right paren
            } else {
                String token = tokenizer.nextToken();
                if (Character.isDigit(token.charAt(0))) {
                    value = Float.parseFloat(token);
                } else {
                    Integer i = variables.get(token);
                    if (i == null) {
                        i = (Integer)getFrameGeometry().get(token);
                    }
                    if (i == null) {
                        logError(themeName, "Variable \"" + token + "\" not defined");
                        return 0;
                    }
                    value = (i != null) ? i.intValue() : 0F;
                }
            }
            return value;
        }


    }

    static class PeekableStringTokenizer extends StringTokenizer {
        String token = null;

        public PeekableStringTokenizer(String str, String delim,
                                       boolean returnDelims) {
            super(str, delim, returnDelims);
            peek();
        }

        public String peek() {
            if (token == null) {
                token = nextToken();
            }
            return token;
        }

        public boolean hasMoreTokens() {
            return (token != null || super.hasMoreTokens());
        }

        public String nextToken() {
            if (token != null) {
                String t = token;
                token = null;
                if (hasMoreTokens()) {
                    peek();
                }
                return t;
            } else {
                String token = super.nextToken();
                while ((token.equals(" ") || token.equals("\t"))
                       && hasMoreTokens()) {
                    token = super.nextToken();
                }
                return token;
            }
        }
    }


    static class RoundRectClipShape extends RectangularShape {
        static final int TOP_LEFT = 1;
        static final int TOP_RIGHT = 2;
        static final int BOTTOM_LEFT = 4;
        static final int BOTTOM_RIGHT = 8;

        int x;
        int y;
        int width;
        int height;
        int arcwidth;
        int archeight;
        int corners;

        public RoundRectClipShape() {
        }

        public RoundRectClipShape(int x, int y, int w, int h,
                                  int arcw, int arch, int corners) {
            setRoundedRect(x, y, w, h, arcw, arch, corners);
        }

        public void setRoundedRect(int x, int y, int w, int h,
                                   int arcw, int arch, int corners) {
            this.corners = corners;
            this.x = x;
            this.y = y;
            this.width = w;
            this.height = h;
            this.arcwidth = arcw;
            this.archeight = arch;
        }

        public double getX() {
            return (double)x;
        }

        public double getY() {
            return (double)y;
        }

        public double getWidth() {
            return (double)width;
        }

        public double getHeight() {
            return (double)height;
        }

        public double getArcWidth() {
            return (double)arcwidth;
        }

        public double getArcHeight() {
            return (double)archeight;
        }

        public boolean isEmpty() {
            return false;  // Not called
        }

        public Rectangle2D getBounds2D() {
            return null;  // Not called
        }

        public int getCornerFlags() {
            return corners;
        }

        public void setFrame(double x, double y, double w, double h) {
            // Not called
        }

        public boolean contains(double x, double y) {
            return false;  // Not called
        }

        private int classify(double coord, double left, double right, double arcsize) {
            return 0;  // Not called
        }

        public boolean intersects(double x, double y, double w, double h) {
            return false;  // Not called
        }

        public boolean contains(double x, double y, double w, double h) {
            return false;  // Not called
        }

        public PathIterator getPathIterator(AffineTransform at) {
            return new RoundishRectIterator(this, at);
        }


        static class RoundishRectIterator implements PathIterator {
            double x, y, w, h, aw, ah;
            AffineTransform affine;
            int index;

            double ctrlpts[][];
            int types[];

            private static final double angle = Math.PI / 4.0;
            private static final double a = 1.0 - Math.cos(angle);
            private static final double b = Math.tan(angle);
            private static final double c = Math.sqrt(1.0 + b * b) - 1 + a;
            private static final double cv = 4.0 / 3.0 * a * b / c;
            private static final double acv = (1.0 - cv) / 2.0;

            // For each array:
            //     4 values for each point {v0, v1, v2, v3}:
            //         point = (x + v0 * w + v1 * arcWidth,
            //                  y + v2 * h + v3 * arcHeight);
            private static final double CtrlPtTemplate[][] = {
                {  0.0,  0.0,  1.0,  0.0 },     /* BOTTOM LEFT corner */
                {  0.0,  0.0,  1.0, -0.5 },     /* BOTTOM LEFT arc start */
                {  0.0,  0.0,  1.0, -acv,       /* BOTTOM LEFT arc curve */
                   0.0,  acv,  1.0,  0.0,
                   0.0,  0.5,  1.0,  0.0 },
                {  1.0,  0.0,  1.0,  0.0 },     /* BOTTOM RIGHT corner */
                {  1.0, -0.5,  1.0,  0.0 },     /* BOTTOM RIGHT arc start */
                {  1.0, -acv,  1.0,  0.0,       /* BOTTOM RIGHT arc curve */
                   1.0,  0.0,  1.0, -acv,
                   1.0,  0.0,  1.0, -0.5 },
                {  1.0,  0.0,  0.0,  0.0 },     /* TOP RIGHT corner */
                {  1.0,  0.0,  0.0,  0.5 },     /* TOP RIGHT arc start */
                {  1.0,  0.0,  0.0,  acv,       /* TOP RIGHT arc curve */
                   1.0, -acv,  0.0,  0.0,
                   1.0, -0.5,  0.0,  0.0 },
                {  0.0,  0.0,  0.0,  0.0 },     /* TOP LEFT corner */
                {  0.0,  0.5,  0.0,  0.0 },     /* TOP LEFT arc start */
                {  0.0,  acv,  0.0,  0.0,       /* TOP LEFT arc curve */
                   0.0,  0.0,  0.0,  acv,
                   0.0,  0.0,  0.0,  0.5 },
                {},                             /* Closing path element */
            };
            private static final int CornerFlags[] = {
                RoundRectClipShape.BOTTOM_LEFT,
                RoundRectClipShape.BOTTOM_RIGHT,
                RoundRectClipShape.TOP_RIGHT,
                RoundRectClipShape.TOP_LEFT,
            };

            RoundishRectIterator(RoundRectClipShape rr, AffineTransform at) {
                this.x = rr.getX();
                this.y = rr.getY();
                this.w = rr.getWidth();
                this.h = rr.getHeight();
                this.aw = Math.min(w, Math.abs(rr.getArcWidth()));
                this.ah = Math.min(h, Math.abs(rr.getArcHeight()));
                this.affine = at;
                if (w < 0 || h < 0) {
                    // Don't draw anything...
                    ctrlpts = new double[0][];
                    types = new int[0];
                } else {
                    int corners = rr.getCornerFlags();
                    int numedges = 5;  // 4xCORNER_POINT, CLOSE
                    for (int i = 1; i < 0x10; i <<= 1) {
                        // Add one for each corner that has a curve
                        if ((corners & i) != 0) numedges++;
                    }
                    ctrlpts = new double[numedges][];
                    types = new int[numedges];
                    int j = 0;
                    for (int i = 0; i < 4; i++) {
                        types[j] = SEG_LINETO;
                        if ((corners & CornerFlags[i]) == 0) {
                            ctrlpts[j++] = CtrlPtTemplate[i*3+0];
                        } else {
                            ctrlpts[j++] = CtrlPtTemplate[i*3+1];
                            types[j] = SEG_CUBICTO;
                            ctrlpts[j++] = CtrlPtTemplate[i*3+2];
                        }
                    }
                    types[j] = SEG_CLOSE;
                    ctrlpts[j++] = CtrlPtTemplate[12];
                    types[0] = SEG_MOVETO;
                }
            }

            public int getWindingRule() {
                return WIND_NON_ZERO;
            }

            public boolean isDone() {
                return index >= ctrlpts.length;
            }

            public void next() {
                index++;
            }

            public int currentSegment(float[] coords) {
                if (isDone()) {
                    throw new NoSuchElementException("roundrect iterator out of bounds");
                }
                double ctrls[] = ctrlpts[index];
                int nc = 0;
                for (int i = 0; i < ctrls.length; i += 4) {
                    coords[nc++] = (float) (x + ctrls[i + 0] * w + ctrls[i + 1] * aw);
                    coords[nc++] = (float) (y + ctrls[i + 2] * h + ctrls[i + 3] * ah);
                }
                if (affine != null) {
                    affine.transform(coords, 0, coords, 0, nc / 2);
                }
                return types[index];
            }

            public int currentSegment(double[] coords) {
                if (isDone()) {
                    throw new NoSuchElementException("roundrect iterator out of bounds");
                }
                double ctrls[] = ctrlpts[index];
                int nc = 0;
                for (int i = 0; i < ctrls.length; i += 4) {
                    coords[nc++] = x + ctrls[i + 0] * w + ctrls[i + 1] * aw;
                    coords[nc++] = y + ctrls[i + 2] * h + ctrls[i + 3] * ah;
                }
                if (affine != null) {
                    affine.transform(coords, 0, coords, 0, nc / 2);
                }
                return types[index];
            }
        }
    }
}
