import math
from shortcrust.gl2 import GLfloats


def glmatrix(m):
	return GLfloats(m[0] + m[1] + m[2] + m[3])


identity = [
	[1, 0, 0, 0],
	[0, 1, 0, 0],
	[0, 0, 1, 0],
	[0, 0, 0, 1]
]


# Generates a frustum matrix with the given bounds
#
# @param {number} left Left bound of the frustum
# @param {number} right Right bound of the frustum
# @param {number} bottom Bottom bound of the frustum
# @param {number} top Top bound of the frustum
# @param {number} near Near bound of the frustum
# @param {number} far Far bound of the frustum
def frustum(left, right, bottom, top, near, far):
#	rl = (right - left)
#	tb = (top - bottom)
#	fn = (far - near)
#	return [
#		[(near * 2) / rl, 0, 0, 0],
#		[0, (near * 2) / tb, 0, 0],
#		[(right + left) / rl, (top + bottom) / tb, -(far + near) / fn, -1],
#		[0, 0, -(far * near * 2) / fn, 0]
#	]
	delta = [right - left, top - bottom, far - near]
	summ = [right + left, top + bottom, far + near]
	ratio = [summ[0] / delta[0], summ[1] / delta[1], summ[2] / delta[2]]
	twoRatio = [2.0 * near / delta[0], 2.0 * near / delta[1], 2.0 * near / delta[2]]

	return [
		[twoRatio[0], 0, 0, 0],
		[0, twoRatio[1], 0, 0],
		[ratio[0], ratio[1], -ratio[2], -1.0],
		[0, 0, -near * twoRatio[2], 0]
	]


def perspective(fovy, aspect, near, far):
	top = near * math.tan(fovy * math.pi / 360.0)
	right = top * aspect
	return frustum(-right, right, -top, top, near, far)


def translate(x, y, z):
	return [
		[1, 0, 0, x],
		[0, 1, 0, y],
		[0, 0, 1, z],
		[0, 0, 0, 1]
	]


def rotate_x(angle):
	return [
		[1, 0, 0, 0],
		[0, math.cos(angle), -math.sin(angle), 0],
		[0, math.sin(angle), math.cos(angle), 0],
		[0, 0, 0, 1]
	]


def rotate_y(angle):
	return [
		[math.cos(angle), 0, math.sin(angle), 0],
		[0, 1, 0, 0],
		[-math.sin(angle), 0, math.cos(angle), 0],
		[0, 0, 0, 1]
	]


def rotate_z(angle):
	return [
		[math.cos(angle), -math.sin(angle), 0, 0],
		[math.sin(angle), math.cos(angle), 0, 0],
		[0, 0, 1, 0],
		[0, 0, 0, 1]
	]


def mat_vec_mul(m, v):
	return[sum(m[k][j] * v[j] for j in range(4)) for k in range(4)]


def mul(A, B):
	return [[sum(A[i][j] * B[j][k] for j in range(4)) for k in range(4)] for i in range(4)]
