window.onload = scryptonite_boot;

var scryptonite_logging = true;
var scryptonite_context = null;
var scryptonite_plugins = [];

window.onresize = function(){ 
	document.location.href='';
}


function render_context()
{
	this.write_log = function(what)
	{
		if (scryptonite_logging)
		{
			console.log(what);
		}
	};

	this.write_html = function(what)
	{
		document.body.innerHTML = what+document.body.innerHTML;
	};

	
	this.fullscreen = function()
	{
		if (!document.getElementById('scryptonite_canvas'))
		{
			this.write_html('<table height=100% width=100%><tr><td><center><canvas id="scryptonite_canvas" width=1 height=1></canvas></center></td></tr></table>');
		}
		this.canvas = document.getElementById("scryptonite_canvas");
		
		var w = window.innerWidth;
		var h = (w/16.0)*9.0;
	
		if (h > window.innerHeight)
		{
			h = window.innerHeight;
			w = (h/9.0)*16.0;
		}

	
		this.canvas.width = w;
		this.canvas.height = h;
		
		this.write_log("render_context: full screen "+this.canvas.width+"x"+this.canvas.height);
	}
	
	this.windowed = function(width,height)
	{
		if (!document.getElementById('scryptonite_canvas'))
		{
			this.write_html('<canvas id="scryptonite_canvas" width=1 height=1></canvas>');
		}
		this.write_log("render_context: windowed");
		this.canvas = document.getElementById("scryptonite_canvas");
		this.canvas.width = width;
		this.canvas.height = height;
	}
	
	this.add_list = function(e)
	{
		this.write_log('render_context: add_list, '+e.length);
		this.elements = e;
	}
	
	this.add = function(e)
	{
		this.write_log('render_context: add - '+e.constructor.name);
		if (!this.elements) this.elements = [];
		this.elements.push(e);
	}
	
	this.render = function()
	{
		var gl = scryptonite_context.gl;
		var canvas = scryptonite_context.canvas;
		var elements = scryptonite_context.elements;
		
		gl.viewport(0, 0, canvas.width, canvas.height);
		for (var i=0; i<elements.length; ++i)
		{
			elements[i].render();
		}
		document.title = scryptonite_context.audio_time;
		window.setTimeout(scryptonite_context.render, 1000/60);
	}


	this.go = function()
	{
		this.write_log("render_context: go, elements: "+this.elements.length);
		this.gl = getWebGLContext(this.canvas);
		if (!this.gl)
		{
			this.write_log("render_context: go - failed to get gl");
		}

		for (var i=0; i<this.elements.length; ++i)
		{
			this.elements[i].init(this.gl);
		}
		
		scryptonite_context.render();
	}
	

	this.write_log('-------');
}

function element_audio(tag,auto_play)
{
	this.play = function()
	{
		var e = document.getElementById(this.audio_tag);
		e.play();
		this.playing = true;
	}

	this.init = function(gl) 
	{
		this.playing = false;
		this.audio_tag = tag;
		scryptonite_context.write_log("render_audio: init "+this.audio_tag);
		

		document.onkeydown = function(evt) 
		{
			var e = document.getElementById(tag);
			if (!e) console.log('unable to find: '+tag);
			switch (evt.keyCode) 
			{
				case 37:
					e.currentTime-=5.0;
				break;
				case 39:
					e.currentTime+=5.0;
				break;
				case 13:
					if (this.playing) { e.pause(); this.playing = false; }
					else { e.play(); this.playing=true; }
				break;

			};
		};

		if (auto_play) this.play();
	};
	
	this.render = function()
	{
		var e = document.getElementById(this.audio_tag);		
		var t = e.currentTime;	
		scryptonite_context.audio_time = t;
	}
}


