(*========================================================================
 This is a small test application for GLFW.
 The program opens a window (640x480), and renders a spinning colored
 triangle (it is controlled with both the GLFW timer and the mouse). It
 also calculates the rendering speed (FPS), which is displayed in the
 window title bar.
 ======================================================================== *)


let running = ref true
let frames = ref 0

let main () =
	try
	    (* Initialise GLFW *)
		if (Glfw.init () = 0) then failwith "glfwInit failed";
		
		(* Open OpenGL window *)
		if (Glfw.open_window 640 480 0 0 0 0 0 0 Glfw.window = 0) then begin
			Glfw.terminate ();
			failwith "open_window failed";	
		end;
		
		(* Enable sticky keys *)
		Glfw.enable Glfw.sticky_keys;
		
		(* Disable vertical sync (on cards that support it) *)		
		Glfw.swap_interval 0;
		
		(* Main loop *)
		let t0 = Glfw.get_time () in
		let rec r () =
			if not !running then ()
			else begin
			
				(* Get time and mouse position *)			
				let t = Glfw.get_time () 
				and (x, y) = Glfw.get_mouse_pos () in
					if t -. t0 > 1.0 || !frames = 0 then begin
					
						(*  Calculate and display FPS (frames per second) *)					
					    let fps = float !frames /. (t -. t0) in
					    	let s = Printf.sprintf "Spinning triangle (%.1f FPS)" fps in
					    		 Glfw.set_window_title s;
					end;	
					frames := !frames + 1;	
					
					(* Get window size (may be different than the requested size) *)					
					let (width, height) = Glfw.get_window_size () in 
					let height = if height > 0 then height else 1 in
					
						(* Set viewport *)					
						GlDraw.viewport 0 0 width height;

						(* Clear color buffer *)
					    GlClear.color (((float x) /. 256.0), ((float y) /. 256.0), ((float x *. float y) /. 65530.0));
					    GlClear.clear [`color];
					    
					    (* Select and setup the projection matrix *)					    
					    GlMat.mode `projection;
					    GlMat.load_identity ();
					    GluMat.perspective ~fovy:(65.0) ~aspect:(float width /. float height) ~z:(1.0 ,100.0);
					    
					    (* Select and setup the modelview matrix *)					    
					    GlMat.mode `modelview;
						GlMat.load_identity();
					    GluMat.look_at ~eye:(0.0, 1.0, 0.0)  ~center:(0.0, 20.0, 0.0) ~up:(0.0, 0.0, 1.0);

					    (* Draw a rotating coloured triangle *)					    
					    GlMat.translate  ~y:(14.0) ();
					    GlMat.rotate  ~x:1.0  ~angle:(0.3 *. float x +. (t -. t0) *. 100.0) () ; 
					    GlDraw.begins `triangles;
							GlDraw.color (1.0, 0.0, 0.0);
							GlDraw.vertex3 ((-5.0), 0.0, (-4.0));
							GlDraw.color (0.0, 1.0, 0.0);
							GlDraw.vertex3 (5.0, 0.0, (-4.0));
							GlDraw.color (0.0, 0.0, 1.0);
							GlDraw.vertex3 (0.0, 0.0, 6.0);
					    GlDraw.ends ();
					    					
					    (* Swap buffers *)					
					    Glfw.swap_buffers ();	
					    
						(* Check if the ESC key was pressed or the window was closed *)					    
					    if ((Glfw.get_key Glfw.key_esc) = 1)  or  ((Glfw.get_window_param Glfw.opened) = 0) then running := false;		 
				r ();
			end;	
		in
		r ();	
		(* Close OpenGL window and terminate GLFW *)		
		Glfw.terminate ();
	with
		Failure s -> Printf.printf "Failure: %s\n" s
;;

main ()