package ru.dbotthepony.kstarbound.math.matrix

class Matrix3fStack {
	private val stack = ArrayDeque<Matrix3f>()

	init {
		stack.addLast(Matrix3f.identity())
	}

	fun clear(top: Matrix3f): Matrix3fStack {
		stack.clear()
		stack.addLast(top.copy())
		return this
	}

	fun push(): Matrix3fStack {
		stack.addLast(stack.last().copy())
		return this
	}

	fun pop(): Matrix3f {
		return stack.removeLast()
	}

	fun last(): Matrix3f {
		return stack.last()
	}

	fun push(matrix: Matrix3f): Matrix3fStack {
		stack.addLast(matrix.copy())
		return this
	}

	fun identity() = push(Matrix3f.identity())
	fun zero() = push(Matrix3f.all(0f))
	fun all(value: Float) = push(Matrix3f.all(value))

	inline fun <T> with(block: Matrix3f.() -> T): T {
		return try {
			push()
			block(last())
		} finally {
			pop()
		}
	}

	inline fun <T> with(matrix: Matrix3f, block: Matrix3f.() -> T): T {
		return try {
			push(matrix)
			block(last())
		} finally {
			pop()
		}
	}
}
