package iDSS.gView;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import java.awt.image.*;
import java.io.*;

import iDSS.disp.*;
import iDSS.utils.*;



public class AnimationFrame extends DisplayFrame implements ActionListener, ChangeListener, Runnable {



    private Vector imagesVector;
    private javax.swing.Timer fpsTimer;
    private JLabel fpsLabel;
    private JSlider fpsSlider;
    private JButton startButton,pauseButton,stopButton,rewindButton,nextButton,prevButton;
    private int fps_init = 1;

    private Image currentImage;
    private JLabel titleLabel;
    private JLabel imagePanel;
    private String currentTitle;

    private int currentFrame = 0;
    //private final int MINIMUM_IMAGE_SIZE = 300;

    private Thread animThread;

    private boolean started,stopped,paused,rewound;

    public AnimationFrame (String title,Vector images) {

        //super(title,false,true,false,true,null);
        super(title,true,true,true,true,null);

        //rescaleImage(images);
        imagesVector = images;

        if(imagesVector.size() > 0) {

            Vector currentRow = (Vector)imagesVector.elementAt(0);
            File currentImageFile = (File)currentRow.elementAt(0);
            currentImage = getImageFromFile(currentImageFile);

            String s = (String) currentRow.elementAt(1);
            titleLabel = new JLabel("Frame#"+currentFrame+": "+s);


        } //if(imagesVector.size() > 0)


        animThread = new Thread(this);
        animThread.start();


    } //public AnimationFrame (String title,Vector images)





/**
    private void rescaleImage(Vector images) {

        currentFrame = 0;

        if(images.size() > 0) {

            Vector firstRow = (Vector) images.elementAt(currentFrame);
            currentImage = firstRow.elementAt(0);
            String s = (String) firstRow.elementAt(1);
            titleLabel = new JLabel("Frame#"+currentFrame+": "+s);

        }

        else {
            currentImage = new BufferedImage(200,200,BufferedImage.TYPE_INT_RGB);
            titleLabel = new JLabel("Empty image vector");
        }


        if ((currentImage.getWidth() < MINIMUM_IMAGE_SIZE) && (currentImage.getHeight() < MINIMUM_IMAGE_SIZE)) {

            int longSide = Math.max(currentImage.getWidth(),currentImage.getHeight());
            int ratio = MINIMUM_IMAGE_SIZE / longSide;

            imagesVector = new Vector();

            for (int i=0;i<images.size();i++) {

                Vector currentRow = (Vector) images.elementAt(i);
                BufferedImage bi = (BufferedImage) currentRow.elementAt(0);
                String s = (String) currentRow.elementAt(1);

                BufferedImage bi2 = new BufferedImage (bi.getWidth()*ratio,bi.getHeight()*ratio,BufferedImage.TYPE_INT_RGB);
                Graphics g2 = bi2.getGraphics();
                g2.drawImage(bi,0,0,bi2.getWidth(),bi2.getHeight(),
                                                0,0,bi.getWidth(),bi.getHeight(),this);


                Vector newRow = new Vector();
                newRow.add(bi2);
                newRow.add(s);
                imagesVector.add(newRow);

            }

        }

        else {
            imagesVector = images;
        }


        Vector firstRow = (Vector) imagesVector.elementAt(0);
        currentImage = (BufferedImage) firstRow.elementAt(0);


    } //private void rescaleImage(images)

**/



    public void nextImage() {

        if (currentFrame >= (imagesVector.size()-1)) {

            nextButton.setEnabled(false);
            //if(started)
                stopAnimation();
        }

        else {

            Vector currentRow = (Vector) imagesVector.elementAt(++currentFrame);

            //currentImage = (BufferedImage) currentRow.elementAt(0);

            File currentImageFile = (File)currentRow.elementAt(0);
            currentImage = getImageFromFile(currentImageFile);

            currentTitle = (String) currentRow.elementAt(1);
            titleLabel.setText("Frame#"+currentFrame+": "+currentTitle);
            imagePanel.setIcon(new ImageIcon(currentImage));

            if(!started)
                if(currentFrame > 0)
                    prevButton.setEnabled(true);

            if(!started) {

                if(currentFrame >= (imagesVector.size()-1))
                    nextButton.setEnabled(false);

                if(currentFrame >= (imagesVector.size()-1))
                    nextButton.setEnabled(false);

            } //if(!started)

        }

    } //public void nextImage()






