package net.beadsproject.touch.examples;
import math.geom2d.Point2D;
import net.beadsproject.touch.HVLayout;
import net.beadsproject.touch.ParticleSimulator;
import net.beadsproject.touch.perform.PerformNode;
import processing.core.PApplet;

/**
 * Demonstrates the use of a particle simulation with some interaction.
 * 
 * @author ben
 *
 */
public class ParticleSimulatorTestWithInteraction extends PApplet {	
	
	static final int DEPTH = 5;
	static final int NARY = 3;
	static int NUM_PARTICLES = 1;
	
	static PerformNode pt = null;
	ParticleSimulator simulator = null;
	
	boolean isSimulating = false; 
	ParticleSimulator.Particle draggingParticle = null;	
	
	public void setup()
	{		
		size(900,900);
		ellipseMode(CENTER);
		simulator = new ParticleSimulator();		
		
		println("Building tree");
		pt = Example.example1();
		pt.computeUniqueValue(0,1);
				
		println("Laying out and initialising simulator.");
		simulator.addHVPoints(HVLayout.layout(pt));
		simulator.computeTreeDistance();
		
		println("Done");
	}	
		
	public void draw()
	{		
		background(200,100,100);
		pushMatrix();
		scale(width,height);
		noStroke();
		for(ParticleSimulator.Particle p: simulator.getParticles())
		{
			//Color c = new Color(Color.HSBtoRGB(p.pn.uniqueValue(),.8f,1f));			
			//fill(c.getRed(),c.getGreen(),c.getBlue(),150);
			fill(255,200);
			ellipse((float)p.x,(float)p.y,(float)(p.radius*2),(float)(p.radius*2));
			
			fill(0);
			ellipse((float)p.x,(float)p.y,4.f/width,4.f/height);
		}
		
		if (mousePressed && draggingParticle!=null)
		{
			fill(255,255,200);
			ParticleSimulator.Particle p = draggingParticle;
			ellipse((float)p.x,(float)p.y,(float)(p.radius*2),(float)(p.radius*2));			
		}
		
		popMatrix();
		
		// now simulate by some amount
		simulator.step(0.005f);
	}		
	
	public void mouseClicked()
	{
		// transform the mouse click into particle world coordinates
		double mx = (double)mouseX/width, my = (double)mouseY/height;
		
		// if the mouse is clicked then we locate the node under the mouse and mutate it by some amount
		for(ParticleSimulator.Particle p: simulator.getParticles())
		{
			if (p.contains(new Point2D(mx,my)))
			{
				ParticleSimulator.Particle q = new ParticleSimulator.Particle(p);
				q.setLocation(q.plus(new Point2D((1-2*Math.random())*p.radius,(1-2*Math.random())*p.radius)));
				q.pn = p.pn; // p.pn.reproduce();
				q.radius = p.radius;
				simulator.addParticle(q);
				break;
			}
		}		
	}
		
	public void mousePressed()
	{
		// grab a particle and start to move it
		
		// transform the mouse click into particle world coordinates
		double mx = (double)mouseX/width, my = (double)mouseY/height;
		
		// if the mouse is clicked then we locate the node under the mouse and mutate it by some amount
		for(ParticleSimulator.Particle p: simulator.getParticles())
		{
			if (p.contains(new Point2D(mx,my)))
			{
				draggingParticle = p;
				break;
			}
		}
	}
	
	public void mouseReleased()
	{
		draggingParticle = null;		
	}
	
	public void mouseDragged()
	{
		// transform the mouse click into particle world coordinates
		double mx = (double)mouseX/width, my = (double)mouseY/height;
		draggingParticle.setLocation(new Point2D(mx,my));
	}
}
