package ru.dbotthepony.kstarbound.test

import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import ru.dbotthepony.kommons.vector.Vector2d
import ru.dbotthepony.kstarbound.math.*
import ru.dbotthepony.kstarbound.util.random.random
import ru.dbotthepony.kstarbound.world.CHUNK_SIZE
import ru.dbotthepony.kstarbound.world.CHUNK_SIZE_FF
import ru.dbotthepony.kstarbound.world.ChunkPos
import ru.dbotthepony.kstarbound.world.physics.Poly
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin

object MathTests {
	@Test
	@DisplayName("roundByAbsoluteValue test")
	fun roundByAbsoluteValueTest() {
		check(roundByAbsoluteValue(0.0) == 0)
		check(roundByAbsoluteValue(0.1) == 1)
		check(roundByAbsoluteValue(1.1) == 2)
		check(roundByAbsoluteValue(-0.1) == -1)
		check(roundByAbsoluteValue(-0.0) == 0)
		check(roundByAbsoluteValue(-1.0) == -1)
		check(roundByAbsoluteValue(-1.1) == -2)
	}

	@Test
	@DisplayName("roundTowardsNegativeInfinity test")
	fun roundTowardsNegativeInfinityTest() {
		check(roundTowardsNegativeInfinity(0.0) == 0)
		check(roundTowardsNegativeInfinity(0.1) == 0)
		check(roundTowardsNegativeInfinity(0.6) == 0)
		check(roundTowardsNegativeInfinity(1.1) == 1)
		check(roundTowardsNegativeInfinity(-0.1) == -1)
		check(roundTowardsNegativeInfinity(-0.0) == 0)
		check(roundTowardsNegativeInfinity(-1.0) == -1)
		check(roundTowardsNegativeInfinity(-1.1) == -2)
		check(roundTowardsNegativeInfinity(-1.6) == -2)
	}

	@Test
	@DisplayName("roundTowardsPositiveInfinity test")
	fun roundTowardsPositiveInfinityTest() {
		check(roundTowardsPositiveInfinity(0.0) == 0)
		check(roundTowardsPositiveInfinity(0.1) == 1)
		check(roundTowardsPositiveInfinity(0.6) == 1)
		check(roundTowardsPositiveInfinity(1.1) == 2)
		check(roundTowardsPositiveInfinity(-0.1) == 0)
		check(roundTowardsPositiveInfinity(-0.0) == 0)
		check(roundTowardsPositiveInfinity(-1.0) == -1)
		check(roundTowardsPositiveInfinity(-1.1) == -1)
		check(roundTowardsPositiveInfinity(-1.6) == -1)
	}

	@Test
	@DisplayName("Quickhull test")
	fun quickhullTest() {
		// this test is fragile since it is at discretion of "random" how it goes
		val random = random(28383384L)
		val vertices = ArrayList<Vector2d>()

		for (i in 0 until 1000) {
			val angle = random.nextDouble(PI * 2.0)
			vertices.add(Vector2d(sin(angle), cos(angle)))
		}

		val hull = Poly.quickhull(vertices)

		val testPoints = ArrayList<Vector2d>()

		for (i in 0 until 1000) {
			val angle = random.nextDouble(PI * 2.0)
			testPoints.add(Vector2d(sin(angle) * 0.8, cos(angle) * 0.8))
		}

		for (point in testPoints) {
			assertTrue(point in hull)
		}
	}
}
