import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

class ParticlePanel extends Canvas implements Runnable
{
    public Thread gameThread;
    Image offScreenBuffer;
    Graphics offGraphics;
    Graphics2D offGraphics2D;

    ParticleSystem system;


    public ParticlePanel()
    {	
        system = new ParticleSystem();
	gameThread = new Thread(this, "Particle");
	createGUI();
	gameThread.start(); 
    }


    public void update(Graphics g)
    {
	paint(g);
    }

    public void paint(Graphics g)
    {
	Dimension dim = this.getSize();

	if (offScreenBuffer==null ||
                (! (offScreenBuffer.getWidth(this) == dim.width
                && offScreenBuffer.getHeight(this) == dim.height)))
	    {
		offScreenBuffer = this.createImage(dim.width, dim.height);
		offGraphics = offScreenBuffer.getGraphics();
		offGraphics2D = (Graphics2D)offGraphics;
	    }


        offGraphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);       
	offGraphics2D.setColor(Color.black);
	offGraphics2D.fillRect(0,0,dim.width,dim.height);

	system.paint(offGraphics2D);

	g.drawImage(offScreenBuffer,0,0,this);	
    }


    public void init()
    {

    }

    private void createGUI()
    {


	addMouseListener(new ShuffleListener(system));



	//       setBounds(0,0,450,450);       
	setVisible(true);
    }

    public static JPanel getControls(ParticleSystem system)
    {
	JPanel bpanel = new JPanel(new FlowLayout());
	JButton button1 = new JButton("Null");
	button1.addActionListener(new StrategyListener(system, new NullStrategy()));	
	bpanel.add(button1);


	JButton button2 = new JButton("Clump");
	button2.addActionListener(new StrategyListener(system, new ClumpStrategy()));	
	bpanel.add(button2);

 
	JButton button3 = new JButton("Flower");
	button3.addActionListener(new StrategyListener(system, new FlowerStrategy()));	
	bpanel.add(button3);



	JButton button4 = new JButton("Chase");
	button4.addActionListener(new StrategyListener(system, new ChaseStrategy()));	
	bpanel.add(button4);
	
	return bpanel;
    }
    public static void main(String args[])
    {

	ParticlePanel peli = new ParticlePanel();

	JFrame f= new JFrame("Peli");
	f.addWindowListener(new WindowAdapter(){
		public void windowClosing(WindowEvent e) {System.exit(0);}
		public void windowGainedFocus(WindowEvent e){e.getWindow().requestFocus();}
	    });
	





	f.getContentPane().add("Center",peli);
	f.getContentPane().add("North",getControls(peli.system));	


	f.pack();
	//f.setSize(new Dimension(400,500));


       	f.setBounds(0,0,450,450);       
        f.setVisible(true);
	f.requestFocus();
	//peli.gameThread.setPriority(Thread.MAX_PRIORITY);

    }




   public void run() 
    {
	Thread me = Thread.currentThread();

	long delay = 2 ;
	while(true)
	    {

		long sleepTime = System.currentTimeMillis();				
	    
		
		long time = System.currentTimeMillis();		

		system.loopLogic();
		repaint();
		//		paintImmediately(0,0,400,400);

  	    try{me.sleep(Math.max(1, (sleepTime+20) - System.currentTimeMillis()));}
	    //	    try{me.sleep(20)                                                   ;}
		catch(InterruptedException e)
		    {;
		    }
	}
	
	    
    }

    public void start() 
    {;
    }


}

class ShuffleListener implements MouseListener
{

    private ParticleSystem system;
    ShuffleListener(ParticleSystem s)
    {
	system = s;
    }

    public void mousePressed(MouseEvent e)
    {
	system.shuffle();
    }

    public void mouseClicked(MouseEvent e){}

    public void mouseEntered(MouseEvent e){}

    public void mouseExited(MouseEvent e){}


    public void mouseReleased(MouseEvent e){} 


}


class StrategyListener implements ActionListener
{
    private ParticleSystem system;
    private ParticleStrategy strategy;

    StrategyListener(ParticleSystem s, ParticleStrategy str)
    {
	system = s;
	strategy = str;
    }
    public void actionPerformed(ActionEvent e)
    {
	system.setStrategy(strategy);
    }
}
