// Project: 		TrafficFlow
// File: 			FlowTest.java
// Created by: 		rcarlsen, Feb 25, 2009


// Imports
import java.util.ArrayList;
import javax.media.opengl.GL;
import processing.core.*;
import processing.opengl.PGraphicsOpenGL;


public class FlowTest extends PApplet {

  //Seek_Arrive
  //Daniel Shiffman <http://www.shiffman.net>
  //Nature of Code, Spring 2009
  
  // adapted for Eclipse by Robert Carlsen

  //Two "boids" follow the mouse position

  //Implements Craig Reynold's autonomous steering behaviors
  //One boid "seeks"
  //One boid "arrives"
  //See: http://www.red3d.com/cwr/

  //Boid seeker;
  //Boid arriver;

  ArrayList<PVector> deviceEmitters;
  Flock flockOut;
  ArrayList<Flock> flocksIn;
  
  ArrayList<Boid> seekers;
  FlowField flowfield;
  
  boolean debug = false;
  
  // to set up the openGL context:
  PGraphicsOpenGL pgl;
  GL gl;
  
  public void setup() {
    size(600,600,OPENGL);
    
    // set up a bunch of these Boids:
    //seekers = new ArrayList<Boid>();
    flockOut = new Flock();
    /*
    for(int i=0;i<30;i++){
      flockOut.addBoid(new Boid(this,new PVector(random(width),random(height)),random(2,5),random(0.1f,0.5f)));
    }
    */
    PVector center = new PVector(this.width/2.0f, this.height/2.0f);
    
    deviceEmitters = new ArrayList<PVector>();
    flocksIn = new ArrayList<Flock>();
    int num = 7;
    float radius = (this.width-40)/2.0f;
    for(int i=0;i<num;i++){
      float a = i*(TWO_PI/(float)num);
      PVector loc = new PVector(radius*cos(a),radius*sin(a));
      loc.add(center);

      // TODO: create boids at these points
      deviceEmitters.add(loc);
      flocksIn.add(new Flock());
    }
    
    // Make a new flow field with "resolution" of 16
    flowfield = new FlowField(this,16,center);
    
    smooth();
  }

  public void draw() {
    //***//
    // OPENGL Additive blending stuff:
    pgl = (PGraphicsOpenGL) g;
    gl = pgl.gl;
    
    pgl.beginGL();
    // This fixes the overlap issue
     gl.glDisable(GL.GL_DEPTH_TEST);
    // Turn on the blend mode
    gl.glEnable(GL.GL_BLEND);
    // Define the blend mode
     gl.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE);
    //gl.glBlendFunc(GL.GL_SRC_ALPHA, GL.GL_ONE_MINUS_SRC_ALPHA);
     
     //gl.glFrustum(0, this.width, this.height, 0, 0, 20000);
    pgl.endGL();  
    //***//
    
    background(0);

    if (debug) flowfield.display();
    
    /*
    // Draw an ellipse at the mouse location
    int mx = mouseX;
    int my = mouseY;
    fill(175);
    stroke(0);
    ellipse(mx,my,30,30);
     */
    
    /*
    // Call the appropriate steering behaviors for our agents
    seeker.seek(new PVector(mx,my));
    seeker.run();
    arriver.arrive(new PVector(mx,my));
    arriver.run();
    */
    
//  PVector target = new PVector(mx,my);
    PVector target = new PVector(this.width/2,this.height/2);
    
    // add new boids at the device emitters
    for(int i=0;i<deviceEmitters.size();i++){
      PVector p = deviceEmitters.get(i);
      
      // all this stuff is simulating the bursts of info:
      if(frameCount%(int)random(5,10)==0){
        int num = (int)random(5);
        for(int j=0;j<num;j++){
          flockOut.addBoid(new Boid(this,p,random(2,5),random(0.1f,0.5f),color(150,20,20)));
        }
        num = (int)random(5);
        for(int j=0;j<num;j++){
          flocksIn.get(i).addBoid(new Boid(this,target,random(2,5),random(0.1f,0.5f),color(20,20,150)));
        }
      }
      //flocksIn.get(i).follow(flowfield);
      flocksIn.get(i).arrive(p);
      flocksIn.get(i).run();
    }
    
    flockOut.follow(flowfield);
    flockOut.seek(target);
    flockOut.run();

    
    /*
    // do it for the array:
    for(int i=0;i<seekers.size();i++){
      Boid b = seekers.get(i);
      
      PVector target = new PVector(mx,my);
      //PVector target = new PVector(this.width/2,this.height/2);
      //b.follow(flowfield);
      b.seek(target);
      b.run();
      if(b.dead())
        seekers.remove(i);
    }
    */
  }


public void keyPressed(){
  switch(key){
  case ' ':
    debug = !debug;
    break;
  }
}

}  
