/*
	Kah Liu
	Jon Dauz
	Halcyon Design for Disney ABC
	Luxo

	Main o3d javascript file for Luxo. This controls the rendering, texturing, animation and interaction for the cube. 
*/

// global config
var utilBase = "/appresource/vsi/lib/util/";
var assetBase = "/appresource/vsi/lib/assets/";

// imports
o3djs.require('o3djs.util');
o3djs.require('o3djs.math');
o3djs.require('o3djs.rendergraph');
o3djs.require('o3djs.io');
o3djs.require('o3djs.simple');
o3djs.require('o3djs.loader');
o3djs.require('o3djs.picking');
o3djs.require('o3djs.canvas');
// init() once the page has finished loading and uninit() when it's unloaded
//window.onload = start;
window.unload = uninit;

// global variables
var c3dElement;
var g_timeMult = 1.0;
var g_framesRendered = 0;
var g_c3d;
var g_math;
var g_client;
var g_viewInfo;
var g_pack;
var g_sceneRoot;
var g_c3dWidth;	 
var g_c3dHeight; 
var g_clock = 0;
var g_groupTransforms = [];
var g_textures = [];
var g_textureUrls = [
assetBase+'bkgd.jpg',  // background for all sides
assetBase+'abcsearch.png', // top ABC logo
assetBase+'btn_play.png',  // play button
assetBase+'btn_info.png',  // info button
assetBase+'btn_char.png',  // character button
assetBase+'btn_more.png',  // more button
assetBase+'bkgd2.jpg',  // background for bottom side
assetBase+'bar_red.png',
assetBase+'cube_ocean_v5.png',
assetBase+'stripe_white.png',
assetBase+'cloud.png'
];
var g_textureInfo = [];
var g_textureMoreInfo = [];
var g_moreInfo = false;
var g_moreInfoUrls = [];
var g_moreInfoTextures = [];
//var transform; // Main transform element for the cube.

var setupComplete = 0; // 0 = not ready, 1 = ready
var state = 0; // state of the app, detailed in renderCallback
var cubeState = 0; // 0=front 1=left 2=back 3=right; 
var prevCubeState = 0; // keeps track of what state the cube was in before looking at information
var resetTime = 0; // time to rotate to the cube to inital position when a new search is executed.
var time=0; // overall custom timecount (is resetted throughout states)
var g_pickInfoElem;
var g_treeInfo;
var g_selectedInfo = null;
var lastSelectedBox = 0;
var picked = 0;
var mousedown = false;
var front = true;

var y=0; // tracking camera's x, y,z
var z=0;
var x=0;

var mouseDownX = 0;
var mouseDownY = 0;
var trackX = 0;

var isAnimating = false;

var g_groupTLocation = [[1,1,1], [0,0,0]];

var fepid;
var apikey;
var timecode;

function play(episode) {
	setTimeout(function() {
		$('loader').style.display = 'none';
		$('o3d').style.display = 'none';
		$('vsi_player').style.display = 'block';
		$('move_wrapper').style.display = 'block';
		playerPage.load(episode, $('move_player'));
	}, 1000);
}

function start(fep, time, api) {
	//state = 1;
	//fep = '83977';
	//time = '00:00:15';
	api = 'e85b3b912102c8bd9a1055d1ce22df05';
	
	fepid = fep;
	timecode = time;
	apikey = api;

	init(fep, time, api);
}

function mouseup() {
	mousedown = false;
}

function mousemove(e) {
	if (mousedown && state == 4 && cubeState != 4 && !g_moreInfo) {
		var deltaX = mouseDownX - e.x;	
		var deltaY = mouseDownY - e.y;
		mouseDownX = e.x;
		mouseDownY = e.y;

		g_groupTransforms[0].rotateY(g_math.degToRad(-deltaX/2));
		trackX += -deltaX/2;
		//console.log(trackX);
	}
}

