package ocelot.desktop.node

import ocelot.desktop.ColorScheme
import ocelot.desktop.entity.traits.OcelotInterface
import ocelot.desktop.util.NumberUtils.ExtendedFloat
import ocelot.desktop.geometry.Vector2D
import ocelot.desktop.graphics.Graphics
import ocelot.desktop.node.OcelotLogParticleNode._
import ocelot.desktop.ui.UiHandler
import ocelot.desktop.ui.event.BrainEvent
import ocelot.desktop.ui.particle.Particle

import scala.util.Random

trait OcelotLogParticleNode extends Node {
  private var queuedParticles: Int = 0

  eventHandlers += {
    case BrainEvent(OcelotInterface.LogEvent.CardToUser(_, _)) =>
      queuedParticles += 1
  }

  override def update(): Unit = {
    super.update()
    spawnParticles()
  }

  private def spawnParticles(): Unit = {
    val system = UiHandler.root.workspaceView.particleSystem
    val toSpawn = queuedParticles min (MaxLogParticles - system.count[LogParticle](Some(this))) max 0

    for (_ <- 0 until toSpawn) {
      system.add(new LogParticle)
    }

    queuedParticles = 0
  }

  private class LogParticle extends Particle(time = -LogParticleGrow, speed = LogParticleMoveSpeed, origin = Some(this)) {
    private val angle: Float = Random.between(0f, 2 * math.Pi.toFloat * LogParticleMaxAngle)
    override def draw(g: Graphics): Unit = {
      val size = (1 + time / LogParticleGrow).clamped() * LogParticleSize
      val offset = time.clamped() * LogParticleMoveDistance
      val alpha = 1 - time.clamped()

      val r1 = (bounds.w max bounds.h) / math.sqrt(2).toFloat + offset + LogParticlePadding
      val r2 = r1 + size

      for (i <- 0 until LogParticleCount) {
        val a = angle + (2 * math.Pi).toFloat * i / LogParticleCount
        val v = Vector2D.unit(a)
        val p1 = v * r1 + bounds.center
        val p2 = v * r2 + bounds.center
        g.line(p1, p2, 1f, ColorScheme("LogParticle").mapA(_ => alpha))
      }
    }
  }
}

object OcelotLogParticleNode {
  private val MaxLogParticles: Int = 15
  private val LogParticleMaxAngle: Float = 0.25f
  private val LogParticleCount: Int = 12
  private val LogParticleGrow: Float = 0.25f
  private val LogParticlePadding: Float = 2f
  private val LogParticleSize: Float = 10f
  private val LogParticleMoveSpeed: Float = 1f
  private val LogParticleMoveDistance: Float = 20f
}
