// Simple particle system with mouse interaction
(function(){
  const canvas = document.getElementById('particle-canvas');
  const ctx = canvas.getContext('2d');
  let W = canvas.width = innerWidth;
  let H = canvas.height = innerHeight;

  const config = {
    particleCount: 120,
    maxVelocity: 0.7,
    linkDistance: 120,
    size: 2.2,
    color: '200,220,255'
  };

  window.addEventListener('resize', ()=>{
    W = canvas.width = innerWidth;
    H = canvas.height = innerHeight;
  });

  const mouse = {x: null, y: null, radius: 100};
  window.addEventListener('mousemove', (e)=>{ mouse.x = e.clientX; mouse.y = e.clientY; });
  window.addEventListener('mouseleave', ()=>{ mouse.x = null; mouse.y = null; });

  class Particle{
    constructor(){
      this.reset();
    }
    reset(){
      this.x = Math.random()*W;
      this.y = Math.random()*H;
      const v = config.maxVelocity;
      this.vx = (Math.random()*2-1)*v;
      this.vy = (Math.random()*2-1)*v;
      this.size = Math.random()*config.size + 0.3;
      this.alpha = 0.8;
    }
    update(){
      this.x += this.vx;
      this.y += this.vy;
      if(this.x < -10 || this.x > W+10 || this.y < -10 || this.y > H+10) this.reset();

      // repel from mouse
      if(mouse.x !== null){
        const dx = this.x - mouse.x;
        const dy = this.y - mouse.y;
        const dist = Math.sqrt(dx*dx+dy*dy);
        if(dist < mouse.radius){
          const force = (mouse.radius - dist) / mouse.radius;
          this.vx += (dx/dist) * force * 0.6;
          this.vy += (dy/dist) * force * 0.6;
        }
      }
      // slow down
      this.vx *= 0.98;
      this.vy *= 0.98;
    }
    draw(){
      ctx.beginPath();
      ctx.fillStyle = `rgba(${config.color}, ${this.alpha})`;
      ctx.arc(this.x, this.y, this.size, 0, Math.PI*2);
      ctx.fill();
    }
  }

  let particles = [];
  function initParticles(count){
    particles = [];
    for(let i=0;i<count;i++) particles.push(new Particle());
  }

  function connect(){
    for(let i=0;i<particles.length;i++){
      for(let j=i+1;j<particles.length;j++){
        const a = particles[i];
        const b = particles[j];
        const dx = a.x - b.x;
        const dy = a.y - b.y;
        const dist = Math.sqrt(dx*dx+dy*dy);
        if(dist < config.linkDistance){
          const alpha = 0.6 * (1 - dist / config.linkDistance);
          ctx.strokeStyle = `rgba(${config.color}, ${alpha})`;
          ctx.lineWidth = 1 * alpha;
          ctx.beginPath();
          ctx.moveTo(a.x,a.y);
          ctx.lineTo(b.x,b.y);
          ctx.stroke();
        }
      }
    }
  }

  function frame(){
    ctx.clearRect(0,0,W,H);
    for(const p of particles){ p.update(); p.draw(); }
    connect();
    requestAnimationFrame(frame);
  }

  // hook range control
  const range = document.getElementById('count');
  range.addEventListener('input', ()=>{
    config.particleCount = parseInt(range.value,10) || 120;
    initParticles(config.particleCount);
  });

  // start
  initParticles(config.particleCount);
  frame();
})();