var degToTurn = 0;
var charMatch = [];
function select(pickInfo) 
{
	if(state == 0) 
	{
		state = 1;
	} 
	else 
	{
		if (!isAnimating) 
		{
			unSelectAll();
			console.log('Picked Info: ' + pickInfo.shapeInfo.shape.name);
			console.log('Cube State: ' + cubeState);
			
			if (pickInfo) 
			{
				//console.log(pickInfo);
				g_selectedInfo = pickInfo;
				//state = 5;
				if (!g_moreInfo) 
				{
					if (cubeState >= 0 && cubeState < 4) 
					{
				
						if(pickInfo.shapeInfo.shape.name.substr(0,2) == 'ss') {
							//state = 5;
						}

						if (pickInfo.shapeInfo.shape.name.substr(0,6) == 'button') {
							switch(pickInfo.shapeInfo.shape.name.substr(6)) {
								case '7':
								case '11':
								case '15':
								case '19':
									//makeBottom();
									var xCoord = (trackX)%360;
									//console.log(xCoord);
									if (pickInfo.shapeInfo.shape.name.substr(6) == 7) 
									{
										makeBottom(0);
										cubeState = 0;
										if (xCoord > 180) 
											degToTurn = xCoord-360;
										else
											degToTurn = xCoord;
									}
									else if (pickInfo.shapeInfo.shape.name.substr(6) == 11) 
									{
										makeBottom(1);
										cubeState = 3;
										if (xCoord > 180)
											degToTurn = xCoord - 270;
										else
											degToTurn = xCoord + 90;
									}
									else if (pickInfo.shapeInfo.shape.name.substr(6) ==15) 
									{
										makeBottom(2);
										cubeState = 2;
										if (xCoord > 0) 
											degToTurn = xCoord - 180;
										else 
											degToTurn = xCoord + 180;
									}
									else if (pickInfo.shapeInfo.shape.name.substr(6) == 19) 
									{
										makeBottom(3);
										cubeState = 1;
										if (xCoord < -180)
											degToTurn = xCoord + 270;
										else
											degToTurn = xCoord - 90;
									}
									trackX = trackX - degToTurn;
									//console.log(trackX);
									//console.log(degToTurn);
									//state = 13;
									break;
								case '6':
									play(g_textureInfo[0]);
									state = 15;
									break;	
								case '10':
									play(g_textureInfo[1]);
									state = 15;
									break;	
								case '14':
									play(g_textureInfo[2]);
									state = 15;
									break;	
								case '18':
									play(g_textureInfo[3]);
									state = 15;
									break;
								case '8':
								case '12':
								case '16':
								case '20':
									
									var fep;
									var time;
									var curr;

									if(pickInfo.shapeInfo.shape.name.substr(6) == '8') {
										fep = g_textureInfo[0].fep;
										time = g_textureInfo[0].time;
										curr = 0;
									}
									else if(pickInfo.shapeInfo.shape.name.substr(6) == '12') {
										fep = g_textureInfo[1].fep;
										time = g_textureInfo[1].time;
										curr = 1;
									}
									else if(pickInfo.shapeInfo.shape.name.substr(6) == '16') {
										fep = g_textureInfo[2].fep;
										time = g_textureInfo[2].time;
										curr = 2;
									}			
									else if(pickInfo.shapeInfo.shape.name.substr(6) == '20') {
										fep = g_textureInfo[3].fep;
										time = g_textureInfo[3].time;
										curr = 3;
									}
									
								var request = false;
									try {
										request = new XMLHttpRequest();
									} catch (e) {
										try {
											request = new ActiveXObject("Msxml2.XMLHTTP");
										} catch (error) {
											try {
												request = new ActiveXObject("Microsoft.XMLHTTP");
											} catch (failed) {
												request = false;
											}  
										}
									}
									
									var url = utilBase+"api.php?action=char&fep="+fep+
										"&time="+time+
										"&api="+apikey+
										"&curr="+curr+
										"&faces=4"+
										"&fep1="+g_textureInfo[0].fep+
										"&fep3="+g_textureInfo[2].fep+
										"&fep2="+g_textureInfo[1].fep+
										"&fep4="+g_textureInfo[3].fep+
										"&time1="+g_textureInfo[0].time+
										"&time2="+g_textureInfo[1].time+
										"&time3="+g_textureInfo[2].time+
										"&time4="+g_textureInfo[3].time+
										"&max=9";
									// sends the request
										request.open("GET", url, true);
										request.onreadystatechange = function() {
											if (request.readyState == 4) {
												if (request.status == 200) {
													var xml = request.responseXML;
														
													 // prases the new xml for information on the new timeframe
													for (var i=0; i<xml.childNodes[0].childNodes[0].childNodes[0].nodeValue; ++i) {
														// sets the new texture urls
														var infoObj = new Object;
																infoObj.fep = xml.childNodes[0].childNodes[1].childNodes[i].childNodes[0].childNodes[0].nodeValue;
														infoObj.fullname = xml.childNodes[0].childNodes[1].childNodes[i].childNodes[1].childNodes[0].nodeValue;
														infoObj.x = xml.childNodes[0].childNodes[1].childNodes[i].childNodes[2].childNodes[0].nodeValue;
														infoObj.y = xml.childNodes[0].childNodes[1].childNodes[i].childNodes[3].childNodes[0].nodeValue;
														infoObj.h = xml.childNodes[0].childNodes[1].childNodes[i].childNodes[4].childNodes[0].nodeValue;
														infoObj.w = xml.childNodes[0].childNodes[1].childNodes[i].childNodes[5].childNodes[0].nodeValue;
														infoObj.plane = xml.childNodes[0].childNodes[1].childNodes[i].childNodes[8].childNodes[0].nodeValue;
														charMatch[i] = infoObj;
													 }
													 createMatches();
												}
											}
										};
										request.send(null);
									break;
								case '9':
								case '13':
								case '17':
								case '21':
									var xCoord = trackX%360;
								//	console.log("xCoord: "+xCoord);
									if (pickInfo.shapeInfo.shape.name.substr(6) == 9) 
									{
										cubeState = 0;
										if (xCoord > 180) 
											degToTurn = xCoord-(360-23.4);
										else
											degToTurn = xCoord+23.4;
									}
									else if (pickInfo.shapeInfo.shape.name.substr(6) == 13) 
									{
										cubeState = 3;
										if (xCoord > 180)
											degToTurn = xCoord - (270-23.4);
										else
											degToTurn = xCoord + (90+23.4);
									}
									else if (pickInfo.shapeInfo.shape.name.substr(6) ==17) 
									{
										cubeState = 2;
										if (xCoord > 0) 
											degToTurn = xCoord - 180 - 23.4;
										else 
											degToTurn = xCoord + 180 + 23.4;
									}
									else if (pickInfo.shapeInfo.shape.name.substr(6) == 21) 
									{
										cubeState = 1;
										if (xCoord < -180)
											degToTurn = xCoord + 270-23.4;
										else
											degToTurn = (xCoord - 90+23.4);
									}
									//console.log("trackX: "+trackX);
									//console.log("degToTurn: "+degToTurn);

									trackX = trackX - degToTurn;
									//console.log(cubeState);
									state = 14;
									var request = false;
									try {
										request = new XMLHttpRequest();
									} catch (e) {
										try {
											request = new ActiveXObject("Msxml2.XMLHTTP");
										} catch (error) {
											try {
												request = new ActiveXObject("Microsoft.XMLHTTP");
											} catch (failed) {
												request = false;
											}  
										}
									}

									// gets the episode number (fep), timecode of the paused clip (timecode), and api-key from index.html's form elements.
								var fep;
								var time;
							
								if(pickInfo.shapeInfo.shape.name.substr(6) == '9') {
									fep = g_textureInfo[0].fep;
									time = g_textureInfo[0].time;
								}
								else if(pickInfo.shapeInfo.shape.name.substr(6) == '13') {
									fep = g_textureInfo[1].fep;
									time = g_textureInfo[1].time;
								}
								else if(pickInfo.shapeInfo.shape.name.substr(6) == '17') {
									fep = g_textureInfo[2].fep;
									time = g_textureInfo[2].time;
								}			
								else if(pickInfo.shapeInfo.shape.name.substr(6) == '21') {
									fep = g_textureInfo[3].fep;
									time = g_textureInfo[3].time;
								}
								var url = utilBase+"api.php?fep="+fep+"&time="+time+"&api="+apikey+"&max=9";

								// sends the request
								request.open("GET", url, true);
								request.onreadystatechange = function() {
									if (request.readyState == 4) {
										if (request.status == 200) {
											var xml = request.responseXML;
											 // prases the new xml for information on the new timeframe
											for (var i=1; i<xml.childNodes[0].firstChild.textContent; ++i) {
												// sets the new texture urls
												var infoObj = new Object;
												g_moreInfoUrls[i-1] = xml.childNodes[0].childNodes[i+1].childNodes[1].childNodes[0].nodeValue;
												infoObj.imageurl = xml.childNodes[0].childNodes[i+1].childNodes[1].childNodes[0].nodeValue;
												infoObj.time = xml.childNodes[0].childNodes[i+1].childNodes[2].childNodes[0].nodeValue;
												infoObj.fep = xml.childNodes[0].childNodes[i+1].childNodes[4].childNodes[0].nodeValue;
												infoObj.des = breakLines(xml.childNodes[0].childNodes[i+1].childNodes[7].childNodes[0].nodeValue);
											//infoObj.des = breakLines("Now prisoners of the others, head games begin for Jack, Kate, and Sawyer.");
												var epnum = xml.childNodes[0].childNodes[i+1].childNodes[5].childNodes[0].nodeValue;
												infoObj.epnum = "Season " + epnum.substring(0, 1) + ", Episode " + epnum.substring(1); 
												infoObj.epshort = xml.childNodes[0].childNodes[i+1].childNodes[6].childNodes[0].nodeValue;
												infoObj.epshow = xml.childNodes[0].childNodes[i+1].childNodes[8].childNodes[0].nodeValue
												infoObj.eptitle = infoObj.epnum + ": " + xml.childNodes[0].childNodes[i+1].childNodes[6].childNodes[0].nodeValue;
												infoObj.score = Math.round(xml.childNodes[0].childNodes[i+1].childNodes[3].childNodes[0].nodeValue).toString();
												g_textureMoreInfo[i-1] = infoObj;
											 }
											 // checks to see if the results is valid
											 if (xml.childNodes[0].firstChild.textContent > 0) {
												g_moreInfo = true;
												// load the new textures then call reskinObjects
												var loader = o3djs.loader.createLoader(createMoreInfo);
												for (var k = 0; k < g_moreInfoUrls.length; ++k) {
												  loadTexture(loader, g_moreInfoUrls[k], k, "moreInfo");
												}
												loader.finish();
											 }
											}
									}
								};
								request.send(null);
									break;
							default:
								break;
						
							}
					
						}
					} 
			 
				}
				else
				{
					if (picked == 0) {
						if(pickInfo.shapeInfo.shape.name.substr(0,2) == 'ss') {
							picked = pickInfo.shapeInfo.shape.name.substr(2) - 40;
							state = 10;
						}
					}
					else {
						console.log("Picked: " + picked);
						if (pickInfo.shapeInfo.shape.name.substr(0,6) == 'button') {
							switch(pickInfo.shapeInfo.shape.name.substr(6)) {
								case '9':
								case '169':
									play(g_textureMoreInfo[0]);
									state = 15;
									break;
								case '13':
								case '170':
									play(g_textureMoreInfo[1]);
									state = 15;
									break;
								case '17':
								case '171':
									play(g_textureMoreInfo[2]);
									state = 15;
									break;
								case '21':
								case '172':
									play(g_textureMoreInfo[3]);
									state = 15;
									break;
								case '25':
								case '173':
									play(g_textureMoreInfo[4]);
									state = 15;
									break;
								case '29':
								case '174':
									play(g_textureMoreInfo[5]);
									state = 15;
									break;
								case '33':
								case '175':
									play(g_textureMoreInfo[6]);
									state = 15;
									break;
								case '37':
								case '176':
									play(g_textureMoreInfo[7]);
									state = 15;
									break;
								case '10':
								case '177':
									selectedBox = 1;	
									state = 10;
									break;
								case '14':
								case '178':
									selectedBox = 2;	
									state = 10;
									break;
								case '18':
								case '179':
									selectedBox = 3;	
									state = 10;
									break;
								case '22': 
								case '180':
									selectedBox = 4;	
									state = 10;
									break;
								case '26':
								case '181':
									selectedBox = 5;	
									state = 10;
									break;
								case '30':
								case '182':
									selectedBox = 6;	
									state = 10;
									break;
								case '34':
								case '183':
									selectedBox = 7;	
									state = 10;
									break;
								case '38':
								case '184':
									selectedBox = 8;	
									state = 10;
									break;
							}	
							//if (selectedBox != 0) 
							//	state = 10;
						}
						else if (pickInfo.shapeInfo.shape.name.substr(0,10) == 'background') {
							if (pickInfo.shapeInfo.shape.name.substr(10) >= 0) {
								state = 12;
							}
						}
					}
				} 
			

				if(cubeState == 4) {
					console.log('Cube State: ' + cubeState);
					console.log('Picked Info: ' + pickInfo.shapeInfo.shape.name);
					if (pickInfo.shapeInfo.shape.name == "button43") {
						switch(prevCubeState) {
							case 0:
								play(g_textureInfo[0]);
								break;
							case 1:
								play(g_textureInfo[3]);
								break;
							case 2:
								play(g_textureInfo[2]);
								break;
							case 3:
								play(g_textureInfo[1]);
								break;
						}
						state = 15;
					}
					else if (pickInfo.shapeInfo.shape.name == "button44") {
						state = 8;
					}
				}  
			
			}
		 }
	}
}

var selectedBox = 0;

function updateInfo() {
  if (!g_treeInfo) {
	g_treeInfo = o3djs.picking.createTransformInfo(g_client.root,
														null);
  }
  g_treeInfo.update();
} 

function pick(e) {
  mousedown = true;
  mouseDownX = e.x;
  mouseDownY = e.y;
  var worldRay = o3djs.picking.clientPositionToWorldRay(
	  e.x,
	  e.y,
	  g_viewInfo.drawContext,
	  g_client.width,
	  g_client.height);
  unSelectAll();

  // Update the entire tree in case anything moved.
  g_treeInfo.update();
//	console.log(e);
  var pickInfo = g_treeInfo.pick(worldRay);
  if (pickInfo) {
	select(pickInfo);
  }
}

function unSelectAll() {
  if (g_selectedInfo) {
	// Remove it from the transform of the selected object.
	// Remove everything related to it.
	g_selectedInfo = null;
  }
}

