/**
 * Initialize a shader program, so WebGL knows how to draw our data
 * @param {any} gl the WebGL context
 * @param {any} shader the shader to unlink
 * @param {any} shaderProgram the existing shaderprogram
 * @return {any} the shader program
 */
export function unlinkShaderProgram(gl: any, shader: any, shaderProgram: any) {
	// Create the shader program
	gl.deleteShader(shader);
	return [shaderProgram, shader];
}

/**
 * Initialize a shader program, so WebGL knows how to draw our data
 * @param {any} gl the WebGL context
 * @param {string} vsSource the vertex shader source
 * @param {string} fsSource the fragment shader source
 * @return {any} the shader program
 */
export function initShaderProgram(gl: any, vsSource: string, fsSource: string) {
	const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource);
	const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource);

	// Create the shader program
	const shaderProgram = gl.createProgram();
	gl.attachShader(shaderProgram, vertexShader);
	gl.attachShader(shaderProgram, fragmentShader);
	gl.linkProgram(shaderProgram);

	// If creating the shader program failed, alert
	if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
		alert('Unable to initialize the shader program: ' +
			gl.getProgramInfoLog(shaderProgram));
		return null;
	}
	return [shaderProgram, fragmentShader];
}

/**
 * load a GL shader
 * @param {any} gl the WebGL context
 * @param {any} type type of shader to load
 * @param {string} source source code of shader
 * @return {any} the loaded shader
 */
export function loadShader(gl: any, type: any, source: string) {
	const shader = gl.createShader(type);
	// Send the source to the shader object
	gl.shaderSource(shader, source);
	// Compile the shader program
	gl.compileShader(shader);
	// See if it compiled successfully
	if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
		alert('An error occurred compiling the shaders: ' +
			gl.getShaderInfoLog(shader));
		gl.deleteShader(shader);
		return null;
	}
	return shader;
}
