/*
 *
 * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Oracle nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package java2d;


import static java.awt.Color.BLACK;
import static java.awt.Color.GRAY;
import static java.awt.Color.RED;
import static java.awt.Color.WHITE;
import static java.awt.Color.YELLOW;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Composite;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Paint;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.TexturePaint;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.FlatteningPathIterator;
import java.awt.geom.GeneralPath;
import java.awt.geom.Line2D;
import java.awt.geom.PathIterator;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JTable;
import javax.swing.border.BevelBorder;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TableModelEvent;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;


/**
 * Introduction to the J2Ddemo.
 *
 * @author Brian Lichtenwalter
 * @author Alexander Kouznetsov
 */
@SuppressWarnings("serial")
public class Intro extends JPanel {

    private static final Color myBlack = new Color(20, 20, 20);
    private static final Color myWhite = new Color(240, 240, 255);
    private static final Color myRed = new Color(149, 43, 42);
    private static final Color myBlue = new Color(94, 105, 176);
    private static final Color myYellow = new Color(255, 255, 140);
    private ScenesTable scenesTable;
    private boolean doTable;
    private final Surface surface;

    public Intro() {
        EmptyBorder eb = new EmptyBorder(80, 110, 80, 110);
        BevelBorder bb = new BevelBorder(BevelBorder.LOWERED);
        setBorder(new CompoundBorder(eb, bb));
        setLayout(new BorderLayout());
        setBackground(GRAY);
        setToolTipText("click for scene table");
        add(surface = new Surface());
        addMouseListener(new MouseAdapter() {

            @Override
            public void mouseClicked(MouseEvent e) {
                removeAll();
                if ((doTable = !doTable)) {
                    setToolTipText("click for animation");
                    surface.stop();
                    if (scenesTable == null) {
                        scenesTable = new ScenesTable(Intro.this);
                    }
                    add(scenesTable);
                } else {
                    setToolTipText("click for scene table");
                    surface.start();
                    add(surface);
                }
                revalidate();
                repaint();
            }
        });
    }

    public void start() {
        if (!doTable) {
            surface.start();
        }
    }

    public void stop() {
        if (!doTable) {
            surface.stop();
        }
    }