function init(fep, time, api) {
	console.log('init() -- begin');
	// ajax call to to php script to execute visual search via api from ABC
	
	// create object to send request
	var request = false;
	try {
		request = new XMLHttpRequest();
	} catch (e) {
		try {
			request = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (error) {
			try {
				request = new ActiveXObject("Microsoft.XMLHTTP");
			} catch (failed) {
				request = false;
			}  
		}
	}

	// gets the episode number (fep), timecode of the paused clip (timecode), and api-key from index.html's form elements.
	//var fep = document.getElementById('fep').value;
	//var time = document.getElementById('timecode').value;
	//var api = document.getElementById('apikey').value;
	
	// url to the php scripts
	var url = utilBase+"api.php?fep="+fep+"&time="+time+"&api="+api+"&max=3";
	
	// sends the request
	request.open("GET", url, true);
	request.onreadystatechange = function() {
		if (request.readyState == 4) {
			if (request.status == 200) {
				var xml = request.responseXML;

				// get information from the xml.
				for (var i=0; i<xml.childNodes[0].firstChild.textContent; ++i) {
					// gets the texture url
					var infoObj = new Object;
					g_textureUrls[g_textureUrls.length] = xml.childNodes[0].childNodes[i+1].childNodes[1].childNodes[0].nodeValue;
					infoObj.imageurl = xml.childNodes[0].childNodes[i+1].childNodes[1].childNodes[0].nodeValue;
					infoObj.time = xml.childNodes[0].childNodes[i+1].childNodes[2].childNodes[0].nodeValue;
					infoObj.fep = xml.childNodes[0].childNodes[i+1].childNodes[4].childNodes[0].nodeValue;
					infoObj.des = breakLines(xml.childNodes[0].childNodes[i+1].childNodes[7].childNodes[0].nodeValue);
					//infoObj.des = breakLines("Now prisoners of the others, head games begin for Jack, Kate, and Sawyer.");
					var epnum = xml.childNodes[0].childNodes[i+1].childNodes[5].childNodes[0].nodeValue;
					infoObj.epnum = "Season " + epnum.substring(0, 1) + ", Episode " + epnum.substring(1); 
					infoObj.epshort = xml.childNodes[0].childNodes[i+1].childNodes[6].childNodes[0].nodeValue;
					infoObj.epshow = xml.childNodes[0].childNodes[i+1].childNodes[8].childNodes[0].nodeValue
					infoObj.eptitle = infoObj.epnum + ": " + xml.childNodes[0].childNodes[i+1].childNodes[6].childNodes[0].nodeValue;
					infoObj.score = Math.round(xml.childNodes[0].childNodes[i+1].childNodes[3].childNodes[0].nodeValue).toString();
					g_textureInfo[i] = infoObj;
				}
				// initialize o3d when the xml is parsed
				o3djs.util.makeClients(initStep2);
			}
		}
	};
	request.send(null);

	console.log('init() -- end');
}

// Unable to find text wraping, function breaks down the sentence to 45 chars each 4 lines max for the baseball card.
function breakLines(str) {
	var chars = 60;
	var length = Math.ceil(str.length/60);
	var out = [" "," "," "," "];
	for (var i=0; i<length; ++i) {
		out[i] = str.substring(i*60, (i+1)*60);
	}
	return out;
}

// cleans the unload
function uninit() {
	if (g_client) {
		g_client.cleanup();
	}
}

function createMatches() {
	for (i=0; i<charMatch.length; ++i) {
		var positionArray;
		if (charMatch[i].plane == 0) {
				positionArray = [
						-25.0, -10.0,  25.7,  // vertex 0
						 25.0, -10.0,  25.7,  // vertex 1
						-25.0,  17.6,  25.7,  // vertex 2
						 25.0,  17.6,  25.7,  // vertex 3
					];
					
		}
		else if (charMatch[i].plane == 1) {
					positionArray = [
						 25.6, -10.0,  25.5,  // vertex 0
						 25.6, -10.0,  -25.5,  // vertex 1
						 25.6,  17.6,  25.5,  // vertex 2
						 25.6,  17.6,  -25.5,  // vertex 3
					];

		}
		else if (charMatch[i].plane == 2) {
					positionArray = [
						 25.5, -10.0,  -25.6,  // vertex 1
						-25.5, -10.0,  -25.6,  // vertex 0
						 25.5,  17.6,  -25.6,  // vertex 3
						 -25.5, 17.6,  -25.6,  // vertex 2
					];
		}
		else if (charMatch[i].plane == 3) {
			var x;
			var y;
			var h = parseInt(charMatch[i].h);
			var w = parseInt(charMatch[i].w);

			if (charMatch[i].x > 255) 
				x = parseInt(charMatch[i].x) - 255;
			else
				x = -255+parseInt(charMatch[i].x);
			console.log(x);	
			
			if (charMatch[i].y > 100) 
				y = parseInt(charMatch[i].y) - 100;
			else
				y = -100+parseInt(charMatch[i].y);
			for (var i=0; i<8; ++i) {
				positionArray = getPosBox(i, 3, x, y, w, h);
				var material = createMaterial([1,1,1,1]);
				var samplerParam = material.getParam('texSampler0');
		
				var g_sampler = g_pack.createObject('Sampler');
				g_sampler.minFilter = g_c3d.Sampler.ANISOTROPIC;
				g_sampler.maxAnisotropy = 24;
				samplerParam.value = g_sampler;
			
				var plane = makeQuad(material, positionArray);
				g_groupTransforms[0].addShape(plane);
				plane.createDrawElements(g_pack, null);
				g_sampler.texture = g_textures[9]; // sets the texture

			}

		}

	}
}

function getPosBox(i, face, x, y, w, h) {
	var positionArray;
	if (face == 3) {
		switch(i) {
			case 1: 
	 			positionArray = [		
	  				 -25.7,  (y/10)-2,  x/10,  // vertex 0
					 -25.7,  (y/10)-2,  (x/10)+0.4,  // vertex 1
					 -25.7,  y/10,  x/10,  // vertex 2
					 -25.7,  y/10,  (x/10)+0.4,  // vertex 3
				];
				break;
			case 2: 
	 			positionArray = [		
		  			 -25.7,  (y/10)-0.4,  x/10,  // vertex 0
					 -25.7,  (y/10)-0.4,  (x/10)+2,  // vertex 1
					 -25.7,  y/10,  x/10,  // vertex 2
					 -25.7,  y/10,  (x/10)+2,  // vertex 3
				];
				break;
			case 3: 
	 			positionArray = [		
		  			 -25.7,  (y/10)-0.4,  x/10,  // vertex 0
					 -25.7,  (y/10)-0.4,  (x/10)+2,  // vertex 1
					 -25.7,  y/10,  x/10,  // vertex 2
					 -25.7,  y/10,  (x/10)+2,  // vertex 3
				];
				break;
			case 4: 
	 			positionArray = [		
		  			 -25.7,  (y/10)-0.4,  x/10,  // vertex 0
					 -25.7,  (y/10)-0.4,  (x/10)+2,  // vertex 1
					 -25.7,  y/10,  x/10,  // vertex 2
					 -25.7,  y/10,  (x/10)+2,  // vertex 3
				];
				break;
		}
	}
	return positionArray;
}

function makeBottom(side) {
	console.log("makeBottom() -- begin");
	
	for (var i=0; i<g_groupTransforms[0].shapes.length; ++i) {
		var name = g_groupTransforms[0].shapes[i].name;
		var positionArray;
		if (name == "bar42") {
			g_groupTransforms[0].removeShape(g_groupTransforms[0].shapes[i]);
			
			positionArray = getPosArr(42, "cube", g_textureInfo[side].score); // Bottom Red Bar
			var material = createMaterial([0,1,1,1]);
			var samplerParam = material.getParam('texSampler0');
		
			// Create a Sampler object and set the min filtering to ANISOTROPIC.  This
			// will improve the quality of the rendered texture when viewed at an angle.
			var g_sampler = g_pack.createObject('Sampler');
			g_sampler.minFilter = g_c3d.Sampler.ANISOTROPIC;
			g_sampler.maxAnisotropy = 24;
			samplerParam.value = g_sampler;
		
			// Creates a sqaure shape
			var plane = makeQuad(material, positionArray);
			
			plane.name = "bar42";
			g_groupTransforms[0].addShape(plane);
			plane.createDrawElements(g_pack, null);
			g_sampler.texture = g_textures[7]; // sets the texture
		}
		else if (name == "tb5") {
			var samplerParam = g_groupTransforms[0].shapes[i].elements[0].material.getParam('texSampler0');
			var g_sampler = g_pack.createObject('Sampler'); // create sampler
			g_sampler.minFilter = g_c3d.Sampler.ANISOTROPIC; 
			g_sampler.maxAnisotropy = 24; // large to keep quality
			samplerParam.value = g_sampler; 
			g_sampler.texture = g_textures[11+side]; // sets the texture

		}
		else if (name.substr(0,9) == "textField") {
			if (name.substr(9) >= 46) {
				g_groupTransforms[0].removeShape(g_groupTransforms[0].shapes[i]);
				i--;
			}
		}
	}
	
	for (var i = 46; i < 54; ++i) {
				positionArray = getPosArr(i, "cube"); // Bottom Red Bar
				var texture;
				//g_groupTransforms[0].removeShape(g_groupTransforms[0].shapes[i]);
				if (i == 46) {	
					var canvasLib = o3djs.canvas.create(g_pack, g_client.root, g_viewInfo);

					// Create a canvas surface to draw on.
					var canvasQuad = canvasLib.createXYQuad(0, 0, -1, 50, 15, false);
	
					canvasQuad.canvas.clear([0.098, 0.098, 0.098, 1]);
					canvasQuad.updateTexture();

					var textPaint = g_pack.createObject('CanvasPaint');
					textPaint.color = [1, 1, 1, 1];
					textPaint.textSize = 15;
					textPaint.textStyle = 1 // 1 = bold
					textPaint.textAlign = 0; // 0 = left
					textPaint.textTypeface = 'Arial';
					var text;

					text = g_textureInfo[side].score + "%";	

					canvasQuad.canvas.drawText(text, 0, 15, textPaint);
	
					canvasQuad.updateTexture();
					texture = g_pack.createTexture2D(50, 15, g_c3d.Texture.XRGB8, 1, false);
					canvasQuad.canvas.copyToTexture(texture);
				}
				else if (i == 47) {
				
					var heightOffset = 18;
					var color = 0.098;
				
					var canvasLib = o3djs.canvas.create(g_pack, g_client.root, g_viewInfo);

					// Create a canvas surface to draw on.
					var canvasQuad = canvasLib.createXYQuad(0, 0, -1, 50, heightOffset + 3, false);
	
					canvasQuad.canvas.clear([color, color, color, 1]);
					canvasQuad.updateTexture();

					var textPaint = g_pack.createObject('CanvasPaint');
					textPaint.color = [1, 1, 1, 1];
					textPaint.textSize = 14;
					//textPaint.textStyle = 0 // 1 = bold
					textPaint.textAlign = 0; // 0 = left
					textPaint.textTypeface = 'Arial';
					//	console.log(textPaint.measureText("11:11"));
					var text = g_textureInfo[side].time;

					var time = text.substring(3);
					canvasQuad.canvas.drawText(time, 3, 18, textPaint);

					canvasQuad.updateTexture();
					texture = g_pack.createTexture2D(50, heightOffset + 3, g_c3d.Texture.XRGB8, 1, false);
					canvasQuad.canvas.copyToTexture(texture);
				}
				else if (i > 47 && i < 54) {
					//console.log(name);
					//var i = parseInt(name.substr(9));
					var canvasLib = o3djs.canvas.create(g_pack, g_client.root, g_viewInfo);

					var textSize = 12;
					if (i == 52) {
						textSize = 15;
					
					}
					else if (i == 53) {
						textSize = 14;
					}
					// Create a canvas surface to draw on.
					var canvasQuad = canvasLib.createXYQuad(0, 0, -1, 465, textSize + 6, false);
					canvasQuad.canvas.clear([0.188, 0.188, 0.188, 1]);
					canvasQuad.updateTexture();

					var textPaint = g_pack.createObject('CanvasPaint');
					textPaint.color = [1, 1, 1, 1];
					textPaint.textSize = textSize;
					//textPaint.textStyle = style; // 1 = bold
					textPaint.textAlign = 0; // 0 = left
					textPaint.textTypeface = 'Arial';
				
					var text;
				
					switch(i) {
						case 48:
							text = g_textureInfo[side].des[0];
							break;
						case 49:
							text = g_textureInfo[side].des[1];
							break;
						case 50:
							text = g_textureInfo[side].des[2];
							break;
						case 51:
							text = g_textureInfo[side].des[3];
							break;
						case 52:
							text = g_textureInfo[side].epshort;
							break;
						case 53:
							text = g_textureInfo[side].epshow + " " + g_textureInfo[side].epnum;
							break;
					}
				
					canvasQuad.canvas.drawText(text, 0, textSize+1, textPaint);

					canvasQuad.updateTexture();
					texture = g_pack.createTexture2D(465, textSize + 6, g_c3d.Texture.XRGB8, 1, false);
					canvasQuad.canvas.copyToTexture(texture);	
				}
			
				var material = createMaterial([0,1,1,1]);
				var samplerParam = material.getParam('texSampler0');
		
				// Create a Sampler object and set the min filtering to ANISOTROPIC.  This
				// will improve the quality of the rendered texture when viewed at an angle.
				var g_sampler = g_pack.createObject('Sampler');
				g_sampler.minFilter = g_c3d.Sampler.ANISOTROPIC;
				g_sampler.maxAnisotropy = 24;
				samplerParam.value = g_sampler;
		
				// Creates a sqaure shape
				var plane = makeQuad(material, positionArray);
			
				plane.name = "textField"+i;
				g_groupTransforms[0].addShape(plane);
				plane.createDrawElements(g_pack, null);
				g_sampler.texture = texture; // sets the texture
	}
	state = 13;
	console.log("makeBottom() -- end");
}

// init for o3d step 2.
function initStep2(clientElements) {
	console.log('initStep2() -- begin');
	// Init global variables.
	initGlobals(clientElements);
	
	// Set up the view and projection transformations.
	initContext();
	
	updateInfo();
	
	// Sets up the listeners
	addListeners();
	
	g_sceneRoot = g_pack.createObject('Transform');
	g_sceneRoot.parent = g_client.root;
	
	// Sets the callback
	g_client.setRenderCallback(renderCallback);
	console.log('initStep2() -- end');
}

function initGlobals(clientElements) {
	console.log('initGlobals() -- begin');
	// Initializes global variables and libraries.
	c3dElement = clientElements[0];
	g_client = c3dElement.client;
	g_c3d = c3dElement.o3d;
	g_math = o3djs.math;


	// Initialize the sample javascript library.
	o3djs.base.init(c3dElement);
	// Get the width and height of our client area. We will need this to create
	// a projection matrix.
	g_c3dWidth	= c3dElement.clientWidth;
	g_c3dHeight = c3dElement.clientHeight;

	// Creates a pack to manage our resources/assets
	g_pack = g_client.createPack();

	g_viewInfo = o3djs.rendergraph.createBasicView(
	  g_pack,
	  g_client.root,
	  g_client.renderGraphRoot);
	console.log('initGlobals() -- end');
}

function initContext() {
	console.log('initContext() -- begin');
	// Create our projection matrix, with a vertical field of view of 45
	// degrees a near clipping plane of 0.1 and far clipping plane of 100.
	g_viewInfo.drawContext.projection = g_math.matrix4.perspective(
	  g_math.degToRad(45),
	  g_c3dWidth / g_c3dHeight,
	  0.1,
	  1000);

	// Set our view
	g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
		[0, 0, 2],
		[0, 0, 0],
		[0, 1, 0]);
	// Sets background to black
	g_viewInfo.clearBuffer.clearColor = [0, 0, 0, 1];

	// Load the texture from the API call
	var loader = o3djs.loader.createLoader(createObjects);
	for (var k = 0; k < g_textureUrls.length; ++k) {
	  loadTexture(loader, g_textureUrls[k], k);
	}
	loader.finish();
	console.log('initContext() -- end');
}