    private Image getImageFromFile(File currentImageFile) {


        Toolkit toolkit = Toolkit.getDefaultToolkit();
        Image image = toolkit.getImage(currentImageFile.toString());

        return image;


    } //private Image getImageFromFile(File currentImageFile)








    public void prevImage() {


        if (currentFrame > 0) {

            Vector currentRow = (Vector) imagesVector.elementAt(--currentFrame);

            //currentImage = (BufferedImage) currentRow.elementAt(0);
            File currentImageFile = (File)currentRow.elementAt(0);
            currentImage = getImageFromFile(currentImageFile);

            currentTitle = (String) currentRow.elementAt(1);
            titleLabel.setText("Frame#"+currentFrame+": "+currentTitle);
            imagePanel.setIcon(new ImageIcon(currentImage));
            nextButton.setEnabled(true);

            if (currentFrame == 0) {
                prevButton.setEnabled(false);
                rewindButton.setEnabled(false);
            }

        } //if (currentFrame > 0)

    } //public void prevImage()










    public void actionPerformed(ActionEvent e) {


        if (e.getSource() == fpsTimer) {

            try {
                animThread.sleep(1);
            }
            catch (InterruptedException ie) {
                System.out.println("InterruptedException : " + ie);
            }
            nextImage();

        } //if(e.getSource() == fpsTimer)

        else if (e.getSource() == startButton) {

            startAnimation();

        }

        else if (e.getSource() == pauseButton) {
            pauseAnimation();
        }

        else if (e.getSource() == stopButton) {
            stopAnimation();

        }

        else if (e.getSource() == rewindButton) {
            rewindAnimation();
        }

        else if (e.getSource() == prevButton) {
            prevImage();
        }

        else if (e.getSource() == nextButton) {
            nextImage();
        }


    } //public void actionPerformed(ActionEvent e)






    private void rewindAnimation() {

        currentFrame = 1;
        prevImage();
        startButton.setEnabled(true);
        stopButton.setEnabled(false);
        pauseButton.setEnabled(false);
        rewindButton.setEnabled(false);

        started = false;
        stopped = false;
        rewound = true;

/**
        if(!paused)
            startAnimation();
**/
    } //private void rewindAnimation()





    private void startAnimation() {


        if(stopped)
            rewindAnimation();
        fpsTimer.start();
        startButton.setEnabled(false);
        stopButton.setEnabled(true);
        pauseButton.setEnabled(true);
        rewindButton.setEnabled(false);
        prevButton.setEnabled(false);
        nextButton.setEnabled(false);

        started = true;
        stopped = false;
        paused = false;
        rewound = false;

    } //private void startAnimation()



    private void pauseAnimation() {

        fpsTimer.stop();
        startButton.setEnabled(true);
        stopButton.setEnabled(true);
        pauseButton.setEnabled(false);
        rewindButton.setEnabled(true);
        prevButton.setEnabled(true);
        nextButton.setEnabled(true);

        started = false;
        stopped = false;
        paused = true;
        rewound = false;

    } //private void pauseAnimation()



    private void stopAnimation() {

        currentFrame = 0;
        fpsTimer.stop();
        startButton.setEnabled(true);
        stopButton.setEnabled(false);
        pauseButton.setEnabled(false);
        rewindButton.setEnabled(false);

        rewindAnimation();

        started = false;
        stopped = true;
        paused = false;
        rewound = true;

    } //private void stopAnimation()



