import {setProgramInfo} from './init';

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

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

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

/**
 * 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;
}

/**
 *
 * @param {any} context the program context
 * @param {string} fsSource new fragment shader source
 * @param {string} vsSource current vsSource
 */
export function changeFragmentShader(context: any,
	fsSource: string,
	vsSource: string) {
	context.gl.deleteShader(context.fragmentShader);
	initShaderProgram(context, vsSource, fsSource);
	setProgramInfo(context);
}