function createMoreInfo() {
	console.log('createMoreInfo() -- begin');
	// Create quads
	// 1-8: Slides
	// 7-40: Buttons on each slides
	// 41-48: Results
	// 49-56: % Label
	// 57-64: Time
	// 65-72: Title
	// 73-80: Red match bar
	// 81-88: Baseball card backs
	// 89-96: Back red bar
	// 97-104: Match count
	// 105-112: Time
	// 113-120: Title
	// 121-128: Season
	// 129-136: Des line 1
	// 137-144: Des line 2
	// 145-152: Des line 3
	// 153-160: Des line 4
	// 161-168: Thumb
	// 169-176: Button 1
	// 177-184: Button 2
	// 185-192: Close button
	for (var i=1; i<=184; ++i) {
		// Create a shape.
		var shape;
		// Creates the transform for everything on the quad.
		var transform = g_pack.createObject('Transform');
		
		var positionArray;
		switch (i) {
			case 73:
			case 89:
				positionArray = getPosArr(i, "moreInfo", g_textureMoreInfo[0].score);
				break;
			case 74:
			case 90:
				positionArray = getPosArr(i, "moreInfo", g_textureMoreInfo[1].score);
				break;
			case 75:
			case 91:
				positionArray = getPosArr(i, "moreInfo", g_textureMoreInfo[2].score);
				break;
			case 76:
			case 92:
				positionArray = getPosArr(i, "moreInfo", g_textureMoreInfo[3].score);
				break;
			case 77:
			case 93:
				positionArray = getPosArr(i, "moreInfo", g_textureMoreInfo[4].score);
				break;
			case 78:
			case 94:
				positionArray = getPosArr(i, "moreInfo", g_textureMoreInfo[5].score);
				break;
			case 79:
			case 95:
				positionArray = getPosArr(i, "moreInfo", g_textureMoreInfo[6].score);
				break;
			case 80:
			case 96:
				positionArray = getPosArr(i, "moreInfo", g_textureMoreInfo[7].score);
				break;
			default:
				positionArray = getPosArr(i, "moreInfo");
				break;
		}
		var texture;	
		if ((i >= 49 && i <= 72) || (i >= 97 && i <= 160)) {
			if (i >= 113 && i <= 160) {

				var canvasLib = o3djs.canvas.create(g_pack, g_client.root, g_viewInfo);

				var textSize = 12;
				if (i >= 113 && i <=120) {
					textSize = 15;
					
				}
				else if (i >= 121 && i <= 128) {
					textSize = 14;
				}
				// Create a canvas surface to draw on.
				var canvasQuad = canvasLib.createXYQuad(0, 0, -1, 465, textSize + 6, false);
				canvasQuad.canvas.clear([0.188, 0.188, 0.188, 1]);
				canvasQuad.updateTexture();

				var textPaint = g_pack.createObject('CanvasPaint');
				textPaint.color = [1, 1, 1, 1];
				textPaint.textSize = textSize;
				//textPaint.textStyle = style; // 1 = bold
				textPaint.textAlign = 0; // 0 = left
				textPaint.textTypeface = 'Arial';
				
				var text;
				if (i <= 120) {
					text = g_textureMoreInfo[(i-1)%8].epshort;
				} else if (i <= 128) {
					text = g_textureMoreInfo[(i-1)%8].epshow + " " + g_textureMoreInfo[(i-1)%8].epnum;
				} else if (i <= 136) {
					text = g_textureMoreInfo[(i-1)%8].des[0];
				} else if (i <= 144) {
					text = g_textureMoreInfo[(i-1)%8].des[1];
				} else if (i <= 152) {
					text = g_textureMoreInfo[(i-1)%8].des[2];
				} else if (i <= 160) {
					text = g_textureMoreInfo[(i-1)%8].des[3];
				}
				canvasQuad.canvas.drawText(text, 0, textSize+1, textPaint);

				canvasQuad.updateTexture();
				texture = g_pack.createTexture2D(465, textSize + 6, g_c3d.Texture.XRGB8, 1, false);
				canvasQuad.canvas.copyToTexture(texture);	
			}
			else if (i <= 56 || (i >= 97 && i<=104)) {
				var canvasLib = o3djs.canvas.create(g_pack, g_client.root, g_viewInfo);

				// Create a canvas surface to draw on.
				var canvasQuad = canvasLib.createXYQuad(0, 0, -1, 40, 15, false);

				canvasQuad.canvas.clear([0.098, 0.098, 0.098, 1]);
				canvasQuad.updateTexture();

				var textPaint = g_pack.createObject('CanvasPaint');
				textPaint.color = [1, 1, 1, 1];
				textPaint.textSize = 15;
				textPaint.textStyle = 1 // 1 = bold
				textPaint.textAlign = 0; // 0 = left
				textPaint.textTypeface = 'Arial';
				textPaint
				var text;
				switch(i) {
					case 49:
					case 97:
						text = g_textureMoreInfo[0].score + "%";	
						break;
					case 50:
					case 98:
						text = g_textureMoreInfo[1].score + "%";	
						break;
					case 51: 
					case 99:
						text = g_textureMoreInfo[2].score + "%";	
						break;
					case 52: 
					case 100:
						text = g_textureMoreInfo[3].score + "%";	
						break;
					case 53: 
					case 101:
						text = g_textureMoreInfo[4].score + "%";	
						break;
					case 54: 
					case 102:
						text = g_textureMoreInfo[5].score + "%";	
						break;
					case 55: 
					case 103:
						text = g_textureMoreInfo[6].score + "%";	
						break;
					case 56: 
					case 104:
						text = g_textureMoreInfo[7].score + "%";	
						break;
				}
				canvasQuad.canvas.drawText(text, 0, 15, textPaint);
	
				canvasQuad.updateTexture();
				texture = g_pack.createTexture2D(40, 15, g_c3d.Texture.XRGB8, 1, false);
				canvasQuad.canvas.copyToTexture(texture);
			} else if (i <= 64 || (i >= 97 && i<=112)) {
	
				var heightOffset = 15;
				var color = 0.188;

				if (i >= 97) {
					heightOffset = 14;
					color = 0.098;
				}
				var canvasLib = o3djs.canvas.create(g_pack, g_client.root, g_viewInfo);

				// Create a canvas surface to draw on.
				var canvasQuad = canvasLib.createXYQuad(0, 0, -1, 50, heightOffset, false);

				canvasQuad.canvas.clear([color, color, color, 1]);
				canvasQuad.updateTexture();

				var textPaint = g_pack.createObject('CanvasPaint');
				textPaint.color = [1, 1, 1, 1];
				textPaint.textSize = heightOffset;
				//textPaint.textStyle = 0 // 1 = bold
				textPaint.textAlign = 0; // 0 = left
				textPaint.textTypeface = 'Arial';
				var text;
				switch (i) {
					case 57:
					case 105:
						text = g_textureMoreInfo[0].time;	
						break;
					case 58:
					case 106:
						text = g_textureMoreInfo[1].time;	
						break;
					case 59:
					case 107:
						text = g_textureMoreInfo[2].time;	
						break;
					case 60:
					case 108:
						text = g_textureMoreInfo[3].time;	
						break;
					case 61:
					case 109:
						text = g_textureMoreInfo[4].time;	
						break;
					case 62:
					case 110:
						text = g_textureMoreInfo[5].time;	
						break;
					case 63:
					case 111:
						text = g_textureMoreInfo[6].time;	
						break;
					case 64:
					case 112:
						text = g_textureMoreInfo[7].time;	
						break;
				}
				var time = text.substring(3);
				canvasQuad.canvas.drawText(time, 0, heightOffset - 1, textPaint);

				canvasQuad.updateTexture();
				texture = g_pack.createTexture2D(50, heightOffset, g_c3d.Texture.XRGB8, 1, false);
				canvasQuad.canvas.copyToTexture(texture);
			} else if (i <= 72) {
				var canvasLib = o3djs.canvas.create(g_pack, g_client.root, g_viewInfo);

				// Create a canvas surface to draw on.
				var canvasQuad = canvasLib.createXYQuad(0, 0, -1, 420, 10, false);

				canvasQuad.canvas.clear([0.188, 0.188, 0.188, 1]);
				canvasQuad.updateTexture();

				var textPaint = g_pack.createObject('CanvasPaint');
				textPaint.color = [1, 1, 1, 1];
				textPaint.textSize = 11;
				//textPaint.textStyle = 0 // 1 = bold
				textPaint.textAlign = 0; // 0 = left
				textPaint.textTypeface = 'Arial';
				
				var text;
				switch(i) {
					case 65:
						text = g_textureMoreInfo[0].eptitle; 
						break;
					case 66:
						text = g_textureMoreInfo[1].eptitle; 
						break;
					case 67:
						text = g_textureMoreInfo[2].eptitle; 
						break;
					case 68:
						text = g_textureMoreInfo[3].eptitle; 
						break;
					case 69:
						text = g_textureMoreInfo[4].eptitle; 
						break;
					case 70:
						text = g_textureMoreInfo[5].eptitle; 
						break;
					case 71:
						text = g_textureMoreInfo[6].eptitle; 
						break;
					case 72:
						text = g_textureMoreInfo[7].eptitle; 
						break;
				}

				canvasQuad.canvas.drawText(text, 0, 10, textPaint);

				canvasQuad.updateTexture();
				texture = g_pack.createTexture2D(420, 10, g_c3d.Texture.XRGB8, 1, false);

				canvasQuad.canvas.copyToTexture(texture);	
			}
		}
		var material = createMaterial([0,1,1,1]);
		var samplerParam = material.getParam('texSampler0');
		// Create a Sampler object and set the min filtering to ANISOTROPIC.  This
		// will improve the quality of the rendered texture when viewed at an angle.
		var g_sampler = g_pack.createObject('Sampler');
		g_sampler.minFilter = g_c3d.Sampler.ANISOTROPIC;
		g_sampler.maxAnisotropy = 12;
		samplerParam.value = g_sampler;
		// Creates a sqaure shape
		var plane = makeQuad(material, positionArray);
		// Adds the shape to the transform with the rest of the shapes
		if (i <= 8)
			transform.addShape(plane);
		else {
			if (i <= 12 || (i>40 && i%8==1)) {
				g_groupTransforms[1].addShape(plane);
			} 
			else if (i<=16 || (i>40 && i%8==2)) {
				g_groupTransforms[2].addShape(plane);
			}
			else if (i<=20 || (i>40 && i%8==3)) {
				g_groupTransforms[3].addShape(plane);
			}
			else if (i<=24 || (i>40 && i%8==4)) {
				g_groupTransforms[4].addShape(plane);
			}
			else if (i<=28 || (i>40 && i%8==5)) {
				g_groupTransforms[5].addShape(plane);
			}
			else if (i<=32 || (i>40 && i%8==6)) {
				g_groupTransforms[6].addShape(plane);
			}
			else if (i<=36 || (i>40 && i%8==7)) {
				g_groupTransforms[7].addShape(plane);
			}
			else if (i<=40 || (i>40 && i%8==0)) {
				g_groupTransforms[8].addShape(plane);
			}
		}
		
		plane.createDrawElements(g_pack, null);

		// Sets the textures and names them
		if (i < 9) {
			g_sampler.texture = g_textures[0];
			plane.name = "background" + i;
		}
		else if (i>40 && i<=48) {
			plane.name = "ss"+i;
			g_sampler.texture = g_moreInfoTextures[i-41];
		}
		else if ((i >= 49 && i <= 72) || (i >= 97 && i<=160)) {
			g_sampler.texture = texture;  
		}
		else if ((i >= 73 && i <= 80) || (i >= 89 && i <= 96)) {
			plane.name = "bar" + i;
			g_sampler.texture = g_textures[7];
		}
		else if (i >= 81 && i <= 88) {
			plane.name = "back" + i;
			g_sampler.texture = g_textures[6];
		}
		else if (i>160 && i<=168) {
			g_sampler.texture = g_moreInfoTextures[i-161];
		}
		else if (i>168 && i<=176) {
			plane.name="button"+i;
			g_sampler.texture = g_textures[2];
		}
		else if (i>176 && i<=184) {
			plane.name="button"+i;
			g_sampler.texture = g_textures[3];
		}
		else {
			plane.name = "button"+i;
			g_sampler.texture = g_textures[((i-1)%4)+2];
		}
		transform.parent = g_sceneRoot;
		if (i <= 8)
			g_groupTransforms[i] = transform;
	}
	state = 9;
	time = 0;
	console.log('createMoreInfo() -- end');
}
var background;
function createBackground() {
	console.log('createObjects() -- begin');
	// Create a shape.
	var shape;
	// Creates the transform for everything on the cube.
	var transform = g_pack.createObject('Transform');
	
	for (var i=0; i<2; ++i) {
		if (i==0) {
			// Creates the points array for the shape
			var positionArray = [
							 -512.0,  -200, -25,  // vertex 0
							 512.0, -200, -25,	// vertex 1
							 -512.0,  0, -100,	 // vertex 2
							 512.0, 0, -100,  // vertex 3
						];
 		}
		else {
			
			var positionArray = [
							 512.0, 200, -25,	// vertex 1
							 -512.0,  200, -25,  // vertex 0
							 512.0, 0, -100,  // vertex 3
							 -512.0,  0, -100,	 // vertex 2
						];
		}

		// Creates the material
		var material = createMaterial([0,1,1,1]);
		var samplerParam = material.getParam('texSampler0');
		
		// Create a Sampler object and set the min filtering to ANISOTROPIC.  This
		// will improve the quality of the rendered texture when viewed at an angle.
		var g_sampler = g_pack.createObject('Sampler');
		g_sampler.minFilter = g_c3d.Sampler.ANISOTROPIC;
		g_sampler.maxAnisotropy = 24;
		samplerParam.value = g_sampler;
		
		// Creates a sqaure shape
		var plane = makeQuad(material, positionArray);
		// Adds the shape to the transform with the rest of the shapes
		transform.addShape(plane);
		plane.createDrawElements(g_pack, null);
		
		// Sets the textures and names them
		if (i==0)
			g_sampler.texture = g_textures[8];
		else 
			g_sampler.texture = g_textures[10];
			
		plane.name = "background" + i;
	}
	
	transform.parent = g_sceneRoot;
	background = transform;
	console.log('createObjects() -- end');
}
function createObjects() {
	console.log('createObjects() -- begin');
	// Create a shape.
	createBackground();
	var shape;
	// Creates the transform for everything on the cube.
	var transform = g_pack.createObject('Transform');
	
	// Creates shapes:
	// 1-4: Sides of cube
	// 5-6: Top and bottom of cube
	// 7-21: Buttons on the side of the cube
	// 22-25: Screenshots of results
	// 26-28: Front face text, %, time, des
	// 29-31: Right face text
	// 32-34: Back face text
	// 35-37: Left face text
	// 38-42: Red Bars
	// 43-44: Bottom buttons
	// 45: Bottom Screenshot
	// 46-47: %/Time
	// 48-51: Description
	// 52: Des Title
	// 53-54: Des Show/Season
	for (var i=0; i<=53; ++i) {

		// Creates the points array for the shape
		var positionArray;
		switch (i) {
			case 38:
				positionArray = getPosArr(i, "cube", g_textureInfo[0].score);
				break;
			case 39:
				positionArray = getPosArr(i, "cube", g_textureInfo[1].score);
				break;
			case 40:
				positionArray = getPosArr(i, "cube", g_textureInfo[2].score);
				break;
			case 41:
				positionArray = getPosArr(i, "cube", g_textureInfo[3].score);
				break;
			case 42:
				positionArray = getPosArr(i, "cube", g_textureInfo[0].score); // Bottom Red Bar
				break;
			default:
				positionArray = getPosArr(i, "cube");
				break;
		}
		var texture;
		if ((i >= 26 && i <= 37) || (i >= 46 && i <=53)) {
			if (i >= 48 && i <= 53) {

				var canvasLib = o3djs.canvas.create(g_pack, g_client.root, g_viewInfo);

				var textSize = 12;
				if (i == 52) {
					textSize = 15;
					
				}
				else if (i == 53) {
					textSize = 14;
				}
				// Create a canvas surface to draw on.
				var canvasQuad = canvasLib.createXYQuad(0, 0, -1, 465, textSize + 6, false);
				canvasQuad.canvas.clear([0.188, 0.188, 0.188, 1]);
				canvasQuad.updateTexture();

				var textPaint = g_pack.createObject('CanvasPaint');
				textPaint.color = [1, 1, 1, 1];
				textPaint.textSize = textSize;
				//textPaint.textStyle = style; // 1 = bold
				textPaint.textAlign = 0; // 0 = left
				textPaint.textTypeface = 'Arial';
				
				var text;
				
				switch(i) {
					case 48:
						text = g_textureInfo[0].des[0];
						break;
					case 49:
						text = g_textureInfo[0].des[1];
						break;
					case 50:
						text = g_textureInfo[0].des[2];
						break;
					case 51:
						text = g_textureInfo[0].des[3];
						break;
					case 52:
						text = g_textureInfo[0].epshort;
						break;
					case 53:
						text = g_textureInfo[0].epshow + " " + g_textureInfo[0].epnum;
						break;
				}
				
				canvasQuad.canvas.drawText(text, 0, textSize+1, textPaint);

				canvasQuad.updateTexture();
				texture = g_pack.createTexture2D(465, textSize + 6, g_c3d.Texture.XRGB8, 1, false);
				canvasQuad.canvas.copyToTexture(texture);	
			}
			else if ((i%3 == 2 && i != 47) || i == 46) {
				var canvasLib = o3djs.canvas.create(g_pack, g_client.root, g_viewInfo);

				// Create a canvas surface to draw on.
				var canvasQuad = canvasLib.createXYQuad(0, 0, -1, 50, 15, false);

				canvasQuad.canvas.clear([0.098, 0.098, 0.098, 1]);
				canvasQuad.updateTexture();

				var textPaint = g_pack.createObject('CanvasPaint');
				textPaint.color = [1, 1, 1, 1];
				textPaint.textSize = 15;
				textPaint.textStyle = 1 // 1 = bold
				textPaint.textAlign = 0; // 0 = left
				textPaint.textTypeface = 'Arial';
				var text;
				switch(i) {
					case 26: 
					case 46:
						text = g_textureInfo[0].score + "%";	
						break;
					case 29:
						text = g_textureInfo[1].score + "%";	
						break;
					case 32: 
						text = g_textureInfo[2].score + "%";	
						break;
					case 35: 
						text = g_textureInfo[3].score + "%";	
						break;
				}

				canvasQuad.canvas.drawText(text, 0, 15, textPaint);
	
				canvasQuad.updateTexture();
				texture = g_pack.createTexture2D(50, 15, g_c3d.Texture.XRGB8, 1, false);
				canvasQuad.canvas.copyToTexture(texture);
			} else if (i%3 == 0 || i == 47) {
	
				var heightOffset = 15;
				var color = 0.188;

				if (i == 47) {
					heightOffset = 18;
					color = 0.098;
				}
				var canvasLib = o3djs.canvas.create(g_pack, g_client.root, g_viewInfo);

				// Create a canvas surface to draw on.
				var canvasQuad = canvasLib.createXYQuad(0, 0, -1, 50, heightOffset + 3, false);

				canvasQuad.canvas.clear([color, color, color, 1]);
				canvasQuad.updateTexture();

				var textPaint = g_pack.createObject('CanvasPaint');
				textPaint.color = [1, 1, 1, 1];
				textPaint.textSize = 15;
				//textPaint.textStyle = 0 // 1 = bold
				textPaint.textAlign = 0; // 0 = left
				textPaint.textTypeface = 'Arial';
				//	console.log(textPaint.measureText("11:11"));
				var text;
				switch (i) {
					case 27:
					case 47:
						text = g_textureInfo[0].time;	
						break;
					case 30:
						text = g_textureInfo[1].time;	
						break;
					case 33:
						text = g_textureInfo[2].time;	
						break;
					case 36:
						text = g_textureInfo[3].time;	
						break;
				}
				var time = text.substring(3);
				canvasQuad.canvas.drawText(time, 0, heightOffset + 1, textPaint);

				canvasQuad.updateTexture();
				texture = g_pack.createTexture2D(50, heightOffset + 3, g_c3d.Texture.XRGB8, 1, false);
				canvasQuad.canvas.copyToTexture(texture);
			} else if (i%3 == 1) {
				var canvasLib = o3djs.canvas.create(g_pack, g_client.root, g_viewInfo);

				// Create a canvas surface to draw on.
				var canvasQuad = canvasLib.createXYQuad(0, 0, -1, 420, 17, false);

				canvasQuad.canvas.clear([0.188, 0.188, 0.188, 1]);
				canvasQuad.updateTexture();

				var textPaint = g_pack.createObject('CanvasPaint');
				textPaint.color = [1, 1, 1, 1];
				textPaint.textSize = 11;
				//textPaint.textStyle = 0 // 1 = bold
				textPaint.textAlign = 0; // 0 = left
				textPaint.textTypeface = 'Arial';
				
				var text;
				switch(i) {
					case 28:
						text = g_textureInfo[0].eptitle; 
						break;
					case 31:
						text = g_textureInfo[1].eptitle; 
						break;
					case 34:
						text = g_textureInfo[2].eptitle; 
						break;
					case 37:
						text = g_textureInfo[3].eptitle; 
						break;
				}

				canvasQuad.canvas.drawText(text, 0, 14, textPaint);

				canvasQuad.updateTexture();
				texture = g_pack.createTexture2D(420, 17, g_c3d.Texture.XRGB8, 1, false);
				canvasQuad.canvas.copyToTexture(texture);	
			}
		}
		// Creates the material
		var material = createMaterial([0,1,1,1]);
		var samplerParam = material.getParam('texSampler0');
		
		// Create a Sampler object and set the min filtering to ANISOTROPIC.  This
		// will improve the quality of the rendered texture when viewed at an angle.
		var g_sampler = g_pack.createObject('Sampler');
		g_sampler.minFilter = g_c3d.Sampler.ANISOTROPIC;
		g_sampler.maxAnisotropy = 24;
		samplerParam.value = g_sampler;
		
		// Creates a sqaure shape
		var plane = makeQuad(material, positionArray);
		// Adds the shape to the transform with the rest of the shapes
		transform.addShape(plane);
		plane.createDrawElements(g_pack, null);
		
		// Sets the textures and names them
		if (i <= 3) {
			g_sampler.texture = g_textures[0];
			plane.name = "background" + i;
		}
		else if (i == 4) { // top 
			g_sampler.texture = g_textures[1];
			plane.name = "top";
		}
		else if (i == 5) {
				g_sampler.texture = g_textures[6];
			plane.name = "bottom";
		}
		else if (i == 22) {
			plane.name = "ss1";
			g_sampler.texture = g_textures[11];
		}
		else if (i == 23) {
			g_sampler.texture = g_textures[12];
			plane.name = "ss2";
		}
		else if (i == 24) {
			g_sampler.texture = g_textures[13];
			plane.name = "ss3";
		}
		else if (i == 25) {
			plane.name = "ss4";
			g_sampler.texture = g_textures[14];
		}
		else if ((i >= 26 && i <= 37) || (i>=46 && i<=53)) {
			plane.name = "textField"+i;
			g_sampler.texture = texture;

		}
		else if (i >= 38 && i <= 42) {
			plane.name = "bar" + i;
			g_sampler.texture = g_textures[7];
		}
		else if (i == 43) {
			plane.name = "button" + i;
			g_sampler.texture = g_textures[2];
		}
		else if (i == 44) {
			plane.name = "button" + i;
			g_sampler.texture = g_textures[3];
		}
		else if (i == 45) {
			plane.name = "tb5";
			g_sampler.texture = g_textures[9];
		}
		else {
			plane.name = "button" + i;
			g_sampler.texture = g_textures[((i-2)%4)+2];
		}
	}
	
	transform.parent = g_sceneRoot;
	g_groupTransforms[0] = transform;
	setupComplete = 1;
	
	console.log('createObjects() -- end');
	console.log('Version ' + version);
}