    public void stateChanged(ChangeEvent e) {

        JSlider source = (JSlider)e.getSource();
        if (!source.getValueIsAdjusting()) {

            int fps = (int)source.getValue();
            if (fps == 0) {

                if (started) stopAnimation();
                startButton.setEnabled(false);
                stopButton.setEnabled(false);
                pauseButton.setEnabled(false);
                rewindButton.setEnabled(false);
                currentFrame = 0;

            } //if (fps == 0)

            else {

                int delay = 1000 / fps;
                fpsTimer.setDelay(delay);
                if (paused) {
                    startAnimation();
                    startButton.setEnabled(false);
                    stopButton.setEnabled(true);
                    pauseButton.setEnabled(true);
                    rewindButton.setEnabled(true);
                } //if (paused)

                else if (stopped) {
                    startButton.setEnabled(true);
                    stopButton.setEnabled(false);
                    pauseButton.setEnabled(false);
                    rewindButton.setEnabled(false);
                } //else if (stopped)

            } //else

        } //if (!source.getValueIsAdjusting())

    } //public void stateChanged(ChangeEvent e)







    public void run() {

        started = false;
        stopped = true;
        paused = false;
        rewound = true;
        float alignmentX =  (new Double(0.5)).floatValue();

        fpsTimer = new javax.swing.Timer(1000/fps_init,this);
        fpsTimer.setCoalesce(true);
        fpsLabel = new JLabel("Frame per second");
        fpsLabel.setAlignmentX(alignmentX);

        fpsSlider = new JSlider(JSlider.HORIZONTAL,0,24,fps_init);
        fpsSlider.setMajorTickSpacing(6);
        fpsSlider.setMinorTickSpacing(1);
        fpsSlider.setPaintTicks(true);
        fpsSlider.setPaintLabels(true);
        fpsSlider.setBorder(BorderFactory.createEmptyBorder(10,0,10,0));
        fpsSlider.setAlignmentX(alignmentX);
        fpsSlider.addChangeListener(this);

        startButton = new JButton("Start");
        startButton.addActionListener(this);
        startButton.setActionCommand("start");
        startButton.setEnabled(true);

        pauseButton = new JButton("Pause");
        pauseButton.addActionListener(this);
        pauseButton.setActionCommand("pause");
        pauseButton.setEnabled(false);

        stopButton = new JButton("Stop");
        stopButton.addActionListener(this);
        stopButton.setActionCommand("stop");
        stopButton.setEnabled(false);

        rewindButton = new JButton("Rewind");
        rewindButton.addActionListener(this);
        rewindButton.setActionCommand("rewind");
        rewindButton.setEnabled(false);

        nextButton = new JButton("Next>");
        nextButton.addActionListener(this);
        nextButton.setActionCommand("next");
        nextButton.setEnabled(true);

        prevButton = new JButton("<Prev");
        prevButton.addActionListener(this);
        prevButton.setActionCommand("prev");
        prevButton.setEnabled(false);

        titleLabel.setAlignmentX(alignmentX);

        imagePanel = new JLabel(new ImageIcon(currentImage));
        imagePanel.setAlignmentX(alignmentX);
        imagePanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createLoweredBevelBorder(),
                                                                BorderFactory.createEmptyBorder(10,10,10,10)));


        JPanel buttonPanel = new JPanel();
        buttonPanel.setBorder(BorderFactory.createEmptyBorder(10,0,0,0));
        buttonPanel.setAlignmentX(alignmentX);
        buttonPanel.setLayout(new BoxLayout(buttonPanel,BoxLayout.X_AXIS));
        buttonPanel.add(startButton);
        buttonPanel.add(prevButton);
        buttonPanel.add(pauseButton);
        buttonPanel.add(nextButton);
        buttonPanel.add(stopButton);
        buttonPanel.add(rewindButton);

        setBackground(Color.lightGray);
        getContentPane().setLayout(new BoxLayout(getContentPane(),BoxLayout.Y_AXIS));

        getContentPane().add(titleLabel);
        getContentPane().add(imagePanel);
        getContentPane().add(fpsSlider);
        getContentPane().add(fpsLabel);
        getContentPane().add(buttonPanel);

        pack();
        setVisible(true);


    } //public void run()



} //public class AnimationFrame extends DisplayFrame implements ActionListener, Runnable
