package ocelot.desktop.node

import ocelot.desktop.audio.SoundSource
import ocelot.desktop.geometry.Vector3D
import ocelot.desktop.{OcelotDesktop, Settings}

/**
  * Updates sound sources' position depending on where the camera is.
  *
  * @note OpenAL only applies positioning to mono sources!
  *       If your source is stereo, this trait will have no audible effect.
  */
trait PositionalSoundSourcesNode extends Node {
  // Every node can have multiple sound sources playing at the same time
  def soundSources: Seq[SoundSource] = Seq()

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

    // Calculating position of sound source relative to center of workspace
    // but only if corresponding setting is enabled
    val soundPosition = if (Settings.get.soundPositional) {
      val rootWidthHalf = OcelotDesktop.root.width / 2
      val rootHeightHalf = OcelotDesktop.root.height / 2

      val nodeCenterX = position.x + width / 2
      val nodeCenterY = position.y + height / 2

      // Limiting "significance" of the position as a percentage value because on
      // large monitors the sound may become too "non-audiophile"
      val limit = 0.05f

      Vector3D(
        (nodeCenterX - rootWidthHalf) / rootWidthHalf * limit,
        (nodeCenterY - rootHeightHalf) / rootHeightHalf * limit,
        0,
      )
    } else {
      Vector3D.Zero
    }

    for (soundSource <- soundSources)
      soundSource.position = soundPosition
  }
}