// Loads texture into an array
function loadTexture(loader, url, index, type) {
	//console.log(url);
	if (type == 'moreInfo') {
		loader.loadTexture(g_pack, url, function(texture) {
			g_moreInfoTextures[index] = texture;
		});
	}
	else {
		loader.loadTexture(g_pack, url, function(texture) {
			g_textures[index] = texture;
		});
	}
}

// Adds listeners
function addListeners() {
	console.log('addListeners() -- begin');
	o3djs.event.addEventListener(c3dElement, 'mousedown', pick);
	o3djs.event.addEventListener(c3dElement, 'mousemove', mousemove);
	o3djs.event.addEventListener(c3dElement, 'mouseup', mouseup);
	console.log('addListeners() -- end');
}

// Change states according to user interaction.
function changeState() {
	console.log('changeState() -- begin');
	switch (state) {
		case 0: state = 1; break; // From stationary to moving
		case 1: state = 2; break; 
		case 4: state = 5; break; // Spins 90 degree CW
	}
	console.log('changeState() -- end');
}

var time2 = 0;
var timeX = 0;
var timeY = 2.55;
var timeZ = 0;
var bx = 0;
var by = 0;
var bz = 0;

pState = 0;
// Runs every frame, controls animation and timeline.
function renderCallback(render) {
	if (state != pState) {
		console.log("State: " + state);
		pState = state;
	}
//	console.log(time);
	if (setupComplete) {
		// Decides which states to be in
		switch (state) {
			// Stationary (video viewing mode)
			case 0: 
				time=0;
				g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
				[0, 2.55, 70], //eye
				[0, 2.55, 0], //target
				[0, 1, 0]); //up
				state = 1;
				break;
			// Camera zooms out and up while looking at the cube
			case 1:
				isAnimating = true;
				g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
				[0, (time/50)*51, 70+((time/100)*51)], //eye
				[0, 2.55, 0], //target
				[0, 1, 0]); //up
				y=(time/50)*51;
				z=(70+(time/100)*51);
				time++;
				if (time == 70) {
					state = 2;
					time = 0;
				}
				break;
			// Camera zooms out a little while camera goes back down to 0 (y).
			case 2:
				background.rotateY(time/10000);
				g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
					[(time/80)*51, y-((time/80)*51), z+((time/250)*51)], //eye
					[0, 2.55, 0], //target
					[0, 1, 0]); //up
				time++;
				g_groupTransforms[0].rotateY(0.047);//2.693 degree // Total: 298.92 degrees
				if (((y-(time/80)*51)) < 0) {
					x=(time/80)*51;
					y=y-(time/80)*51;
					z=z+((time/250)*51);
					state = 3;
					time=0;
				}
				break;
			// Ease out and bounce
			case 3:
				time++;
				if (time<100) {
					g_groupTransforms[0].rotateY(((500-(time*6))/10000));	
				}
				
				if (time>=110) {
					time=0;
					isAnimating = false;
					//g_groupTransforms[0].rotateY == 0;
					state = 4;
				}	
				break;
			// Rotates 90 CW
			case 4:
				isAnimating = false;
				break;
			case 5:
				isAnimating = true;
				g_groupTransforms[0].rotateY(g_math.degToRad(4.5)); // 4.5 degrees per timeframe
				time++;
				
				if (time >= 20) {
					g_groupTransforms[0].rotateY(0);
					time = 0;
					state = 4;
					if (cubeState != 3)
						cubeState = cubeState + 1;
					else
						cubeState = 0;
				}
				break;
			// Resets cube when a new texture is loaded
			case 6:
				isAnimating = true;
				g_groupTransforms[0].rotateY(g_math.degToRad(-4.5))
				time++;
				if (time >= resetTime) {
					g_groupTransforms[0].rotateY(0);
					resetTime = 0;
					cubeState = 0;
					time = 0;
					state = 4;
				}
				break;
			case 13:
				time++;
				g_groupTransforms[0].rotateY(g_math.degToRad(-degToTurn/10));
				if (time >= 10) {
					degToTurn = 0;
					time = 0;
					state = 7;
				}
				break;
			case 7: // When user clicks "information" cube will rotate to bottom
				isAnimating = true;
				switch(cubeState) {
				
					case 0: 
						g_groupTransforms[0].rotateX(g_math.degToRad(-4.5)); // -4.5 degrees per timeframe upward
						g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
							[x+(time/50), 0, z-(time*3.75)], //eye
							[0, 2.55, 0], //target
							[0, 1, 0]); //up	
					break;
					
					case 1: 
						g_groupTransforms[0].rotateZ(g_math.degToRad(-4.5));
						g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
							[x+(time/50), 0, z-(time*3.75)], //eye
							[0, 2.55, 0], //target
							[0, 1, 0]); //up	
					break;
					
				
					case 2: 
						g_groupTransforms[0].rotateX(g_math.degToRad(4.5)); // -4.5 degrees per timeframe upward
						g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
							[x+(time/50), 0, z-(time*3.75)], //eye
							[0, 2.55, 0], //target
							[0, 1, 0]); //up
					break;
						
					case 3:
						g_groupTransforms[0].rotateZ(g_math.degToRad(4.5));
						g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
							[x+(time/50), 0, z-(time*3.75)], //eye
							[0, 2.55, 0], //target
							[0, 1, 0]); //up
					break;
				}
				
				time++;
				
				if (time == 1) { // Sets the prevCubeState at time 1
					prevCubeState = cubeState;
				}
				else if (time == 20) { // Stop animation at time 20 (90 degrees), sets cubeState to bottom
					g_groupTransforms[0].rotateY(0);
					g_groupTransforms[0].rotateX(0)
					
					x=x+(time/50);
					z=z-(time*3.75); 
					
					//g_groupTransforms[0].rotateZ(g_math.degToRad(-24));
					cubeState = 4;
				}
				
				// Turn and focus the cube to the camera
				if (time > 20) { 
					if (time <= 20+(prevCubeState*20)) {
						
						g_groupTransforms[0].rotateY(g_math.degToRad(-4.5));
						
					}
					else {
						time = 0;
						state = 4;
						
						g_groupTransforms[0].rotateY(0);						
					}
				}
				break;
			case 8: // Returns to side of cube before looking at information
				isAnimating = true;
				if (time < (prevCubeState*20)) {
					if (prevCubeState != 0)
						g_groupTransforms[0].rotateY(g_math.degToRad(4.5));

				}
				else if (time == (prevCubeState*20)) {
					g_groupTransforms[0].rotateY(0);						
				}
				
				if (time > ((prevCubeState*20) - 1)) {
				
					switch(prevCubeState) {
				
						case 0:
							g_groupTransforms[0].rotateX(g_math.degToRad(4.5)); // -4.5 degrees per timeframe upward
							g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
								[x-(time/50), 0, z+(time*3.75)], //eye
								[0, 2.55, 0], //target
								[0, 1, 0]); //up
						break;
						
						case 1:
							g_groupTransforms[0].rotateZ(g_math.degToRad(4.5));
							g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
								[x-((time-(prevCubeState*20))/50), 0, z+((time-(prevCubeState*20))*3.75)], //eye
								[0, 2.55, 0], //target
								[0, 1, 0]); //up
						break;
						
						case 2:
							g_groupTransforms[0].rotateX(g_math.degToRad(-4.5)); // -4.5 degrees per timeframe upward
							g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
								[x-((time-(prevCubeState*20))/50), 0, z+((time-(prevCubeState*20))*3.75)], //eye
								[0, 2.55, 0], //target
								[0, 1, 0]); //up
						break;
					
						case 3:
							g_groupTransforms[0].rotateZ(g_math.degToRad(-4.5));
							g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
								[x-((time-(prevCubeState*20))/50), 0, z+((time-(prevCubeState*20))*3.75)], //eye
								[0, 2.55, 0], //target
								[0, 1, 0]); //up
						break;
				
						}
				}
				time++;
				if (time == (prevCubeState*20)+20) {
					if(prevCubeState == 0){
						x=x-(time/50);
						z=z+(time*3.75); 
					}
					else {
						x=x-((time-(prevCubeState*20))/50);
						z=z+((time-(prevCubeState*20))*3.75); 
				
					}					
					g_groupTransforms[0].rotateY(0);
					g_groupTransforms[0].rotateX(0);
					time = 0;
					state = 4;
					cubeState = prevCubeState;
					
				}	
				break;
			case 9:
				time++;
				isAnimating = true;

				//g_groupTransforms[0].translate(time-10, time-10, time-10);
				if (x-(time*2) >= 0) {
					//time2++;
					background.rotateY(g_math.degToRad(-0.5));
					g_groupTransforms[0].rotateZ(g_math.degToRad(0.75));
					g_groupTransforms[0].translate(time/50, -time/10 , 0);
					moveInstance(g_groupTransforms[1], -1.7*time, 1.7*time, 0);
					moveInstance(g_groupTransforms[2], 0, 1.7*time, 0);
					moveInstance(g_groupTransforms[3], 1.7*time, 1.7*time, 0);
					moveInstance(g_groupTransforms[4], -1.7*time, 0, 0);
					moveInstance(g_groupTransforms[5], 1.7*time, 0, 0);
					moveInstance(g_groupTransforms[6], -1.7*time, -1.7*time, 0);
					moveInstance(g_groupTransforms[7], 0, -1.7*time, 0);
					moveInstance(g_groupTransforms[8], 1.7*time, -1.7*time, 0);
					
					g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
						[x-(time*2), 0, z+(time*3)], //eye
						[0, -2.55, 0], //target
						[0, 1, 0]); //up



				}
				else if (time < 54) {
					g_groupTransforms[0].rotateX(g_math.degToRad(-5));
				} else if (time < 64) {
					if (cubeState == 0)
						g_groupTransforms[0].rotateY(g_math.degToRad(0));
					else if (cubeState == 1)
						g_groupTransforms[0].rotateY(g_math.degToRad(9));
					else if (cubeState == 2)
						g_groupTransforms[0].rotateY(g_math.degToRad(18));
					else if (cubeState == 3)
						g_groupTransforms[0].rotateY(g_math.degToRad(-9));
					
				}
				else {
						//time = 35

						x = x-(70);
						z = z+(35*3);
						y = 0;

						bx = x;
						by = y;
						bz = z;

						time = 0;
						state = 4;
				}
				break;
			case 10:
				time++;
				isAnimating = true;
				//g_groupTransforms[selectedBox].rotateY(g_math.degToRad(5));
				if (picked != 0 && selectedBox == 0) {
					switch (picked) {
						case 1: 
							g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
								[x-(time*1.652), y+(time*1.652), z-(time*3.75)], //eye
								[-time*1.652, 2.55+(time*1.652), 0], //target
								[0, 1, 0]); //up
						
							break;
						case 2: 
							g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
								[x, y+(time*1.652), z-(time*3.75)], //eye
								[0, 2.55+(time*1.652), 0], //target
								[0, 1, 0]); //up

							break;
						case 3: 
							g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
								[x+(time*1.652), y+(time*1.652), z-(time*3.75)], //eye
								[time*1.652, 2.55+(time*1.652), 0], //target
								[0, 1, 0]); //up
							break;
						case 4: 
							g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
								[x-(time*1.652), y, z-(time*3.75)], //eye
								[-time*1.652, 2.55, 0], //target
								[0, 1, 0]); //up
							break;
						case 5: 
							g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
								[x+(time*1.652), y, z-(time*3.75)], //eye
								[time*1.652, 2.55, 0], //target
								[0, 1, 0]); //up
							break;
						case 6: 
							g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
								[x-(time*1.652), y-(time*1.652), z-(time*3.75)], //eye
								[-time*1.652, 2.55-(time*1.652), 0], //target
								[0, 1, 0]); //up
							break;
						case 7: 
							g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
								[x, y-(time*1.652), z-(time*3.75)], //eye
								[0, 2.55-(time*1.652), 0], //target
								[0, 1, 0]); //up
							break;
						case 8: 
							g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
								[x+(time*1.652), y-(time*1.652), z-(time*3.75)], //eye
								[time*1.652, 2.55-(time*1.652), 0], //target
								[0, 1, 0]); //up
							break;
					}
					if (time == 36) {
						state = 4;
						var prevTime = time - 1;
						g_groupTransforms[selectedBox].rotateY(0);

						switch(picked) {
							case 1:
								x = x-(prevTime*1.652);
								y = y+(prevTime*1.652);
								z = z-(prevTime*3.75); //eye
								timeX = -prevTime*1.652
								timeY = 2.55+(prevTime*1.652); //target
								break;
							case 2:
								y = y+(prevTime*1.652);
								z = z-(prevTime*3.75); //eye
								timeY = 2.55+(time*1.652); //target
								break;
							case 3:
								x = x+(prevTime*1.652);
								y = y+(prevTime*1.652);
								z= z-(prevTime*3.75); //eye
								timeX = time*1.652
								timeY = 2.55+(time*1.652); //target
								break;
							case 4:
								x = x-(prevTime*1.652);
								z = z-(prevTime*3.75);
								timeX = -time*1.652; //target
								break;
							case 5:
								x = x+(time*1.652);
								z = z-(time*3.75); //eye
								timeX = time*1.652; //target
								break;
							case 6:
								x = x-(time*1.652);
								y = y-(time*1.652);
								z = z-(time*3.75); //eye
								timeX = -time*1.652;
								timeY = 2.55-(time*1.652); //target
								break;
							case 7:
								y = y-(time*1.652);
								z = z-(time*3.75); //eye
								timeY = 2.55-(time*1.652); //target
								break;
							case 8:
								x = x+(time*1.652);
								y = y-(time*1.652);
								z = z-(time*3.75); //eye
								timeX = time*1.652;
								timeY = 2.55-(time*1.652); //target
								break;
						}
						lastSelectedBox = picked;
						selectedBox = picked;
						time = 0;
						//picked = 0;
					}
				}
				else {
					g_groupTransforms[selectedBox].rotateY(g_math.degToRad(5));
					
					if (time == 36) {
						state = 4;
						//var prevTime = time - 1;
						g_groupTransforms[selectedBox].rotateY(0);
						lastSelectedBox = selectedBox;
						if (front)
							front = false; //negated to show back of card
						else
							front = true;
						time = 0;
					}
				}
				break;
			case 14:
				time++;
				g_groupTransforms[0].rotateY(g_math.degToRad(-degToTurn/10));
				if (time >= 10) {
					degToTurn = 0;
					time = 0;
					state = 11;
				}
				break;
			case 11:
				isAnimating = true;
				time++;
			//	if (time < 18) {
			//		console.log("1: "+time);
			//		g_groupTransforms[0].rotateY(g_math.degToRad(-1.3));
			//	}
				if (time <= 18) {
					console.log("2: "+time);
					if (cubeState == 0)
						g_groupTransforms[0].rotateX(g_math.degToRad(5));
					else if (cubeState == 1)
						g_groupTransforms[0].rotateZ(g_math.degToRad(5));
					else if (cubeState == 2)
						g_groupTransforms[0].rotateX(g_math.degToRad(-5));
					else if (cubeState == 3)
						g_groupTransforms[0].rotateZ(g_math.degToRad(-5));
				}
				else if (time <= 28) {
					console.log("3: "+time);
					if (cubeState == 0)
						g_groupTransforms[0].rotateY(g_math.degToRad(0));
					else if (cubeState == 1)
						g_groupTransforms[0].rotateY(g_math.degToRad(-9));
					else if (cubeState == 2)
						g_groupTransforms[0].rotateY(g_math.degToRad(18));
					else if (cubeState == 3)
						g_groupTransforms[0].rotateY(g_math.degToRad(9));
				}
				else
				{
					time = 0;
					state = 4;

				}

				break;
			case 12:
				isAnimating = true;
				time++;
				if (!front)
					g_groupTransforms[lastSelectedBox].rotateY(g_math.degToRad(5));

				switch (lastSelectedBox) {
					case 1: 
						g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
							[x+(time*1.652), y-(time*1.652), z+(time*3.75)], //eye
							[timeX + time*1.652, timeY+(2.55-(time*1.652)), 0], //target
							[0, 1, 0]); //up
						break;
					case 2: 
						g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
							[x, y-(time*1.652), z+(time*3.75)], //eye
							[0, timeY + (2.55-(time*1.652)), 0], //target
							[0, 1, 0]); //up
						break;
					case 3: 
						g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
							[x-(time*1.652), y-(time*1.652), z+(time*3.75)], //eye
							[timeX-time*1.652, timeY + (2.55-(time*1.652)), 0], //target
							[0, 1, 0]); //up
						break;
					case 4: 
						g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
							[x+(time*1.652), y, z+(time*3.75)], //eye
							[timeX+time*1.652, 2.55, 0], //target
							[0, 1, 0]); //up
						break;
					case 5: 
						g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
							[x-(time*1.652), y, z+(time*3.75)], //eye
							[timeX-time*1.652, 2.55, 0], //target
							[0, 1, 0]); //up
						break;
					case 6: 
						g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
							[x+(time*1.652), y+(time*1.652), z+(time*3.75)], //eye
							[timeX+time*1.652, timeY+(2.55+(time*1.652)), 0], //target
							[0, 1, 0]); //up
						break;
					case 7: 
						g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
							[x, y+(time*1.652), z+(time*3.75)], //eye
							[0, timeY+(2.55+(time*1.652)), 0], //target
							[0, 1, 0]); //up
						break;
					case 8: 
						g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
							[x-(time*1.652), y+(time*1.652), z+(time*3.75)], //eye
							[timeX-time*1.652, timeY+(2.55+(time*1.652)), 0], //target
							[0, 1, 0]); //up
						break;
				}
				if (time == 36) {
					x = bx;
					y = by;
					z = bz;
					state = 4;
					time = 0;
					picked = 0;
					selectedBox = 0;
					lastSelectedBox = 0;
					g_groupTransforms[lastSelectedBox].rotateY(0);
				}
				break;
			case 15:
				time++;
				g_viewInfo.drawContext.view = g_math.matrix4.lookAt(
					[x, y+(time*3), z], //eye
					[0, 2.55+(time*5), -time*5], //target
					[0, 1, 0]); //up
				break;	
			default:
				break;
		}
	}
}


