import vsSource from './shaders/shader.vert';
import texture from './shaders/texture.frag';

import {fetchObj, updateObj} from './objutils';
import {initShaderProgram} from './shaders';
import {loadTexture} from './texture';
import {drawScene} from './draw';
import {initParams, setProgramInfo} from './init';

import {uiUpdateParams,
	uiUpdateTexture,
	uiUpdateObject,
	uiUpdateShader} from './uijquery';
import {initUX} from './ux';
import {updateCamera} from './camera';

main();

/**
 * The program purpose is encapsulated in a main function
 */
async function main() {
	const context: any = {
		gl: null,
		texture: null,
		params: null,
		buffers: null,
		programInfo: null,
		shaderProgram: null,
		fragmentShader: null,
		vertexShader: null,
	};
	const canvas: any = document.querySelector('#glCanvas')!;
	context.gl = canvas.getContext('webgl2');

	if (context.gl == null) {
		canvas.parentNode.removeChild(canvas);
		document.getElementById('root')!.insertAdjacentHTML('beforeend',
			`<p>Unable to initialize WebGL. Your browser or machine may not
			support it.</p>`);
	}

	const data = await fetchObj('/static/objs/racer.obj');
	initParams(context);
	updateObj(context, data, true);
	initShaderProgram(context, vsSource, texture);
	setProgramInfo(context);
	context.texture = loadTexture(context.gl, '/static/textures/racer.png');
	let then = 0;
	let changed = false;

	/**
	 * Draws the scene repeatedly
	 * @param {number} now the current time
	 */
	function render(now: any) {
		now *= 0.001;
		const deltaTime = now - then;
		context.params.squareRotation += deltaTime * context.params.rotSpeed;
		if (now >= 1 && changed == false) {
			changed = true;
		}
		then = now;
		updateCamera(context);
		drawScene(context.gl,
			context.programInfo,
			context.buffers,
			context.params,
			context.texture,
			now);
		requestAnimationFrame(render);
	}
	uiUpdateParams(context.params);
	uiUpdateTexture(context);
	uiUpdateObject(context);
	uiUpdateShader(context);
	initUX(context, canvas);
	requestAnimationFrame(render);
}
