package ocelot.desktop.graphics.mesh

import ocelot.desktop.ColorScheme
import ocelot.desktop.color.{Color, RGBAColorNorm}
import ocelot.desktop.geometry.{Box3D, Vector3D}
import ocelot.desktop.graphics.buffer.Index

object Mesh3D {
  lazy val Cube: Mesh3D = {
    val builder = new MeshBuilder3D
    builder.cuboid(Vector3D(-0.5f, -0.5f, -0.5f), Vector3D(0.5f, 0.5f, 0.5f))
    builder.build()
  }

  lazy val Grid: Mesh3D = {
    val builder = new MeshBuilder3D

    val size = 20
    val gridColor = ColorScheme("Grid3DColor")
    val axisPosXColor = ColorScheme("Grid3DPosX")
    val axisPosZColor = ColorScheme("Grid3DPosZ")
    val axisNegXColor = ColorScheme("Grid3DNegX")
    val axisNegZColor = ColorScheme("Grid3DNegZ")

    def getColor(pos: Vector3D, base: RGBAColorNorm): Color = {
      val a = 1 - (pos.length / size).min(1f).max(0f)
      RGBAColorNorm(base.r, base.g, base.b).withAlpha(base.a * a)
    }

    for (sx <- -size until size) {
      for (sz <- -size until size) {
        val a = Vector3D(sx, 0, sz)
        val b = Vector3D(sx + 1, 0, sz)
        val c = Vector3D(sx, 0, sz + 1)

        var color = if (a.z == 0 && b.z == 0) {
          if (a.x >= 0) axisPosXColor else axisNegXColor
        } else gridColor
        builder.line(a, b, aColor = getColor(a, color), bColor = getColor(b, color))

        color = if (a.x == 0 && c.x == 0) {
          if (a.z >= 0) axisPosZColor else axisNegZColor
        } else gridColor
        builder.line(a, c, aColor = getColor(a, color), bColor = getColor(c, color))
      }
    }

    builder.build()
  }
}

class Mesh3D(override val vertices: Seq[MeshVertex3D], override val indices: Option[Seq[Index]] = None,
             override val primitiveType: PrimitiveType = PrimitiveTriangles)
    extends Mesh[MeshVertex3D] {
  val boundingBox: Box3D = {
    Box3D.fromVertices(vertices.iterator.map(_.pos))
  }
}