function moveInstance(node, x, y, z) {
	node.identity();
	node.translate(x, y, z);
}

// Creates a material
function createMaterial(baseColor) {
	//	console.log('createMaterial() -- begin');
	// Create a new, empty Material object.
	var material = g_pack.createObject('Material');
	material.drawList = g_viewInfo.performanceDrawList;

	var effect = g_pack.createObject('Effect');
	var shaderString = document.getElementById('effect').value;
	effect.loadFromFXString(shaderString);
	material.effect = effect;
	
	effect.createUniformParameters(material);
	var g_cubeColorParam = material.getParam('color');
	g_cubeColorParam.value = baseColor;
	//	console.log('createMaterial() -- end');
	return material;
}

// Makes a sqaure shape
function makeQuad(material, positionArray) {
	// console.log('makeQuad() -- begin');
	var quad = g_pack.createObject('Shape');
	var quadPrimitive = g_pack.createObject('Primitive');
	var streamBank = g_pack.createObject('StreamBank');
	quadPrimitive.material = material;
	quadPrimitive.owner = quad;
	quadPrimitive.streamBank = streamBank;

	quadPrimitive.primitiveType = g_c3d.Primitive.TRIANGLELIST;
	quadPrimitive.numberPrimitives = 2;
	quadPrimitive.numberVertices = 4;

	var texCoordsArray = [
	0, 0,
	1, 0,
	0, 1,
	1, 1
	];

	var indexArray = [0, 1, 2, 
	2, 1, 3];

	var positionsBuffer = g_pack.createObject('VertexBuffer');
	var positionsField = positionsBuffer.createField('FloatField', 3);
	positionsBuffer.set(positionArray);

	var texCoordsBuffer = g_pack.createObject('VertexBuffer');
	var texCoordsField = texCoordsBuffer.createField('FloatField', 2);
	texCoordsBuffer.set(texCoordsArray);

	var indexBuffer = g_pack.createObject('IndexBuffer');
	indexBuffer.set(indexArray);

	streamBank.setVertexStream(
		g_c3d.Stream.POSITION, // semantic: This stream stores vertex positions
		0,					 // semantic index: First (and only) position stream
		positionsField,		 // field: the field this stream uses.
		0);					 // start_index: How many elements to skip in the
		//		field.

		// Associate the texture coordinates buffer with the primitive.
	streamBank.setVertexStream(
		g_c3d.Stream.TEXCOORD,  // semantic
		0,					  // semantic index
		texCoordsField,		  // field
		0);					  // start_index

		// Associate the triangle indices Buffer with the primitive.
	quadPrimitive.indexBuffer = indexBuffer;
		//console.log('makeQuad() -- end');
	return quad;
}