function element_shader(frag,vert)
{
	
	this.init = function(gl) 
	{		
		scryptonite_context.write_log('element_shader: '+frag+' '+vert);
	
		vertexShader = createShaderFromScriptElement(gl, vert);
		fragmentShader = createShaderFromScriptElement(gl, frag);
		
		if (!vertexShader || !fragmentShader)
		{
			this.program = false;
		}
		else
		{
		
			this.program = createProgram(gl, [vertexShader, fragmentShader]);
			gl.useProgram(this.program);

			// look up where the vertex data needs to go.
			this.positionLocation = gl.getAttribLocation(this.program, "a_position");

			// Create a buffer and put a single clipspace rectangle in
			// it (2 triangles)
			this.buffer = gl.createBuffer();
			gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
			gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
			-1.0, -1.0,
			 1.0, -1.0,
			-1.0,  1.0,
			-1.0,  1.0,
			 1.0, -1.0,
			 1.0,  1.0]), gl.STATIC_DRAW);
			}
	}
	this.render = function()
	{
		if (this.program)
		{
			var gl = scryptonite_context.gl;

			gl.useProgram(this.program);
			var l2 = gl.getUniformLocation( this.program, "iGlobalTime"        ); 
			if( l2!=null ) 
			{
				gl.uniform1f(  l2, scryptonite_context.audio_time );
			}

			var l3 = gl.getUniformLocation( this.program, "iResolution"        ); 
			if ( l3!=null ) 
			{
				gl.uniform3f(  l3, scryptonite_context.canvas.width, scryptonite_context.canvas.height, 1.0 );	
			}

			gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
			gl.enableVertexAttribArray(this.positionLocation);
			gl.vertexAttribPointer(this.positionLocation, 2, gl.FLOAT, false, 0, 0);
			gl.drawArrays(gl.TRIANGLES, 0, 6);
		}
	}
}

function element_shader_with_texture(frag,vert,t)
{
	function power2(v)
	{
		return (v & (v-1))==0;
	}

	function load_texture(url,gl)
	{
		var tex = gl.createTexture();	
		var img = new Image();
		img.src = url;
		img.onload = function() {
			gl.bindTexture(gl.TEXTURE_2D, tex);
			gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, img);
			if (power2(img.width) && power2(img.height))
			{
				gl.generateMipmap(gl.TEXTURE_2D);
				gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
			}
			else
			{
				gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
				gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
				gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
			}
//		console.log('(Done) Loading texture: '+url);
		};


		return tex;
	}

	this.init = function(gl)
	{
		scryptonite_context.write_log('element_shader_with_texture: '+t);
		this.shader.init(gl);
		this.texture_id = load_texture(t,gl);
	}
	
	this.render = function()
	{
		var gl = scryptonite_context.gl;
		gl.useProgram(this.shader.program);
		gl.activeTexture(gl.TEXTURE0);
		gl.bindTexture(gl.TEXTURE_2D, this.texture_id);
		gl.uniform1i(gl.getUniformLocation(this.shader.program, 'tex0'), 0);
		this.shader.render();
	}
	
	this.shader = new element_shader(frag,vert);
}

function element_clear(r,g,b,a)
{
	this.r = r;
	this.g = g;
	this.a = a;
	this.b = b;
	this.init = function(gl)
	{
	}
	
	this.render = function()
	{
		var gl = scryptonite_context.gl;
		gl.clearColor(this.r,this.g,this.b,this.a);
		gl.clear(gl.COLOR_BUFFER_BIT);
	}
}

function element_blend(e)
{
	this.element = e;
	
	this.init = function(gl)
	{
		scryptonite_context.write_log('element_blend');
		this.element.init(gl);
	}
	
	this.render = function()
	{
		var gl = scryptonite_context.gl;
		gl.enable(gl.BLEND);
		gl.blendFunc(gl.ONE,gl.ONE);
		this.element.render();
		gl.disable(gl.BLEND);
	}
}

function element_nosound()
{
	this.init = function()
	{
		var d = new Date();
		this.starttime = d.getTime();
	}
	
	this.render = function(gl) 
	{
		var d = new Date();
		this.now = d.getTime();
		scryptonite_context.audio_time = scryptonite_context.ammend_time+((this.now-this.starttime)/1000.0);
	}

	scryptonite_context.ammend_time = 0;
	
	document.onkeydown = function(evt) 
	{
		switch (evt.keyCode) 
		{
			case 37:
				scryptonite_context.ammend_time -= 1;
			break;
			case 39:
				scryptonite_context.ammend_time += 1;
			break;
		};
	};
	
}

function element_timed(start_time, end_time, e)
{
	this.start_time = start_time;
	this.end_time = end_time;
	this.element = e;
	
	
	this.init = function(gl)
	{
		this.element.init(gl);
	}
	
	this.render = function()
	{
		var now = scryptonite_context.audio_time;
		
		if (now >= start_time && now<= end_time)
		{
			this.element.render();
		}
	}
}
