/*
 * Copyright (c) 2010, 2011, Oracle and/or its affiliates. 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.
 *
 * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

/*
  @test
  @bug 5089429 6982632
  @summary Checks that we don't crash if rendering operations and state
  changes are performed on a graphics context from different threads.

  @author Dmitri.Trembovetski@sun.com area=Graphics
  @run main MTGraphicsAccessTest
 */

import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;

public class MTGraphicsAccessTest {

    // in seconds
    static final long STANDALONE_RUN_TIME = 20;
    static final long JTREG_RUN_TIME = 7;

    static boolean standaloneMode;
    static boolean allowExceptions = true;
    static long testRunTime;

    volatile boolean done;
    volatile int stillRunning;
    volatile int numexceptions;

    Graphics2D sharedGraphics;
    BufferedImage sharedBI =
            new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB);

    static final Paint colors[] = {
        Color.red,
        new Color(0x7f, 0xff, 0x00, 0x7f),
        new GradientPaint(0,  0, Color.red,
                          50, 50, new Color(0x7f, 0xff, 0x00, 0x7f)),
    };
    static final Font fonts[] = {
        new Font("Dialog", Font.PLAIN, 12),
        new Font("Dialog", Font.BOLD, 16),
        new Font("Dialog", Font.ITALIC, 18),
    };
    static final AlphaComposite comps[] = {
        AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f),
        AlphaComposite.Src,
        AlphaComposite.Xor,
        AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f),
        null,
    };
    static final Stroke strokes[] = {
        new BasicStroke(),
        new BasicStroke(0.0f),
        new BasicStroke(2.0f),
        new BasicStroke(2.0f, BasicStroke.CAP_ROUND,
                        BasicStroke.JOIN_BEVEL),
        new BasicStroke(5.0f, BasicStroke.CAP_SQUARE,
                        BasicStroke.JOIN_ROUND),
        new BasicStroke(0.0f, BasicStroke.CAP_ROUND,
                        BasicStroke.JOIN_ROUND, 0,
                        new float[]{0,6,0,6}, 0),
    };
    static final AffineTransform transforms[] = {
        new AffineTransform(),
        AffineTransform.getRotateInstance(10.0),
        AffineTransform.getShearInstance(10.0, 4.0),
        AffineTransform.getScaleInstance(1.1, 1.2),
        AffineTransform.getScaleInstance(3.0, 2.0),
    };

    public MTGraphicsAccessTest() {
        BufferedImage bi =
            new BufferedImage(50, 50, BufferedImage.TYPE_INT_RGB);
        sharedGraphics = (Graphics2D)bi.getGraphics();

        done = false;
        numexceptions = 0;

        for (int i = 0; i < (standaloneMode ? stateChangers.length : 3); i++) {
            (new TesterThread(stateChangers[i])).start();
        }
        for (int i = 0; i < (standaloneMode ? renderTests.length : 5); i++) {
            (new TesterThread(renderTests[i])).start();
        }

        mysleep(testRunTime);
        done = true;
        while (stillRunning > 0) { mysleep(500); }

        if (numexceptions == 0) {
            System.err.println("Test passed");
        } else if (!allowExceptions) {
            throw new RuntimeException("Test failed with "+
                                       numexceptions+" exceptions");
        } else {
            System.err.println("Test finished with "+
                               numexceptions+" exceptions");
        }
    }

    private void mysleep(long time) {
        try {
            // add +/-5ms variance to increase randomness
            Thread.sleep(time + (long)(5 - Math.random()*10));
        } catch (InterruptedException e) {};
    }

    public static void usage(String message) {
        if (message != null) {
            System.err.println(message);
        }
        System.err.println("Usage: MTGraphicsAccessTest [-full] "+
            "[-time N/forever] [-help]");
        System.err.println(" -full: run full suite of tests "+
            "(default: limited number of tests is run)");
        System.err.println(" -time N: test duration in seconds/forever"+
            " (default: "+JTREG_RUN_TIME+"s for the short suite, "+
            STANDALONE_RUN_TIME+"s for the full suite)");
        System.err.println(" -help: print this help page");
        System.exit(1);
    }

    public static void main(String[] args) {
        boolean testRunSet = false;
        for (int i = 0; i < args.length; i++) {
            if ("-full".equals(args[i])) {
                standaloneMode = true;
                System.err.println("Running complete list of tests");
            } else if ("-noexc".equals(args[i])) {
                allowExceptions = false;
            } else if ("-time".equals(args[i])) {
                try {
                    String time = args[++i];
                    if ("forever".equals(time)) {
                        testRunTime = (Long.MAX_VALUE - 20)/1000;
                    } else {
                        testRunTime = 1000*Integer.parseInt(time);
                    }
                    testRunSet = true;
                } catch (NumberFormatException e) {
                    usage("Can't parse number of seconds: " + args[i]);
                } catch (ArrayIndexOutOfBoundsException e1) {
                    usage("Missing the 'seconds' argument for -time parameter");
                }
            } else if ("-help".equals(args[i])) {
                usage(null);
            } else {
                usage("Unknown argument:" + args[i]);
            }
        }

        if (!testRunSet) {
            testRunTime = 1000 *
                (standaloneMode ? STANDALONE_RUN_TIME : JTREG_RUN_TIME);
        }

        System.err.println("Approximate test run time: "+
             testRunTime/1000+" seconds");

        new MTGraphicsAccessTest();
    }

    class TesterThread extends Thread {
        Runnable testRunnable;

        public TesterThread(Runnable testRunnable) {
            stillRunning++;
            this.testRunnable = testRunnable;
        }

        public void run() {
            try {
                while (!done) {
                    try {
                        testRunnable.run();
                        yield();
                    } catch (Throwable t) {
                        numexceptions++;
                        t.printStackTrace();
                    }
                }
            } finally {
                stillRunning--;
            }
        }
    }

    final Runnable stateChangers[] = {
        new Runnable() {
            public void run() {
                sharedGraphics.setClip(10, 10, 30, 30);
                mysleep(10);
            }
        },
        new Runnable() {
            public void run() {
                sharedGraphics.setClip(10, 10, 30, 30);
                mysleep(10);
            }
        },
        new Runnable() {
            int c = 0;
            public void run() {
                sharedGraphics.setPaint(colors[c++ % colors.length]);
                mysleep(10);
            }
        },
        new Runnable() {
            boolean AA = false;
            public void run() {
                if (AA) {
                    sharedGraphics.setRenderingHint(
                        RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_ON);
                } else {
                    sharedGraphics.setRenderingHint(
                        RenderingHints.KEY_ANTIALIASING,
                        RenderingHints.VALUE_ANTIALIAS_OFF);
                }
                AA = !AA;
                mysleep(10);
            }
        },
        new Runnable() {
            int t = 0;
            public void run() {
                sharedGraphics.setTransform(
                    transforms[t++ % transforms.length]);
                mysleep(10);
            }
        },
        new Runnable() {
            int c = 0;
            public void run() {
                AlphaComposite comp = comps[c++ % comps.length];
                if (comp == null) {
                    sharedGraphics.setXORMode(Color.green);
                } else {
                    sharedGraphics.setComposite(comp);
                }
                mysleep(10);
            }
        },
        new Runnable() {
            int s = 0;
            public void run() {
                sharedGraphics.setStroke(strokes[s++ % strokes.length]);
                mysleep(10);
            }
        },
        new Runnable() {
            int f = 0;
            public void run() {
                sharedGraphics.setFont(fonts[f++ % fonts.length]);
                mysleep(10);
            }
        },
    };

    final Runnable renderTests[] = {
        new Runnable() {
            public void run() {
                sharedGraphics.drawLine(10, 10, 30, 30);
            }
        },
        new Runnable() {
            public void run() {
                sharedGraphics.drawLine(10, 10, 30, 30);
            }
        },
        new Runnable() {
            public void run() {
                sharedGraphics.drawRect(10, 10, 30, 30);
            }
        },
        new Runnable() {
            public void run() {
                sharedGraphics.fillRect(10, 10, 30, 30);
            }
        },
        new Runnable() {
            public void run() {
                sharedGraphics.drawString("Stuff", 10, 10);
            }
        },
        new Runnable() {
            public void run() {
                sharedGraphics.draw3DRect(10, 10, 30, 30, true);
            }
        },
        new Runnable() {
            public void run() {
                sharedGraphics.drawImage(sharedBI, 10, 10, null);
            }
        },
        new Runnable() {
            public void run() {
                sharedGraphics.fill3DRect(10, 10, 30, 30, false);
            }
        },
        // REMIND: copyArea doesn't work when transform is set..
        //          new Runnable() {
        //              public void run() {
        //                  sharedGraphics.copyArea(10, 10, 30, 30, 20, 20);
        //              }
        //          },
        new Runnable() {
            public void run() {
                sharedGraphics.drawRoundRect(10, 10, 30, 30, 20, 20);
            }
        },
        new Runnable() {
            public void run() {
                sharedGraphics.fillRoundRect(10, 10, 30, 30, 20, 20);
            }
        },
        new Runnable() {
            public void run() {
                sharedGraphics.drawArc(10, 10, 30, 30, 0, 90);
            }
        },
        new Runnable() {
            public void run() {
                sharedGraphics.fillArc(10, 10, 30, 30, 0, 90);
            }
        },
        new Runnable() {
            public void run() {
                sharedGraphics.drawOval(10, 10, 30, 30);
            }
        },
        new Runnable() {
            public void run() {
                sharedGraphics.fillOval(10, 10, 30, 30);
            }
        }
    };
}