function makeQuadNoTex(material, positionArray) {
	// console.log('makeQuad() -- begin');
	var quad = g_pack.createObject('Shape');
	var quadPrimitive = g_pack.createObject('Primitive');
	var streamBank = g_pack.createObject('StreamBank');
	quadPrimitive.material = material;
	quadPrimitive.owner = quad;
	quadPrimitive.streamBank = streamBank;

	quadPrimitive.primitiveType = g_c3d.Primitive.TRIANGLELIST;
	quadPrimitive.numberPrimitives = 2;
	quadPrimitive.numberVertices = 4;



	var indexArray = [0, 1, 2, 
	2, 1, 3];

	var positionsBuffer = g_pack.createObject('VertexBuffer');
	var positionsField = positionsBuffer.createField('FloatField', 3);
	positionsBuffer.set(positionArray);

	var indexBuffer = g_pack.createObject('IndexBuffer');
	indexBuffer.set(indexArray);

	streamBank.setVertexStream(
		g_c3d.Stream.POSITION, // semantic: This stream stores vertex positions
		0,					 // semantic index: First (and only) position stream
		positionsField,		 // field: the field this stream uses.
		0);					 // start_index: How many elements to skip in the
		//		field.

		// Associate the triangle indices Buffer with the primitive.
	quadPrimitive.indexBuffer = indexBuffer;
		//console.log('makeQuad() -- end');
	return quad;
}
