import java.awt.*;
import java.awt.geom.AffineTransform;
import javax.swing.ImageIcon;
import javax.swing.JFrame;

public class ImageSpeedTest2 extends JFrame {

    public static void main(String args[]) {

        DisplayMode displayMode;

        if (args.length == 3) {
            displayMode = new DisplayMode(
                Integer.parseInt(args[0]),
                Integer.parseInt(args[1]),
                Integer.parseInt(args[2]),
                DisplayMode.REFRESH_RATE_UNKNOWN);
        }
        else {
            displayMode = new DisplayMode(800, 600, 16,
                DisplayMode.REFRESH_RATE_UNKNOWN);
        }

        ImageSpeedTest2 test = new ImageSpeedTest2();
        test.run(displayMode);
    }

    private static final int FONT_SIZE = 24;
    private static final long TIME_PER_IMAGE = 1500;

    private SimpleScreenManager screen;
    private Image bgImage;
    private Image opaqueImage;
    private Image transparentImage;
    private Image translucentImage;
    private Image antiAliasedImage;
    private boolean imagesLoaded;

    public void run(DisplayMode displayMode) {
        setBackground(Color.blue);
        setForeground(Color.white);
        setFont(new Font("Dialog", Font.PLAIN, FONT_SIZE));
        imagesLoaded = false;

        screen = new SimpleScreenManager();
        try {
            screen.setFullScreen(displayMode, this);
            synchronized (this) {
                loadImages();
                // oczekiwanie na zakończenie testu
                try {
                    wait();
                }
                catch (InterruptedException ex) { }
            }
        }
        finally {
            screen.restoreScreen();
        }
    }


    public void loadImages() {
        bgImage = loadImage("images/background.jpg");
        opaqueImage = loadImage("images/opaque.png");
        transparentImage = loadImage("images/transparent.png");
        translucentImage = loadImage("images/translucent.png");
        antiAliasedImage = loadImage("images/antialiased.png");
        imagesLoaded = true;
        // sygnał do AWT pozwalający na przerysowanie tego okna
        repaint();
    }


    private final Image loadImage(String fileName) {
        return new ImageIcon(fileName).getImage();
    }


    public void paint(Graphics g) {
        // ustawienie antyaliasingu tekstu
        if (g instanceof Graphics2D) {
            Graphics2D g2 = (Graphics2D)g;
            g2.setRenderingHint(
                RenderingHints.KEY_TEXT_ANTIALIASING,
                RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        }

        // rysowanie
        if (imagesLoaded) {
            drawImage(g, opaqueImage, "Nieprzezroczysty", false);
            drawImage(g, transparentImage, "Przezroczysty", false);
            drawImage(g, translucentImage, "Przeświecający", false);
            drawImage(g, antiAliasedImage,
              "Przeświecający (Antyaliasing)", false);

            drawImage(g, opaqueImage, "Nieprzezroczysty (Odbijanie)", true);
            drawImage(g, transparentImage,
                "Przezroczysty (Odbijanie)", true);
            drawImage(g, translucentImage,
                "Przeświecający (Odbijanie)", true);
            drawImage(g, antiAliasedImage,
              "Przeświecający (Antyaliasing, Odbijanie)", true);

            // powiadomienie o zakończeniu testu
            synchronized (this) {
                notify();
            }
        }
        else {
            g.drawString("Ładowanie rysunków...", 5, FONT_SIZE);
        }
    }


    public void drawImage(Graphics g1, Image image, String name,
        boolean flip)
    {
        Graphics2D g = (Graphics2D)g1;
        AffineTransform transform = new AffineTransform();
        int width = screen.getFullScreenWindow().getWidth() -
            image.getWidth(null);
        int height = screen.getFullScreenWindow().getHeight() -
            image.getHeight(null);
        int numImages = 0;

        g.drawImage(bgImage, 0, 0, null);

        long startTime = System.currentTimeMillis();
        while (System.currentTimeMillis() - startTime
            < TIME_PER_IMAGE)
        {
            int x = Math.round((float)Math.random() * width);
            int y = Math.round((float)Math.random() * height);
            transform.setToTranslation(x, y);

            // jeżeli duszek przesuwa się w lewo, odbij rysunek 
            if (flip) {
                transform.scale(-1, 1);
                transform.translate(-image.getWidth(null), 0);
            }

            // narysuj go
            g.drawImage(image, transform, null);
            numImages++;
        }
        long time = System.currentTimeMillis() - startTime;
        float speed = numImages * 1000f / time;
        System.out.println(name + ": " + speed + " rysunki/s");
    }
}
