let grid_pts  = [];
let rand_pts = [];
let rand_color = [];
let flow_pts = [];

let grid_space = 25;

let numrpts = 6;

function setup() {
  createCanvas(800,800);
  background(0);
  
  let xpts = width/grid_space;
  let ypts = height/grid_space;
  for(let i = 0; i < xpts; ++i){
    for(let j = 0; j < ypts; ++j){
      append(grid_pts, createVector(i*grid_space,j*grid_space,0));
      append(flow_pts, createVector(i*grid_space,j*grid_space,0));
    }
  }
  
  for(let i = 0; i < numrpts; ++i){
    let  pt_pos = grid_pts[int(random(grid_pts.length))];
    append(rand_pts,pt_pos);
    append(rand_color, createVector(random(255),random(255),random(255)));
  }
}

function draw() {
  fill(0,0,0,5);
  noStroke();
  rect(0,0,width,height);
  
   for(let i = 0; i < grid_pts.length; ++i){
     let posV = grid_pts[i];
     noStroke();
     fill(100);
     ellipse(posV.x,posV.y,5,5);
     if(dist(mouseX,mouseY,posV.x,posV.y) < 9){
       fill(255,255,255);
       ellipse(posV.x,posV.y,14,14);
     }
   }
   
   for(let i = 0; i < rand_pts.length; ++i){
     let posV = rand_pts[i];
     noStroke();
     let c = rand_color[i];
     fill(c.x,c.y,c.z);
     ellipse(posV.x,posV.y,15,15);
   }
   
   ////////////get low and high distance//////////////
   let vs0 =  flow_pts[0];
   let vsn =  rand_pts[0];
   let l = 1/dist(vs0.x,vs0.y,vsn.x,vsn.y);
   let h = 1/dist(vs0.x,vs0.y,vsn.x,vsn.x);
   for(let i = 0; i < flow_pts.length; i++){
     for(let j = 0; j < numrpts; j++){
       vsn =  rand_pts[j];
       let d = dist(vs0.x,vs0.y,vsn.x,vsn.y);
       if(d < l){
          l = d;
       }
       if(d > h){
           h = d;
       }
     }
   }
  
   for(let i = 0; i < flow_pts.length; ++i){
    let posV =  flow_pts[i];
    let dv = 0;
    let tx = 0;
    let ty = 0;
     
    let aR = 0;
    let aG = 0;
    let aB = 0;
    
    let dd = 99999;
    for(let j = 0; j < numrpts; j++){
        vsn =  rand_pts[j];
        
        let avcolor = rand_color[j];
        let nd = dist(posV.x,posV.y,vsn.x,vsn.y);
        if(nd < dd){
          dd = nd;
        }
        let d = 1/dist(posV.x,posV.y,vsn.x,vsn.y);
        let rd = map(d,l,h,0.0,1.0);
        tx = tx + vsn.x*rd*rd;
        ty = ty + vsn.y*rd*rd;
        dv = dv + rd*rd;
      
        aR = aR + avcolor.x *rd*rd;
        aG = aG + avcolor.y *rd*rd;
        aB = aB + avcolor.z *rd*rd;
    }
    
    
    tx = tx/dv;
    ty = ty/dv;
     
    aR = aR/dv;
    aG = aG/dv;
    aB = aB/dv;
     
    let na = -atan2(tx-posV.x, ty-posV.y);
    
    stroke(aR,aG,aB);
    strokeWeight(5);
    point(posV.x,posV.y);
    let nx = posV.x;
    let ny = posV.y;
    
    nx = nx + 1 * cos(na);
    ny = ny + 1 * sin(na);
     
    
    flow_pts[i] = createVector(nx,ny,0);
  }
  
  let index = int(random(grid_pts.length));
  let vs =  grid_pts[index];
  flow_pts[index] = createVector(vs.x,vs.y,0);
  
}

function mouseClicked() {
  for(let i = 0; i < grid_pts.length; ++i){
    let vs =  grid_pts[i];
    if(dist(mouseX,mouseY,vs.x,vs.y) < 9){
      let index = int(random(rand_pts.length));
      rand_pts[index] = createVector(vs.x,vs.y,0);
      rand_color[index] = createVector(random(255),random(255),random(255));
    }
  }
}

function keyReleased() {
  if (key == ' '){
    for(let i = 0; i < flow_pts.length; ++i){
      let vs =  grid_pts[i];
      flow_pts[i] = createVector(vs.x,vs.y,0);
    }
  }
}