    public static void main(String[] argv) {
        final Intro intro = new Intro();
        WindowListener l = new WindowAdapter() {

            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }

            @Override
            public void windowDeiconified(WindowEvent e) {
                intro.start();
            }

            @Override
            public void windowIconified(WindowEvent e) {
                intro.stop();
            }
        };
        JFrame f = new JFrame("Java2D(TM) Demo - Intro");
        f.addWindowListener(l);
        f.getContentPane().add("Center", intro);
        f.pack();
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        int w = 720;
        int h = 510;
        f.setLocation(screenSize.width / 2 - w / 2, screenSize.height / 2 - h
                / 2);
        f.setSize(w, h);
        f.setVisible(true);
        intro.start();
    }


    /**
     * ScenesTable is the list of scenes known to the Director.
     * Scene participation, scene name and scene pause amount columns.
     * Global animation delay for scene's steps.
     */
    static class ScenesTable extends JPanel implements ActionListener,
            ChangeListener {
        private final Intro intro;
        private JTable table;
        private TableModel dataModel;

        @SuppressWarnings("LeakingThisInConstructor")
        public ScenesTable(final Intro intro) {
            this.intro = intro;

            setBackground(WHITE);
            setLayout(new BorderLayout());
            final String[] names = { "", "Scenes", "Pause" };

            dataModel = new AbstractTableModel() {

                @Override
                public int getColumnCount() {
                    return names.length;
                }

                @Override
                public int getRowCount() {
                    return intro.surface.director.size();
                }

                @Override
                public Object getValueAt(int row, int col) {
                    Surface.Scene scene = intro.surface.director.get(row);
                    if (col == 0) {
                        return scene.participate;
                    } else if (col == 1) {
                        return scene.name;
                    } else {
                        return scene.pauseAmt;
                    }
                }

                @Override
                public String getColumnName(int col) {
                    return names[col];
                }

                @Override
                public Class<?> getColumnClass(int c) {
                    return getValueAt(0, c).getClass();
                }

                @Override
                public boolean isCellEditable(int row, int col) {
                    return col != 1 ? true : false;
                }

                @Override
                public void setValueAt(Object aValue, int row, int col) {
                    Surface.Scene scene = intro.surface.director.get(row);
                    if (col == 0) {
                        scene.participate = aValue;
                    } else if (col == 1) {
                        scene.name = aValue;
                    } else {
                        scene.pauseAmt = aValue;
                    }
                }
            };

            table = new JTable(dataModel);
            TableColumn col = table.getColumn("");
            col.setWidth(16);
            col.setMinWidth(16);
            col.setMaxWidth(20);
            col = table.getColumn("Pause");
            col.setWidth(60);
            col.setMinWidth(60);
            col.setMaxWidth(60);
            table.sizeColumnsToFit(0);

            JScrollPane scrollpane = new JScrollPane(table);
            add(scrollpane);

            JPanel panel = new JPanel(new BorderLayout());
            JButton b = new JButton("Unselect All");
            b.setHorizontalAlignment(JButton.LEFT);
            Font font = new Font(Font.SERIF, Font.PLAIN, 10);
            b.setFont(font);
            b.addActionListener(this);
            panel.add("West", b);

            JSlider slider = new JSlider(JSlider.HORIZONTAL, 0, 200,
                    (int) intro.surface.sleepAmt);
            slider.addChangeListener(this);
            TitledBorder tb = new TitledBorder(new EtchedBorder());
            tb.setTitleFont(font);
            tb.setTitle("Anim delay = " + String.valueOf(intro.surface.sleepAmt)
                    + " ms");
            slider.setBorder(tb);
            slider.setPreferredSize(new Dimension(140, 40));
            slider.setMinimumSize(new Dimension(100, 40));
            slider.setMaximumSize(new Dimension(180, 40));
            panel.add("East", slider);

            add("South", panel);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            JButton b = (JButton) e.getSource();
            b.setSelected(!b.isSelected());
            b.setText(b.isSelected() ? "Select All" : "Unselect All");
            for (int i = 0; i < intro.surface.director.size(); i++) {
                Surface.Scene scene = intro.surface.director.get(i);
                scene.participate = Boolean.valueOf(!b.isSelected());
            }
            table.tableChanged(new TableModelEvent(dataModel));
        }

        @Override
        public void stateChanged(ChangeEvent e) {
            JSlider slider = (JSlider) e.getSource();
            int value = slider.getValue();
            TitledBorder tb = (TitledBorder) slider.getBorder();
            tb.setTitle("Anim delay = " + String.valueOf(value) + " ms");
            intro.surface.sleepAmt = (long) value;
            slider.repaint();
        }
    }  // End ScenesTable class


    /**
     * Surface is the stage where the Director plays its scenes.
     */
    static class Surface extends JPanel implements Runnable {

        private final Image dukeanim, duke;
        private BufferedImage bimg;
        public Director director;
        public int index;
        public long sleepAmt = 30;
        private Thread thread;

        @SuppressWarnings("LeakingThisInConstructor")
        public Surface() {
            setBackground(myBlack);
            setLayout(new BorderLayout());
            addMouseListener(new MouseAdapter() {

                @Override
                public void mouseClicked(MouseEvent e) {
                    if (thread == null) {
                        start();
                    } else {
                        stop();
                    }
                }
            });
            dukeanim = DemoImages.getImage("duke.running.gif", this);
            duke = DemoImages.getImage("duke.png", this);
            director = new Director(this);
        }

        public FontMetrics getMetrics(Font font) {
            return getFontMetrics(font);
        }

        @Override
        public void paint(Graphics g) {
            Dimension d = getSize();
            if (d.width <= 0 || d.height <= 0) {
                return;
            }
            if (bimg == null || bimg.getWidth() != d.width || bimg.getHeight()
                    != d.height) {
                bimg = getGraphicsConfiguration().createCompatibleImage(d.width,
                        d.height);
                // reset future scenes
                for (int i = index + 1; i < director.size(); i++) {
                    (director.get(i)).reset(d.width, d.height);
                }
            }

            Scene scene = director.get(index);
            if (scene.index <= scene.length) {
                if (thread != null) {
                    scene.step(d.width, d.height);
                }

                Graphics2D g2 = bimg.createGraphics();
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
                g2.setBackground(getBackground());
                g2.clearRect(0, 0, d.width, d.height);

                scene.render(d.width, d.height, g2);

                if (thread != null) {
                    // increment scene.index after scene.render
                    scene.index++;
                }
                g2.dispose();
            }
            g.drawImage(bimg, 0, 0, this);
        }

        public void start() {
            if (thread == null) {
                thread = new Thread(this);
                thread.setPriority(Thread.MIN_PRIORITY);
                thread.setName("Intro");
                thread.start();
            }
        }

        public synchronized void stop() {
            if (thread != null) {
                thread.interrupt();
            }
            thread = null;
            notifyAll();
        }

        public void reset() {
            index = 0;
            Dimension d = getSize();
            for (Scene scene : director) {
                scene.reset(d.width, d.height);
            }
        }

        @Override
        @SuppressWarnings("SleepWhileHoldingLock")
        public void run() {

            Thread me = Thread.currentThread();

            while (thread == me && !isShowing() || getSize().width <= 0) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    return;
                }
            }

            if (index == 0) {
                reset();
            }

            while (thread == me) {
                Scene scene = director.get(index);
                if (((Boolean) scene.participate).booleanValue()) {
                    repaint();
                    try {
                        Thread.sleep(sleepAmt);
                    } catch (InterruptedException e) {
                        break;
                    }
                    if (scene.index > scene.length) {
                        scene.pause();
                        if (++index >= director.size()) {
                            reset();
                        }
                    }
                } else {
                    if (++index >= director.size()) {
                        reset();
                    }
                }
            }
            thread = null;
        }


        /**
         * Part is a piece of the scene.  Classes must implement Part
         * in order to participate in a scene.
         */
        interface Part {

            public void reset(int newwidth, int newheight);

            public void step(int w, int h);

            public void render(int w, int h, Graphics2D g2);

            public int getBegin();

            public int getEnd();
        }


        /**
         * Director is the holder of the scenes, their names & pause amounts
         * between scenes.
         */
        static class Director extends ArrayList<Scene> {

            GradientPaint gp = new GradientPaint(0, 40, myBlue, 38, 2, myBlack);
            Font f1 = new Font(Font.SERIF, Font.PLAIN, 200);
            Font f2 = new Font(Font.SERIF, Font.PLAIN, 120);
            Font f3 = new Font(Font.SERIF, Font.PLAIN, 72);

            public Director(Surface surf) {
                Object[][][] partsInfo = {
                { { "J  -  scale text on gradient", "0" },
                    { new GpE(GpE.BURI, myBlack, myBlue, 0, 20),
                        new TxE("J", f1, TxE.SCI, myYellow, 2, 20) } },
                { { "2  -  scale & rotate text on gradient", "0" },
                    { new GpE(GpE.BURI, myBlue, myBlack, 0, 22),
                        new TxE("2", f1, TxE.RI | TxE.SCI, myYellow, 2, 22) } },
                { { "D  -  scale text on gradient", "0" },
                    { new GpE(GpE.BURI, myBlack, myBlue, 0, 20),
                        new TxE("D", f1, TxE.SCI, myYellow, 2, 20) } },
                { { "J2D demo  -  scale & rotate text on gradient", "1000" },
                    { new GpE(GpE.SIH, myBlue, myBlack, 0, 40),
                        new TxE("J2D demo", f2, TxE.RI | TxE.SCI, myYellow, 0, 40) } },
                { { "Previous scene dither dissolve out", "0" },
                    { new DdE(0, 20, 1, surf) } },
                { { "Graphics Features", "999" },
                    { new Temp(Temp.RECT, null, 0, 15),
                        new Temp(Temp.IMG, surf.duke, 2, 15),
                        new Temp(Temp.RNA | Temp.INA, surf.duke, 16, 130),
                        new Features(Features.GRAPHICS, 16, 130, surf) } },
                { { "J2D demo  -  texture text on gradient", "1000" },
                    { new GpE(GpE.WI, myBlue, myBlack, 0, 20),
                        new GpE(GpE.WD, myBlue, myBlack, 21, 40),
                        new TpE(TpE.OI | TpE.NF, myBlack, myYellow, 4, 0, 10),
                        new TpE(TpE.OD | TpE.NF, myBlack, myYellow, 4, 11, 20),
                        new TpE(TpE.OI | TpE.NF | TpE.HAF, myBlack, myYellow, 5,
                        21, 40),
                        new TxE("J2D demo", f2, 0, null, 0, 40) } },
                { { "Previous scene random close out", "0" },
                    { new CoE(CoE.RAND, 0, 20, surf) } },
                { { "Text Features", "999" },
                    { new Temp(Temp.RECT, null, 0, 15),
                        new Temp(Temp.IMG, surf.duke, 2, 15),
                        new Temp(Temp.RNA | Temp.INA, surf.duke, 16, 130),
                        new Features(Features.TEXT, 16, 130, surf) } },
                { { "J2D demo  -  composite text on texture", "1000" },
                    { new TpE(TpE.RI, myBlack, gp, 40, 0, 20),
                        new TpE(TpE.RD, myBlack, gp, 40, 21, 40),
                        new TpE(TpE.RI, myBlack, gp, 40, 41, 60),
                        new TxE("J2D demo", f2, TxE.AC, myYellow, 0, 60) } },
                { { "Previous scene dither dissolve out", "0" },
                    { new DdE(0, 20, 4, surf) } },
                { { "Imaging Features", "999" },
                    { new Temp(Temp.RECT, null, 0, 15),
                        new Temp(Temp.IMG, surf.duke, 2, 15),
                        new Temp(Temp.RNA | Temp.INA, surf.duke, 16, 130),
                        new Features(Features.IMAGES, 16, 130, surf) } },
                { { "J2D demo  -  text on gradient", "1000" },
                    { new GpE(GpE.SDH, myBlue, myBlack, 0, 20),
                        new GpE(GpE.SIH, myBlue, myBlack, 21, 40),
                        new GpE(GpE.SDH, myBlue, myBlack, 41, 50),
                        new GpE(GpE.INC | GpE.NF, myRed, myYellow, 0, 50),
                        new TxE("J2D demo", f2, TxE.NOP, null, 0, 50) } },
                { { "Previous scene ellipse close out", "0" },
                    { new CoE(CoE.OVAL, 0, 20, surf) } },
                { { "Color Features", "999" },
                    { new Temp(Temp.RECT, null, 0, 15),
                        new Temp(Temp.IMG, surf.duke, 2, 15),
                        new Temp(Temp.RNA | Temp.INA, surf.duke, 16, 99),
                        new Features(Features.COLOR, 16, 99, surf) } },
                { { "J2D demo  -  composite and rotate text on paints", "2000" },
                    { new GpE(GpE.BURI, myBlack, myBlue, 0, 20),
                        new GpE(GpE.BURD, myBlack, myBlue, 21, 30),
                        new TpE(TpE.OI | TpE.HAF, myBlack, myBlue, 10, 31, 40),
                        new TxE("J2D demo", f2, TxE.AC | TxE.RI, myYellow, 0, 40) } },
                { { "Previous scene subimage transform out", "0" },
                    { new SiE(60, 60, 0, 40, surf) } },
                { { "CREDITS  -  transform in", "1000" },
                    { new LnE(LnE.ACI | LnE.ZOOMI | LnE.RI, 0, 60),
                        new TxE("CREDITS", f3, TxE.AC | TxE.SCI, RED, 20, 30),
                        new TxE("CREDITS", f3, TxE.SCXD, RED, 31, 38),
                        new TxE("CREDITS", f3, TxE.SCXI, RED, 39, 48),
                        new TxE("CREDITS", f3, TxE.SCXD, RED, 49, 54),
                        new TxE("CREDITS", f3, TxE.SCXI, RED, 55, 60) } },
                { { "CREDITS  -  transform out", "0" },
                    { new LnE(LnE.ACD | LnE.ZOOMD | LnE.RD, 0, 45),
                        new TxE("CREDITS", f3, 0, RED, 0, 9),
                        new TxE("CREDITS", f3, TxE.SCD | TxE.RD, RED, 10, 30) } },
                { { "Contributors", "1000" },
                    { new Temp(Temp.RECT, null, 0, 30),
                        new Temp(Temp.IMG, surf.dukeanim, 4, 30),
                        new Temp(Temp.RNA | Temp.INA, surf.dukeanim, 31, 200),
                        new Contributors(34, 200, surf) } }, };

                for (Object[][] partInfo : partsInfo) {
                    List<Part> parts = new ArrayList<Part>();
                    for (Object part : partInfo[1]) {
                        parts.add((Part) part);
                    }
                    add(new Scene(parts, partInfo[0][0], partInfo[0][1]));
                }
            }
        }


        /**
         * Scene is the manager of the parts.
         */
        static class Scene extends Object {

            public Object name;
            public Object participate = Boolean.TRUE;
            public Object pauseAmt;
            public List<Part> parts;
            public int index;
            public int length;

            public Scene(List<Part> parts, Object name, Object pauseAmt) {
                this.name = name;
                this.parts = parts;
                this.pauseAmt = pauseAmt;
                for (Part part : parts) {
                    int partLength = part.getEnd();
                    if (partLength > length) {
                        length = partLength;
                    }
                }
            }

            public void reset(int w, int h) {
                index = 0;
                for (int i = 0; i < parts.size(); i++) {
                    (parts.get(i)).reset(w, h);
                }
            }

            public void step(int w, int h) {
                for (int i = 0; i < parts.size(); i++) {
                    Part part = parts.get(i);
                    if (index >= part.getBegin() && index <= part.getEnd()) {
                        part.step(w, h);
                    }
                }
            }

            public void render(int w, int h, Graphics2D g2) {
                for (int i = 0; i < parts.size(); i++) {
                    Part part = parts.get(i);
                    if (index >= part.getBegin() && index <= part.getEnd()) {
                        part.render(w, h, g2);
                    }
                }
            }

            public void pause() {
                try {
                    Thread.sleep(Long.parseLong((String) pauseAmt));
                } catch (Exception ignored) {
                }
                System.gc();
            }
        } // End Scene class


        /**
         * Text Effect.  Transformation of characters.  Clip or fill.
         */
        static final class TxE implements Part {

            static final int INC = 1;
            static final int DEC = 2;
            static final int R = 4;            // rotate
            static final int RI = R | INC;
            static final int RD = R | DEC;
            static final int SC = 8;            // scale
            static final int SCI = SC | INC;
            static final int SCD = SC | DEC;
            static final int SCX = 16;           // scale invert x
            static final int SCXI = SCX | SC | INC;
            static final int SCXD = SCX | SC | DEC;
            static final int SCY = 32;           // scale invert y
            static final int SCYI = SCY | SC | INC;
            static final int SCYD = SCY | SC | DEC;
            static final int AC = 64;           // AlphaComposite
            static final int CLIP = 128;          // Clipping
            static final int NOP = 512;          // No Paint
            private int beginning, ending;
            private int type;
            private double rIncr, sIncr;
            private double sx, sy, rotate;
            private Shape[] shapes, txShapes;
            private int sw;
            private int numRev;
            private Paint paint;

            public TxE(String text,
                    Font font,
                    int type,
                    Paint paint,
                    int beg,
                    int end) {
                this.type = type;
                this.paint = paint;
                this.beginning = beg;
                this.ending = end;

                setIncrements(2);

                char[] chars = text.toCharArray();
                shapes = new Shape[chars.length];
                txShapes = new Shape[chars.length];
                FontRenderContext frc = new FontRenderContext(null, true, true);
                TextLayout tl = new TextLayout(text, font, frc);
                sw = (int) tl.getOutline(null).getBounds().getWidth();
                for (int j = 0; j < chars.length; j++) {
                    String s = String.valueOf(chars[j]);
                    shapes[j] = new TextLayout(s, font, frc).getOutline(null);
                }
            }

            public void setIncrements(double numRevolutions) {
                this.numRev = (int) numRevolutions;
                rIncr = 360.0 / ((ending - beginning) / numRevolutions);
                sIncr = 1.0 / (ending - beginning);
                if ((type & SCX) != 0 || (type & SCY) != 0) {
                    sIncr *= 2;
                }
                if ((type & DEC) != 0) {
                    rIncr = -rIncr;
                    sIncr = -sIncr;
                }
            }

            @Override
            public void reset(int w, int h) {
                if (type == SCXI) {
                    sx = -1.0;
                    sy = 1.0;
                } else if (type == SCYI) {
                    sx = 1.0;
                    sy = -1.0;
                } else {
                    sx = sy = (type & DEC) != 0 ? 1.0 : 0.0;
                }
                rotate = 0;
            }

            @Override
            public void step(int w, int h) {

                float charWidth = w / 2 - sw / 2;

                for (int i = 0; i < shapes.length; i++) {
                    AffineTransform at = new AffineTransform();
                    Rectangle2D maxBounds = shapes[i].getBounds();
                    at.translate(charWidth, h / 2 + maxBounds.getHeight() / 2);
                    charWidth += (float) maxBounds.getWidth() + 1;
                    Shape shape = at.createTransformedShape(shapes[i]);
                    Rectangle2D b1 = shape.getBounds2D();

                    if ((type & R) != 0) {
                        at.rotate(Math.toRadians(rotate));
                    }
                    if ((type & SC) != 0) {
                        at.scale(sx, sy);
                    }
                    shape = at.createTransformedShape(shapes[i]);
                    Rectangle2D b2 = shape.getBounds2D();

                    double xx = (b1.getX() + b1.getWidth() / 2)
                            - (b2.getX() + b2.getWidth() / 2);
                    double yy = (b1.getY() + b1.getHeight() / 2)
                            - (b2.getY() + b2.getHeight() / 2);
                    AffineTransform toCenterAT = new AffineTransform();
                    toCenterAT.translate(xx, yy);
                    toCenterAT.concatenate(at);
                    txShapes[i] = toCenterAT.createTransformedShape(shapes[i]);
                }
                // avoid over rotation
                if (Math.abs(rotate) <= numRev * 360) {
                    rotate += rIncr;
                    if ((type & SCX) != 0) {
                        sx += sIncr;
                    } else if ((type & SCY) != 0) {
                        sy += sIncr;
                    } else {
                        sx += sIncr;
                        sy += sIncr;
                    }
                }
            }

            @Override
            public void render(int w, int h, Graphics2D g2) {
                Composite saveAC = null;
                if ((type & AC) != 0 && sx > 0 && sx < 1) {
                    saveAC = g2.getComposite();
                    g2.setComposite(AlphaComposite.getInstance(
                            AlphaComposite.SRC_OVER, (float) sx));
                }
                GeneralPath path = null;
                if ((type & CLIP) != 0) {
                    path = new GeneralPath();
                }
                if (paint != null) {
                    g2.setPaint(paint);
                }
                for (int i = 0; i < txShapes.length; i++) {
                    if ((type & CLIP) != 0) {
                        path.append(txShapes[i], false);
                    } else {
                        g2.fill(txShapes[i]);
                    }
                }
                if ((type & CLIP) != 0) {
                    g2.clip(path);
                }
                if (saveAC != null) {
                    g2.setComposite(saveAC);
                }
            }

            @Override
            public int getBegin() {
                return beginning;
            }

            @Override
            public int getEnd() {
                return ending;
            }
        } // End TxE class


        /**
         * GradientPaint Effect.  Burst, split, horizontal and
         * vertical gradient fill effects.
         */
        static class GpE implements Part {

            static final int INC = 1;               // increasing
            static final int DEC = 2;               // decreasing
            static final int CNT = 4;               // center
            static final int WID = 8;               // width
            static final int WI = WID | INC;
            static final int WD = WID | DEC;
            static final int HEI = 16;              // height
            static final int HI = HEI | INC;
            static final int HD = HEI | DEC;
            static final int SPL = 32 | CNT;        // split
            static final int SIW = SPL | INC | WID;
            static final int SDW = SPL | DEC | WID;
            static final int SIH = SPL | INC | HEI;
            static final int SDH = SPL | DEC | HEI;
            static final int BUR = 64 | CNT;        // burst
            static final int BURI = BUR | INC;
            static final int BURD = BUR | DEC;
            static final int NF = 128;             // no fill
            private Color c1, c2;
            private int beginning, ending;
            private float incr, index;
            private List<Rectangle2D> rect = new ArrayList<Rectangle2D>();
            private List<GradientPaint> grad = new ArrayList<GradientPaint>();
            private int type;

            public GpE(int type, Color c1, Color c2, int beg, int end) {
                this.type = type;
                this.c1 = c1;
                this.c2 = c2;
                this.beginning = beg;
                this.ending = end;
            }

            @Override
            public void reset(int w, int h) {
                incr = 1.0f / (ending - beginning);
                if ((type & CNT) != 0) {
                    incr /= 2.3f;
                }
                if ((type & CNT) != 0 && (type & INC) != 0) {
                    index = 0.5f;
                } else if ((type & DEC) != 0) {
                    index = 1.0f;
                    incr = -incr;
                } else {
                    index = 0.0f;
                }
                index += incr;
            }

            @Override
            public void step(int w, int h) {
                rect.clear();
                grad.clear();

                if ((type & WID) != 0) {
                    float w2 = 0, x1 = 0, x2 = 0;
                    if ((type & SPL) != 0) {
                        w2 = w * 0.5f;
                        x1 = w * (1.0f - index);
                        x2 = w * index;
                    } else {
                        w2 = w * index;
                        x1 = x2 = w2;
                    }
                    rect.add(new Rectangle2D.Float(0, 0, w2, h));
                    rect.add(new Rectangle2D.Float(w2, 0, w - w2, h));
                    grad.add(new GradientPaint(0, 0, c1, x1, 0, c2));
                    grad.add(new GradientPaint(x2, 0, c2, w, 0, c1));
                } else if ((type & HEI) != 0) {
                    float h2 = 0, y1 = 0, y2 = 0;
                    if ((type & SPL) != 0) {
                        h2 = h * 0.5f;
                        y1 = h * (1.0f - index);
                        y2 = h * index;
                    } else {
                        h2 = h * index;
                        y1 = y2 = h2;
                    }
                    rect.add(new Rectangle2D.Float(0, 0, w, h2));
                    rect.add(new Rectangle2D.Float(0, h2, w, h - h2));
                    grad.add(new GradientPaint(0, 0, c1, 0, y1, c2));
                    grad.add(new GradientPaint(0, y2, c2, 0, h, c1));
                } else if ((type & BUR) != 0) {

                    float w2 = w / 2;
                    float h2 = h / 2;

                    rect.add(new Rectangle2D.Float(0, 0, w2, h2));
                    rect.add(new Rectangle2D.Float(w2, 0, w2, h2));
                    rect.add(new Rectangle2D.Float(0, h2, w2, h2));
                    rect.add(new Rectangle2D.Float(w2, h2, w2, h2));

                    float x1 = w * (1.0f - index);
                    float x2 = w * index;
                    float y1 = h * (1.0f - index);
                    float y2 = h * index;

                    grad.add(new GradientPaint(0, 0, c1, x1, y1, c2));
                    grad.add(new GradientPaint(w, 0, c1, x2, y1, c2));
                    grad.add(new GradientPaint(0, h, c1, x1, y2, c2));
                    grad.add(new GradientPaint(w, h, c1, x2, y2, c2));
                } else if ((type & NF) != 0) {
                    float y = h * index;
                    grad.add(new GradientPaint(0, 0, c1, 0, y, c2));
                }

                if ((type & INC) != 0 || (type & DEC) != 0) {
                    index += incr;
                }
            }

            @Override
            public void render(int w, int h, Graphics2D g2) {
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_OFF);
                for (int i = 0; i < grad.size(); i++) {
                    g2.setPaint(grad.get(i));
                    if ((type & NF) == 0) {
                        g2.fill(rect.get(i));
                    }
                }
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
            }

            @Override
            public int getBegin() {
                return beginning;
            }

            @Override
            public int getEnd() {
                return ending;
            }
        } // End GpE class


        /**
         * TexturePaint Effect.  Expand and collapse a texture.
         */
        static final class TpE implements Part {

            static final int INC = 1;             // increasing
            static final int DEC = 2;             // decreasing
            static final int OVAL = 4;             // oval
            static final int RECT = 8;             // rectangle
            static final int HAF = 16;             // half oval or rect size
            static final int NF = 32;             // no fill
            static final int OI = OVAL | INC;
            static final int OD = OVAL | DEC;
            static final int RI = RECT | INC;
            static final int RD = RECT | DEC;
            private Paint p1, p2;
            private int beginning, ending;
            private float incr, index;
            private TexturePaint texture;
            private int type;
            private int size;
            private BufferedImage bimg;
            private Rectangle rect;

            public TpE(int type, Paint p1, Paint p2, int size,
                    int beg, int end) {
                this.type = type;
                this.p1 = p1;
                this.p2 = p2;
                this.beginning = beg;
                this.ending = end;
                setTextureSize(size);
            }

            public void setTextureSize(int size) {
                this.size = size;
                bimg = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
                rect = new Rectangle(0, 0, size, size);
            }

            @Override
            public void reset(int w, int h) {
                incr = (float) (size) / (float) (ending - beginning);
                if ((type & HAF) != 0) {
                    incr /= 2;
                }
                if ((type & DEC) != 0) {
                    index = size;
                    if ((type & HAF) != 0) {
                        index /= 2;
                    }
                    incr = -incr;
                } else {
                    index = 0.0f;
                }
                index += incr;
            }

            @Override
            public void step(int w, int h) {
                Graphics2D g2 = bimg.createGraphics();
                g2.setPaint(p1);
                g2.fillRect(0, 0, size, size);
                g2.setPaint(p2);
                if ((type & OVAL) != 0) {
                    g2.fill(new Ellipse2D.Float(0, 0, index, index));
                } else if ((type & RECT) != 0) {
                    g2.fill(new Rectangle2D.Float(0, 0, index, index));
                }
                texture = new TexturePaint(bimg, rect);
                g2.dispose();
                index += incr;
            }

            @Override
            public void render(int w, int h, Graphics2D g2) {
                g2.setPaint(texture);
                if ((type & NF) == 0) {
                    g2.fillRect(0, 0, w, h);
                }
            }

            @Override
            public int getBegin() {
                return beginning;
            }

            @Override
            public int getEnd() {
                return ending;
            }
        } // End TpE class


        /**
         * Close out effect.  Close out the buffered image with different
         * geometry shapes.
         */
        static class CoE implements Part {
            private final Surface surf;
            static final int WID = 1;
            static final int HEI = 2;
            static final int OVAL = 4;
            static final int RECT = 8;
            static final int RAND = 16;
            static final int ARC = 32;
            private int type;
            private int beginning, ending;
            private BufferedImage bimg;
            private Shape shape;
            private double zoom, extent;
            private double zIncr, eIncr;
            private boolean doRandom;

            public CoE(int type, int beg, int end, Surface surf) {
                this.type = type;
                this.beginning = beg;
                this.ending = end;
                this.surf = surf;
                zIncr = -(2.0 / (ending - beginning));
                eIncr = 360.0 / (ending - beginning);
                doRandom = (type & RAND) != 0;
            }

            @Override
            public void reset(int w, int h) {
                if (doRandom) {
                    int num = (int) (Math.random() * 5.0);
                    switch (num) {
                        case 0:
                            type = OVAL;
                            break;
                        case 1:
                            type = RECT;
                            break;
                        case 2:
                            type = RECT | WID;
                            break;
                        case 3:
                            type = RECT | HEI;
                            break;
                        case 4:
                            type = ARC;
                            break;
                        default:
                            type = OVAL;
                    }
                }
                shape = null;
                bimg = null;
                extent = 360.0;
                zoom = 2.0;
            }

            @Override
            public void step(int w, int h) {
                if (bimg == null) {
                    int biw = surf.bimg.getWidth();
                    int bih = surf.bimg.getHeight();
                    bimg = new BufferedImage(biw, bih,
                            BufferedImage.TYPE_INT_RGB);
                    Graphics2D big = bimg.createGraphics();
                    big.drawImage(surf.bimg, 0, 0, null);
                }
                double z = Math.min(w, h) * zoom;
                if ((type & OVAL) != 0) {
                    shape = new Ellipse2D.Double(w / 2 - z / 2, h / 2 - z / 2, z,
                            z);
                } else if ((type & ARC) != 0) {
                    shape = new Arc2D.Double(-100, -100, w + 200, h + 200, 90,
                            extent, Arc2D.PIE);
                    extent -= eIncr;
                } else if ((type & RECT) != 0) {
                    if ((type & WID) != 0) {
                        shape = new Rectangle2D.Double(w / 2 - z / 2, 0, z, h);
                    } else if ((type & HEI) != 0) {
                        shape = new Rectangle2D.Double(0, h / 2 - z / 2, w, z);
                    } else {
                        shape = new Rectangle2D.Double(w / 2 - z / 2, h / 2 - z
                                / 2, z, z);
                    }
                }
                zoom += zIncr;
            }

            @Override
            public void render(int w, int h, Graphics2D g2) {
                g2.clip(shape);
                g2.drawImage(bimg, 0, 0, null);
            }

            @Override
            public int getBegin() {
                return beginning;
            }

            @Override
            public int getEnd() {
                return ending;
            }
        } // End CoE class


        /**
         * Dither Dissolve Effect. For each successive step in the animation,
         * a pseudo-random starting horizontal position is chosen using list,
         * and then the corresponding points created from xlist and ylist are
         * blacked out for the current "chunk".  The x and y chunk starting
         * positions are each incremented by the associated chunk size, and
         * this process is repeated for the number of "steps" in the
         * animation, causing an equal number of pseudo-randomly picked
         * "blocks" to be blacked out during each step of the animation.
         */
        static class DdE implements Part {
            private final Surface surf;
            private int beginning, ending;
            private BufferedImage bimg;
            private Graphics2D big;
            private List<Integer> list, xlist, ylist;
            private int xeNum, yeNum;    // element number
            private int xcSize, ycSize;  // chunk size
            private int inc;
            private int blocksize;

            public DdE(int beg, int end, int blocksize, Surface surf) {
                this.beginning = beg;
                this.ending = end;
                this.blocksize = blocksize;
                this.surf = surf;
            }

            private void createShuffledLists() {
                int width = bimg.getWidth();
                int height = bimg.getHeight();
                xlist = new ArrayList<Integer>(width);
                ylist = new ArrayList<Integer>(height);
                list = new ArrayList<Integer>(ending - beginning + 1);
                for (int i = 0; i < width; i++) {
                    xlist.add(i, i);
                }
                for (int i = 0; i < height; i++) {
                    ylist.add(i, i);
                }
                for (int i = 0; i < (ending - beginning + 1); i++) {
                    list.add(i, i);
                }
                java.util.Collections.shuffle(xlist);
                java.util.Collections.shuffle(ylist);
                java.util.Collections.shuffle(list);
            }

            @Override
            public void reset(int w, int h) {
                bimg = null;
            }

            @Override
            public void step(int w, int h) {
                if (inc > ending) {
                    bimg = null;
                }
                if (bimg == null) {
                    int biw = surf.bimg.getWidth();
                    int bih = surf.bimg.getHeight();
                    bimg = new BufferedImage(biw, bih,
                            BufferedImage.TYPE_INT_RGB);
                    createShuffledLists();
                    big = bimg.createGraphics();
                    big.drawImage(surf.bimg, 0, 0, null);
                    xcSize = (xlist.size() / (ending - beginning)) + 1;
                    ycSize = (ylist.size() / (ending - beginning)) + 1;
                    xeNum = 0;
                    inc = 0;
                }
                xeNum = xcSize * (list.get(inc)).intValue();
                yeNum = -ycSize;
                inc++;
            }

            @Override
            public void render(int w, int h, Graphics2D g2) {
                big.setColor(myBlack);

                for (int k = 0; k <= (ending - beginning); k++) {
                    if ((xeNum + xcSize) > xlist.size()) {
                        xeNum = 0;
                    } else {
                        xeNum += xcSize;
                    }
                    yeNum += ycSize;

                    for (int i = xeNum; i < xeNum + xcSize && i < xlist.size();
                            i++) {
                        for (int j = yeNum; j < yeNum + ycSize && j
                                < ylist.size(); j++) {
                            int xval = (xlist.get(i)).intValue();
                            int yval = (ylist.get(j)).intValue();
                            if (((xval % blocksize) == 0) && ((yval % blocksize)
                                    == 0)) {
                                big.fillRect(xval, yval, blocksize, blocksize);
                            }
                        }
                    }
                }

                g2.drawImage(bimg, 0, 0, null);
            }

            @Override
            public int getBegin() {
                return beginning;
            }

            @Override
            public int getEnd() {
                return ending;
            }
        } // End DdE class


        /**
         * Subimage effect.  Subimage the scene's buffered
         * image then rotate and scale down the subimages.
         */
        static class SiE implements Part {
            private final Surface surf;
            private int beginning, ending;
            private BufferedImage bimg;
            private double rIncr, sIncr;
            private double scale, rotate;
            private int siw, sih;
            private List<BufferedImage> subs = new ArrayList<BufferedImage>(20);
            private List<Point> pts = new ArrayList<Point>(20);

            public SiE(int siw, int sih, int beg, int end, Surface surf) {
                this.siw = siw;
                this.sih = sih;
                this.beginning = beg;
                this.ending = end;
                this.surf = surf;
                rIncr = 360.0 / (ending - beginning);
                sIncr = 1.0 / (ending - beginning);
            }

            @Override
            public void reset(int w, int h) {
                scale = 1.0;
                rotate = 0.0;
                bimg = null;
                subs.clear();
                pts.clear();
            }

            @Override
            public void step(int w, int h) {
                if (bimg == null) {
                    int biw = surf.bimg.getWidth();
                    int bih = surf.bimg.getHeight();
                    bimg = new BufferedImage(biw, bih,
                            BufferedImage.TYPE_INT_RGB);
                    Graphics2D big = bimg.createGraphics();
                    big.drawImage(surf.bimg, 0, 0, null);
                    for (int x = 0; x < w && scale > 0.0; x += siw) {
                        int ww = x + siw < w ? siw : w - x;
                        for (int y = 0; y < h; y += sih) {
                            int hh = y + sih < h ? sih : h - y;
                            subs.add(bimg.getSubimage(x, y, ww, hh));
                            pts.add(new Point(x, y));
                        }
                    }
                }

                rotate += rIncr;
                scale -= sIncr;
            }

            @Override
            public void render(int w, int h, Graphics2D g2) {
                AffineTransform saveTx = g2.getTransform();
                g2.setColor(myBlue);
                for (int i = 0; i < subs.size() && scale > 0.0; i++) {
                    BufferedImage bi = subs.get(i);
                    Point p = pts.get(i);
                    int ww = bi.getWidth();
                    int hh = bi.getHeight();
                    AffineTransform at = new AffineTransform();
                    at.rotate(Math.toRadians(rotate), p.x + ww / 2, p.y + hh / 2);
                    at.translate(p.x, p.y);
                    at.scale(scale, scale);

                    Rectangle b1 = new Rectangle(0, 0, ww, hh);
                    Shape shape = at.createTransformedShape(b1);
                    Rectangle2D b2 = shape.getBounds2D();
                    double xx = (p.x + ww / 2) - (b2.getX() + b2.getWidth() / 2);
                    double yy = (p.y + hh / 2)
                            - (b2.getY() + b2.getHeight() / 2);
                    AffineTransform toCenterAT = new AffineTransform();
                    toCenterAT.translate(xx, yy);
                    toCenterAT.concatenate(at);

                    g2.setTransform(toCenterAT);
                    g2.drawImage(bi, 0, 0, null);
                    g2.draw(b1);
                }
                g2.setTransform(saveTx);
            }

            @Override
            public int getBegin() {
                return beginning;
            }

            @Override
            public int getEnd() {
                return ending;
            }
        } // End SiE class


        /**
         * Line Effect.  Flattened ellipse with lines from the center
         * to the edge.  Expand or collapse the ellipse.  Fade in or out
         * the lines.
         */
        static class LnE implements Part {

            static final int INC = 1;
            static final int DEC = 2;
            static final int R = 4;             // rotate
            static final int ZOOM = 8;             // zoom
            static final int AC = 32;             // AlphaComposite
            static final int RI = R | INC;
            static final int RD = R | DEC;
            static final int ZOOMI = ZOOM | INC;
            static final int ZOOMD = ZOOM | DEC;
            static final int ACI = AC | INC;
            static final int ACD = AC | DEC;
            private int beginning, ending;
            private double rIncr, rotate;
            private double zIncr, zoom;
            private List<Point2D.Double> pts = new ArrayList<Point2D.Double>();
            private float alpha, aIncr;
            private int type;

            public LnE(int type, int beg, int end) {
                this.type = type;
                this.beginning = beg;
                this.ending = end;
                float range = ending - beginning;
                rIncr = 360.0f / range;
                aIncr = 0.9f / range;
                zIncr = 2.0f / range;
                if ((type & DEC) != 0) {
                    rIncr = -rIncr;
                    aIncr = -aIncr;
                    zIncr = -zIncr;
                }
            }

            public void generatePts(int w, int h, double sizeF) {
                pts.clear();
                double size = Math.min(w, h) * sizeF;
                Ellipse2D ellipse = new Ellipse2D.Double(w / 2 - size / 2, h / 2 - size
                        / 2, size, size);
                PathIterator pi = ellipse.getPathIterator(null, 0.8);
                while (!pi.isDone()) {
                    double[] pt = new double[6];
                    switch (pi.currentSegment(pt)) {
                        case FlatteningPathIterator.SEG_MOVETO:
                        case FlatteningPathIterator.SEG_LINETO:
                            pts.add(new Point2D.Double(pt[0], pt[1]));
                    }
                    pi.next();
                }
            }

            @Override
            public void reset(int w, int h) {
                if ((type & DEC) != 0) {
                    rotate = 360;
                    alpha = 1.0f;
                    zoom = 2.0;
                } else {
                    rotate = alpha = 0;
                    zoom = 0;
                }
                if ((type & ZOOM) == 0) {
                    generatePts(w, h, 0.5);
                }
            }

            @Override
            public void step(int w, int h) {
                if ((type & ZOOM) != 0) {
                    generatePts(w, h, zoom += zIncr);
                }
                if ((type & RI) != 0 || (type & RI) != 0) {
                    rotate += rIncr;
                }
                if ((type & ACI) != 0 || (type & ACD) != 0) {
                    alpha += aIncr;
                }
            }

            @Override
            public void render(int w, int h, Graphics2D g2) {
                Composite saveAC = null;
                if ((type & AC) != 0 && alpha >= 0 && alpha <= 1) {
                    saveAC = g2.getComposite();
                    g2.setComposite(AlphaComposite.getInstance(
                            AlphaComposite.SRC_OVER, alpha));
                }
                AffineTransform saveTx = null;
                if ((type & R) != 0) {
                    saveTx = g2.getTransform();
                    AffineTransform at = new AffineTransform();
                    at.rotate(Math.toRadians(rotate), w / 2, h / 2);
                    g2.setTransform(at);
                }
                Point2D p1 = new Point2D.Double(w / 2, h / 2);
                g2.setColor(YELLOW);
                for (Point2D pt : pts) {
                    g2.draw(new Line2D.Float(p1, pt));
                }
                if (saveTx != null) {
                    g2.setTransform(saveTx);
                }
                if (saveAC != null) {
                    g2.setComposite(saveAC);
                }
            }

            @Override
            public int getBegin() {
                return beginning;
            }

            @Override
            public int getEnd() {
                return ending;
            }
        } // End LnE class


        /**
         * Template for Features & Contributors consisting of translating
         * blue and red rectangles and an image going from transparent to
         * opaque.
         */
        static class Temp implements Part {

            static final int NOANIM = 1;
            static final int RECT = 2;
            static final int IMG = 4;
            static final int RNA = RECT | NOANIM;
            static final int INA = IMG | NOANIM;
            private int beginning, ending;
            private float alpha, aIncr;
            private int type;
            private Rectangle rect1, rect2;
            private int x, y, xIncr, yIncr;
            private Image img;

            public Temp(int type, Image img, int beg, int end) {
                this.type = type;
                this.img = img;
                this.beginning = beg;
                this.ending = end;
                aIncr = 0.9f / (ending - beginning);
                if ((type & NOANIM) != 0) {
                    alpha = 1.0f;
                }
            }

            @Override
            public void reset(int w, int h) {
                rect1 = new Rectangle(8, 20, w - 20, 30);
                rect2 = new Rectangle(20, 8, 30, h - 20);
                if ((type & NOANIM) == 0) {
                    alpha = 0.0f;
                    xIncr = w / (ending - beginning);
                    yIncr = h / (ending - beginning);
                    x = w + (int) (xIncr * 1.4);
                    y = h + (int) (yIncr * 1.4);
                }
            }

            @Override
            public void step(int w, int h) {
                if ((type & NOANIM) != 0) {
                    return;
                }
                if ((type & RECT) != 0) {
                    rect1.setLocation(x -= xIncr, 20);
                    rect2.setLocation(20, y -= yIncr);
                }
                if ((type & IMG) != 0) {
                    alpha += aIncr;
                }
            }

            @Override
            public void render(int w, int h, Graphics2D g2) {
                if ((type & RECT) != 0) {
                    g2.setColor(myBlue);
                    g2.fill(rect1);
                    g2.setColor(myRed);
                    g2.fill(rect2);
                }
                if ((type & IMG) != 0) {
                    Composite saveAC = g2.getComposite();
                    if (alpha >= 0 && alpha <= 1) {
                        g2.setComposite(AlphaComposite.getInstance(
                                AlphaComposite.SRC_OVER, alpha));
                    }
                    g2.drawImage(img, 30, 30, null);
                    g2.setComposite(saveAC);
                }
            }

            @Override
            public int getBegin() {
                return beginning;
            }

            @Override
            public int getEnd() {
                return ending;
            }
        } // End Temp class


        /**
         * Features of Java2D(TM).  Single character advancement effect.
         */
        static class Features implements Part {

            static final int GRAPHICS = 0;
            static final int TEXT = 1;
            static final int IMAGES = 2;
            static final int COLOR = 3;
            static final Font font1 = new Font(Font.SERIF, Font.BOLD, 38);
            static final Font font2 = new Font(Font.SERIF, Font.PLAIN, 24);
            private final FontMetrics fm1;
            private final FontMetrics fm2;
            private static final String[][] table = { { "Graphics", "Antialiased rendering",
                    "Bezier paths",
                    "Transforms", "Compositing", "Stroking parameters" },
                { "Text", "Extended font support",
                    "Advanced text layout", "Dynamic font loading",
                    "AttributeSets for font customization" },
                { "Images", "Flexible image layouts",
                    "Extended imaging operations",
                    "   Convolutions, Lookup Tables",
                    "RenderableImage interface" },
                { "Color", "ICC profile support", "Color conversion",
                    "Arbitrary color spaces" } };
            private String[] list;
            private int beginning, ending;
            private int strH;
            private int endIndex, listIndex;
            private List<String> v = new ArrayList<String>();

            public Features(int type, int beg, int end, Surface surf) {
                list = table[type];
                this.beginning = beg;
                this.ending = end;
                fm1 = surf.getMetrics(font1);
                fm2 = surf.getMetrics(font2);
            }

            @Override
            public void reset(int w, int h) {
                strH = (fm2.getAscent() + fm2.getDescent());
                endIndex = 1;
                listIndex = 0;
                v.clear();
                v.add(list[listIndex].substring(0, endIndex));
            }

            @Override
            public void step(int w, int h) {
                if (listIndex < list.length) {
                    if (++endIndex > list[listIndex].length()) {
                        if (++listIndex < list.length) {
                            endIndex = 1;
                            v.add(list[listIndex].substring(0, endIndex));
                        }
                    } else {
                        v.set(listIndex, list[listIndex].substring(0, endIndex));
                    }
                }
            }

            @Override
            public void render(int w, int h, Graphics2D g2) {
                g2.setColor(myWhite);
                g2.setFont(font1);
                g2.drawString(v.get(0), 90, 85);
                g2.setFont(font2);
                for (int i = 1, y = 90; i < v.size(); i++) {
                    g2.drawString(v.get(i), 120, y += strH);
                }
            }

            @Override
            public int getBegin() {
                return beginning;
            }

            @Override
            public int getEnd() {
                return ending;
            }
        } // End Features class


        /**
         * Scrolling text of Java2D(TM) contributors.
         */
        static class Contributors implements Part {

            private static final String[] members = {
                "Brian Lichtenwalter", "Jeannette Hung",
                "Thanh Nguyen", "Jim Graham", "Jerry Evans",
                "John Raley", "Michael Peirce", "Robert Kim",
                "Jennifer Ball", "Deborah Adair", "Paul Charlton",
                "Dmitry Feld", "Gregory Stone", "Richard Blanchard",
                "Link Perry", "Phil Race", "Vincent Hardy",
                "Parry Kejriwal", "Doug Felt", "Rekha Rangarajan",
                "Paula Patel", "Michael Bundschuh", "Joe Warzecha",
                "Joey Beheler", "Aastha Bhardwaj", "Daniel Rice",
                "Chris Campbell", "Shinsuke Fukuda", "Dmitri Trembovetski",
                "Chet Haase", "Jennifer Godinez", "Nicholas Talian",
                "Raul Vera", "Ankit Patel", "Ilya Bagrak",
                "Praveen Mohan", "Rakesh Menon"
            };
            private static final Font font = new Font(Font.SERIF, Font.PLAIN, 26);
            private final FontMetrics fm;
            private int beginning, ending;
            private int nStrs, strH, index, yh, height;
            private List<String> v = new ArrayList<String>();
            private List<String> cast =
                    new ArrayList<String>(members.length + 3);
            private int counter, cntMod;
            private GradientPaint gp;

            public Contributors(int beg, int end, Surface surf) {
                this.beginning = beg;
                this.ending = end;
                fm = surf.getMetrics(font);
                Arrays.sort(members);
                cast.add("CONTRIBUTORS");
                cast.add(" ");
                cast.addAll(Arrays.asList(members));
                cast.add(" ");
                cast.add(" ");
                cntMod = (ending - beginning) / cast.size() - 1;
            }

            @Override
            public void reset(int w, int h) {
                v.clear();
                strH = (fm.getAscent() + fm.getDescent());
                nStrs = (h - 40) / strH + 1;
                height = strH * (nStrs - 1) + 48;
                index = 0;
                gp = new GradientPaint(0, h / 2, WHITE, 0, h + 20, BLACK);
                counter = 0;
            }

            @Override
            public void step(int w, int h) {
                if (counter++ % cntMod == 0) {
                    if (index < cast.size()) {
                        v.add(cast.get(index));
                    }
                    if ((v.size() == nStrs || index >= cast.size()) && !v.
                            isEmpty()) {
                        v.remove(0);
                    }
                    ++index;
                }
            }

            @Override
            public void render(int w, int h, Graphics2D g2) {
                g2.setPaint(gp);
                g2.setFont(font);
                double remainder = counter % cntMod;
                double incr = 1.0 - remainder / cntMod;
                incr = incr == 1.0 ? 0 : incr;
                int y = (int) (incr * strH);

                if (index >= cast.size()) {
                    y = yh + y;
                } else {
                    y = yh = height - v.size() * strH + y;
                }
                for (String s : v) {
                    g2.drawString(s, w / 2 - fm.stringWidth(s) / 2, y += strH);
                }
            }

            @Override
            public int getBegin() {
                return beginning;
            }

            @Override
            public int getEnd() {
                return ending;
            }
        } // End Contributors class
    } // End Surface class
} // End Intro class

