package gay.pizza.CavesOfJolk

import com.badlogic.gdx.Gdx
import com.badlogic.gdx.Input
import com.badlogic.gdx.audio.Sound
import com.badlogic.gdx.controllers.Controllers
import com.badlogic.gdx.graphics.PerspectiveCamera
import com.badlogic.gdx.graphics.Texture
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import com.badlogic.gdx.graphics.g2d.TextureRegion
import com.badlogic.gdx.math.MathUtils
import com.badlogic.gdx.math.Vector2
import com.badlogic.gdx.math.Vector3
import gay.pizza.CavesOfJolk.Resources.Companion.assetManager
import ktx.math.minusAssign
import ktx.math.plusAssign
import ktx.math.times

class Colin
{
	private var pos = Vector2()
	private var angle = 0.0f
	private var offsAngle = Vector2()
	private var fov = 60.0f
	private var cam: PerspectiveCamera
	private var nutted = false

	private var texture: Texture = assetManager.get("colin.png")
	private val nut: Sound = assetManager.get("nut.wav")

	init
	{
		cam = PerspectiveCamera(fov,
			Gdx.graphics.width.toFloat(),
			Gdx.graphics.height.toFloat())
		cam.near = 0.1f
		cam.far = 40.0f
	}

	private fun updateCamera()
	{
		cam.position.set(Vector3(pos.x, 1.0f, pos.y))
		val forward = Vector3(0.0f, 0.0f, -1.0f)
		val up = Vector3(0.0f, 1.0f, 0.0f)
		val right = Vector3(1.0f, 0.0f, 0.0f)
		cam.direction.set(forward.rotateRad(right, offsAngle.y).rotateRad(up, offsAngle.x + angle))
		cam.update()
	}

	fun resize(width: Int, height: Int)
	{
		cam.viewportWidth = width.toFloat()
		cam.viewportHeight = height.toFloat()
	}

	fun update(deltaTime: Float)
	{
		val stick = Controllers.getCurrent()?.let { pad ->
			Vector2(
				pad.getAxis(pad.mapping.axisLeftX),
				pad.getAxis(pad.mapping.axisLeftY))
					.cardinalDeadzone(0.1f, 1.0f)
		} ?: Vector2()

		val turnSpeed = MathUtils.PI2 * 0.1f
		if (Gdx.input.isKeyPressed(Input.Keys.LEFT))
			angle += turnSpeed * deltaTime
		if (Gdx.input.isKeyPressed(Input.Keys.RIGHT))
			angle -= turnSpeed * deltaTime
		if (!stick.isZero)
			angle -= stick.x * 2.0f * turnSpeed * deltaTime

		val speed = 2.0f
		val forward = Vector2(-MathUtils.sin(angle), -MathUtils.cos(angle))
		if (Gdx.input.isKeyPressed(Input.Keys.UP))
			pos += forward * speed * deltaTime
		if (Gdx.input.isKeyPressed(Input.Keys.DOWN))
			pos -= forward * speed * deltaTime
		if (!stick.isZero)
			pos -= forward * stick.y * speed * deltaTime

		offsAngle = Controllers.getCurrent()?.let { pad ->
			val dst = Vector2(
				pad.getAxis(pad.mapping.axisRightX),
				pad.getAxis(pad.mapping.axisRightY))
				.radialDeadzone(0.1f, 1.0f) * MathUtils.PI * -0.25f
			offsAngle.lerp(dst, 16.0f * deltaTime)
		} ?: Vector2.Zero
		Controllers.getCurrent()?.let { pad ->
			val targetFov = MathUtils.lerp(60.0f, 20.0f, pad.getAxis(5))
			cam.fieldOfView = MathUtils.lerp(cam.fieldOfView, targetFov, 20.0f * deltaTime)
		}

		if (Controllers.getCurrent()?.let { pad -> pad.getButton(pad.mapping.buttonA) } == true || Gdx.input.isKeyJustPressed(Input.Keys.N))
		{
			if (!nutted)
			{
				nut.stop()
				nut.play()
				nutted = true
			}
		}
		else
		{
			nutted = false
		}

		updateCamera()
	}

	fun draw(spriteBatch: SpriteBatch)
	{
		val drawPos = Vector2(pos.x * 100.0f, -pos.y * 100.0f)
		//spriteBatch.draw(texture, drawPos.x - 32.0f, drawPos.y - 32.0f, 64.0f, 64.0f)
		val region = TextureRegion(texture)
		spriteBatch.draw(region,
			drawPos.x - 32.0f, drawPos.y - 32.0f,
			32.0f, 32.0f,
			64.0f, 64.0f,
			1.0f, 1.0f, angle * MathUtils.radiansToDegrees)

	}

	val camera get() = cam
	val position get() = pos
}
