
function MiracleOfChile () {
	var overlay;//ko
	var sky;//ko
	overlay=document.getElementById("overlay");//ko
	sky=document.getElementById("sky");


var $ = function(id) { return document.getElementById(id); };
var dc = function(tag) { return document.createElement(tag); };

var fDegRad = Math.PI / 180;
var fTwoPI = Math.PI * 2;

var iScreenWidth = 820;
var iScreenHeight = 600;
var iLineWidth = 3;//ko->was 3 IMPACTS RESOLUTION ->lower number higher rez, higher number lower rez
var fFOV = 60 * fDegRad;//was 60 IMPACTS FIELD OF VIEW ->lower number brings things closer higher number creates distance

var bTexturedWalls = true;

var bRenderMap = !!($("topmap").getContext && $("topmap").getContext("2d"));
var bRenderPlayerOnMap = true;

var bHighResFlickr = true;//was false SWITCH FOR QUALITY of Flickr IMAGES.  True slows down the engine of course

var oPlayer = {
	x : 34.51 * 64, // current x, y position
	y : 56.5 * 64, 
	speed : 0, // is the playing moving forward (speed = 1) or backwards (speed = -1).
	speedinc : 0,
	rotation : fTwoPI * -0.25,
	rotincdir : 0, // the current angle of rotation 
	rotinc : 0,
	cpu : false,
	lastmovetime : 0
}


var iNumWallTextures = 17;//17 is magic

var aWallTexCnv = [];


var aWalls;

var fHalfFOV = fFOV/2;
var fColWidth = fFOV / iScreenWidth;

var fViewDist = (iScreenWidth/2) / Math.tan((fFOV / 2));

var fWallHeight = (64 * fViewDist);//

var iLevelWidth = 64;//was 64
var iLevelHeight = 64;//was 64

var oCtr = $("container");
var oTopMap = $("topmap");
var oTopMapPlayer = $("topmapplayer");

var aLines = [];

var fTopMapScale = 1;

function initScreen() {

	if (aLines.length) {
		for (var i=0;i<aLines.length;i++) {
			if (aLines[i]) {
				oCtr.removeChild(aLines[i]);
			}
		}
		aLines = [];
	}
	for (var i=0;i<iScreenWidth;i+=iLineWidth) {
		var oLine = dc("div");
		oLine.style.position = "absolute";
		oLine.style.left = i + "px";
		oLine.style.width = iLineWidth+"px";//orig-> iLineWidth+"px" IMPACTS TEXTURE (NOT IMAGE) WIDTH by adding "+32" or something  WORKS WITH LINE 500
		oLine.style.height = "0px";
		oLine.style.overflow = "hidden";

		oLine.style.backgroundColor = "black";

		var oImg = new Image();
		oImg.src = (window.opera ? "images/walls_19color.png" : "images/walls.png");
		oImg.style.position = "absolute";
		oImg.style.left = "0px";
		oImg.style.border = "none";
		oImg.style.padding = "0px";
		oImg.style.margin = "0px";
		oLine.appendChild(oImg);
		oLine.img = oImg;
	
		oLine.linedesc = {};
	
		aLines[i] = oLine;
		oLine.flickr = [];
		oCtr.appendChild(oLine);
		

	}


}

function loadLevel(strLevel) {
	aWalls = [];
	aEnemies = [];
	aSprites = [];

	XHR("levels/moc.map",//yeah!!! 
		function(oHTTP) {
			oLevel = eval("("+oHTTP.responseText+")");
			prepLevel();
			setDescText("Game loaded, drawing map...");
			setTimeout(onLevelLoaded, 10);
		}
	);
}

function prepLevel() {
	aWalls = oLevel.walls;
	aSprites = oLevel.sprites;
	prepSprites();
}

var aSpriteTextures = [];
aSpriteTextures[1] = "sprites/dog.png";
aSpriteTextures[2] = "sprites/pinera.png";
aSpriteTextures[3] = "sprites/victor1.png";
aSpriteTextures[4] = "sprites/victor2.png";
aSpriteTextures[5] = "sprites/victor3.png";
//aSpriteTextures[6] = "sprites/";
aSpriteTextures[7] = "sprites/dog.png";
aSpriteTextures[8] = "sprites/friedman3.png";
aSpriteTextures[9] = "sprites/hydrant.png";
aSpriteTextures[10] = "sprites/dog2.png";
aSpriteTextures[11] = "sprites/trashCan.png";
aSpriteTextures[12] = "sprites/totem.png";
//aSpriteTextures[13] = "sprites/";
//aSpriteTextures[14] = "sprites/";
//aSpriteTextures[15] = "sprites/";
aSpriteTextures[16] = "sprites/pinera.png";
aSpriteTextures[17] = "sprites/bachelete.png";


var aSpriteImg = [];

function prepSprites() {
	for (var y=0;y<iLevelHeight;y++) {
		aSpriteImg[y] = [];
		for (var x=0;x<iLevelWidth;x++) {
			if (aSprites[y][x]) {
				var iIdx = aSprites[y][x];
				var oImg = new Image();
				oImg.src = aSpriteTextures[iIdx];
				oImg.style.position = "absolute";
				oImg.style.display = "none";
				oImg.style.left = oImg.style.top = "0px";
				oImg.style.border = "none";
				oImg.style.padding = "0px";
				oImg.style.margin = "0px";

				oImg.posx = x * 64 + 32;
				oImg.posy = y * 64 + 32;
				aSpriteImg[y][x] = oImg;
				oCtr.appendChild(oImg);
				
			}
		}
	}
}

var iMoveTimer = 1000 / 30;
var bRunning = false;


var iIntervalLogic;
var iIntervalRender;

function startGame() {
	bRunning = true;
	oPlayer.lastmovetime = new Date().getTime();

	if (!iIntervalLogic)
		iIntervalLogic = setInterval(logic,1000/30);
	if (!iIntervalRender)
		iIntervalRender = setInterval(render,1000/20);

	$("flickrusernamebtn").disabled = false;
	$("flickrsearchbtn").disabled = false;

	$("splash-div").style.display = "none";//splash screen if we want it
}

function logic() {
	if (!bRunning) return false;

	move(oPlayer);
	
}

var aVisibleSprites = [];

var oLookingAtImg;

var oMapPlayerCtx = oTopMapPlayer.getContext("2d");

function render() {
	if (!bRunning) return false;

	if (bRenderMap && bRenderPlayerOnMap) {
		//oTopMapPlayer.width = oTopMapPlayer.width;
		oMapPlayerCtx.clearRect(0,0,64 * fTopMapScale,64 * fTopMapScale);

		oMapPlayerCtx.strokeStyle = "red";
	
		var fViewRightX = (12*64) * Math.cos(fFOV/2) + oPlayer.x;
		var fViewRightY = (12*64) * Math.sin(fFOV/2) + oPlayer.y;
		var fViewLeftX = (12*64) * Math.cos(-fFOV/2) + oPlayer.x;
		var fViewLeftY = (12*64) * Math.sin(-fFOV/2) + oPlayer.y;

		oMapPlayerCtx.beginPath();
		oMapPlayerCtx.arc(oPlayer.x / 64 * fTopMapScale, oPlayer.y / 64 * fTopMapScale, fTopMapScale/2, 0, Math.PI * 2, true);
		oMapPlayerCtx.closePath();
		oMapPlayerCtx.fillStyle = "red";
		oMapPlayerCtx.fill();

		oMapPlayerCtx.save();

		oMapPlayerCtx.fillStyle = "rgba(255,0,0,0.2)";
	
		oMapPlayerCtx.translate(oPlayer.x / 64 * fTopMapScale, oPlayer.y / 64 * fTopMapScale);
		oMapPlayerCtx.rotate(oPlayer.rotation);
		oMapPlayerCtx.translate(-oPlayer.x / 64 * fTopMapScale, -oPlayer.y / 64 * fTopMapScale);
	
		oMapPlayerCtx.beginPath();
		oMapPlayerCtx.moveTo(fViewRightX/64 * fTopMapScale, fViewRightY/64 * fTopMapScale);
		oMapPlayerCtx.lineTo(oPlayer.x/64 * fTopMapScale,oPlayer.y/64 * fTopMapScale);
		oMapPlayerCtx.lineTo(fViewLeftX/64 * fTopMapScale, fViewLeftY/64 * fTopMapScale);
		oMapPlayerCtx.fill();
		oMapPlayerCtx.stroke();
	
		oMapPlayerCtx.restore();
		
	}

	oLookingAtImg = null;
	setDescText("");

	// clear all visible sprites
	for (var i=0;i<aVisibleSprites.length;i++) {
		var oImg = aVisibleSprites[i];
		oImg.visible = false;
		oImg.style.display = "none";
	}
	aVisibleSprites = [];

	for (var i=0;i<iScreenWidth;i+=iLineWidth) {
		renderLine(i);
	}


	// in the renderLine() method, all sprites that are encountered in the raycasting runs are put in aVisibleSprites
	// since the horizontal and vertical runs are independent of each other, we also get some sprites that are not actually visible
	// but are hidden behind walls. But at least we're not rendering all sprites.
	for (var i=0;i<aVisibleSprites.length;i++) {
		var oImg = aVisibleSprites[i];
		oImg.style.display = "block";
		
		

		// translate position to viewer space
		var fDX = oImg.posx - oPlayer.x;
		var fDY = oImg.posy - oPlayer.y;

		// distance to sprite
		var fDist = Math.sqrt(fDX*fDX + fDY*fDY);

		// size of the sprite
		var iSize = (64 * fViewDist) / fDist;

		// sprite angle relative to viewing angle
		var fSpriteAngle = Math.atan2(fDY, fDX) - oPlayer.rotation;

		// x-position on screen
		var x = Math.sin(fSpriteAngle) * fViewDist / Math.sin(0.5*Math.PI-fSpriteAngle);
		oImg.style.left = (iScreenWidth/2 + x - iSize/2) + "px";

		// y is constant since we keep all sprites at the same height and vertical position
		oImg.style.top = (300-iSize/2)+"px";//KO->change number to move sprites to the floor

		oImg.style.zIndex = 100000000 - Math.floor(fDist);
		oImg.style.width = oImg.style.height = iSize + "px";
			
				
			
	}

	if (oLookingAtImg) {
		setDescText("\"" + oLookingAtImg.title + "\" by " + oLookingAtImg.owner);
	}

		
}


var aWallTextures = [];
//first number in brackets in the map reference, second number refers to walls.png sprite 
aWallTextures[1] = 0;
aWallTextures[31] = 1;
aWallTextures[21] = 2;//FLICKR image, bottom image of sprite walls.png
aWallTextures[3] = 3;
aWallTextures[4] = 4;
aWallTextures[5] = 5;
aWallTextures[6] = 6;
aWallTextures[7] = 7;
aWallTextures[8] = 8;
aWallTextures[9] = 9;
aWallTextures[10] = 4;//
aWallTextures[11] = 5;//
aWallTextures[16] = 12;//girl on brick
aWallTextures[12] = 11;//brick for FLICKR
aWallTextures[13] = 13;//
aWallTextures[14] = 14;
aWallTextures[15] = 15;
aWallTextures[20] = 16;
aWallTextures[2] = 10;
aWallTextures[17] = 17;


//aWallTextures[22] = 9;


function renderLine(i) {
	var x = oPlayer.x;
	var y = oPlayer.y;

	var fLineAngle = (oPlayer.rotation - fFOV/2) + i*fColWidth;
	while (fLineAngle < 0) { fLineAngle += fTwoPI; 
		//sky.style.backgroundPosition=400+"px 0";/////////////////ko  DOES CHANGE BG but not well 
	}
	while (fLineAngle >= fTwoPI) fLineAngle -= fTwoPI;


	// cast a ray from the player's origin

	// this part needs a bit of reworking and optimizing
	// currently we're doing two runs, first to check against the horizontal map/map lines
	// next to check against the vertical lines. If a map block was found in both runs, the 
	// the closest one is used. It works for now, but there should only be one ray per line.

	// moving right/left? up/down?
	var bRight = (fLineAngle > fTwoPI * 0.75 || fLineAngle < fTwoPI * 0.25);
		
	var bUp = (fLineAngle < 0 || fLineAngle > Math.PI);

	var fAngleSin = Math.sin(fLineAngle);
	var fAngleCos = Math.cos(fLineAngle);

	// first check against the horizontal map/wall lines
	var bFoundHor = false;
	var fSlope = fAngleSin / fAngleCos;// the slope of the straight line made by the ray
	var fDX = 64 * (bRight ? 1 : -1);// starting vertical position. We add the small horizontal step we just made, multiplied by the slope.

	var fDY = fDX * fSlope; // how much to move up or down
	var fXHor;
	var fYHor;
	var x = bRight ? Math.ceil(oPlayer.x/64)*64 : Math.floor(oPlayer.x/64)*64;// starting horizontal position, at one of the edges of the current map block
	
	var y = oPlayer.y + (x - oPlayer.x) * fSlope;
	var bHitBlock = false;

	var fTextureXHor;
	var iTextureIdxHor;

	var iWallXHor = -1;
	var iWallYHor = -1;

	var iLevelMaxX = iLevelWidth*64;//was 64
	var iLevelMaxY = iLevelHeight*64;

	while (x >= 0 && x < iLevelWidth*64 && y >= 0 && y < iLevelHeight*64) {

		var iWallX = Math.floor((x + (bRight ? 0 : -1)) / 64);
		var iWallY = Math.floor(y / 64);//was 64

		if (iWallX >= 0) {


	

			if (aSpriteImg[iWallY][iWallX] && !aSpriteImg[iWallY][iWallX].visible) {
				aSpriteImg[iWallY][iWallX].visible = true;
				aVisibleSprites.push(aSpriteImg[iWallY][iWallX]);
			//	setDescText(aSpriteTextures[iIdx]);
			}

			if (aWalls[iWallY][iWallX] > 0) {
				// ok, point is in a wall block
	
				bFoundHor = true;
				fXHor = x;
				fYHor = y;
	
				var fDistX = fXHor - oPlayer.x;
				var fDistY = fYHor - oPlayer.y;
				fHorDist = fDistX*fDistX + fDistY*fDistY;

				fTextureXHor = fYHor % 64 / 64;
				if (!bRight) fTextureXHor = 1 - fTextureXHor;

				iWallXHor = iWallX;
				iWallYHor = iWallY;

				break;
			}
		}

		x += fDX;
		y += fDY;
	}

	// now check against vertical lines
	var bFoundVer = false;

	var fVerDist = 0;
	var fSlope = fAngleCos / fAngleSin;
	var fDY = 64 * (bUp ? -1 : 1);
	var fDX = fDY * fSlope;
	var y = bUp ? Math.floor(oPlayer.y/64)*64 : Math.ceil(oPlayer.y/64)*64;
	var x = oPlayer.x + (y - oPlayer.y) * fSlope;

	var fTextureXVer;

	var iWallXVer = -1;
	var iWallYVer = -1;

	while (x >= 0 && x < iLevelWidth*64 && y >= 0 && y < iLevelHeight*64) {

		var iWallY = Math.floor((y + (bUp ? -1 : 0)) / 64);
		var iWallX = Math.floor(x / 64);

		if (iWallY >= 0) {
			if (aSpriteImg[iWallY][iWallX] && !aSpriteImg[iWallY][iWallX].visible) {
				aSpriteImg[iWallY][iWallX].visible = true;
				aVisibleSprites.push(aSpriteImg[iWallY][iWallX]);
				
				
				
			}
			
			if (aWalls[iWallY][iWallX] > 0) {
				// ok, point is in a wall block

				bFoundVer = true;
				fXVer = x;
				fYVer = y;

				var fDistX = fXVer - oPlayer.x;
				var fDistY = fYVer - oPlayer.y;
				fVerDist = fDistX*fDistX + fDistY*fDistY;

				fTextureXVer = fXVer % 64 / 64;
				if (!bUp) fTextureXVer = 1 - fTextureXVer;

				iWallXVer = iWallX;
				iWallYVer = iWallY;

				break;
			}
		}
		x += fDX;
		y += fDY;
	}

	var fDist = 0;
	var fX = 0;
	var fY = 0;
	var fTextureX;
	var iWallX;// the (x,y) map coords of the block
	var iWallY;

	var bWallIsVert = false;

	// now find which block we hit, horizontal or vertical (if any).
	if (bFoundHor && (!bFoundVer || fHorDist < fVerDist)) {
		fDist = fHorDist;
		fX = fXHor;
		fY = fYHor;
		fTextureX = fTextureXHor;
		iWallX = iWallXHor;
		iWallY = iWallYHor;
	} else if (bFoundVer) {
		bWallIsVert = true;
		fDist = fVerDist;
		fX = fXVer;
		fY = fYVer;
		fTextureX = fTextureXVer;
		iWallX = iWallXVer;
		iWallY = iWallYVer;
	}

	var oLine = aLines[i];
	var oLineStyle = oLine.style;
	var oLineDesc = oLine.linedesc;
	var oImgStyle = oLine.img.style;
	var oImg = oLine.img;

	// ok, we found a wall block
	if (fDist) {
		fDist = Math.sqrt(fDist);
		var iZ = Math.floor(fDist);

		iTextureIdx = aWalls[iWallY][iWallX];//number corresponding to wall texture

		// use perpendicular distance to adjust for fish eye
		fDist = fDist * Math.cos(-fHalfFOV+i*fColWidth);

		// now calc the position, height and width of the wall strip
		// "real" wall height in the game world is 1 unit, the distance from the player to the screen is viewDist,
		// thus the height on the screen is equal to wall_height_real * viewDist / dist
		var iHeight = Math.round(fWallHeight / fDist);
		var iWidth = iHeight * iLineWidth;

		var iTexX = Math.round(fTextureX * iWidth);
		if (iTexX > iWidth-iLineWidth)
			iTexX = iWidth-iLineWidth;

		var iTexXShade = iTexX + (bWallIsVert ? iWidth : 0);
		var iTop = Math.round(iScreenHeight/2 - iHeight/2);
		var iImgTop = aWallTextures[iTextureIdx] * iHeight;
		var fWallScale = iHeight/512;//////////////////////////////////////////////was /64 - KO->CHANGES HEIGHT OF FLICKR IMAGES 

		oLineStyle.zIndex = 100000000 - iZ;

		if (oLineDesc.display != 1) {
			oLineDesc.display = 1;
			oLineStyle.display = "block";
		}

		var bFlickr = false;
		var oFlickrStyle;


		// if the wall texture has a picture frame (texidx 12 and 21) and we are within the picture frame...
		if ((iTextureIdx == 12 || iTextureIdx == 21) && (fTextureX*64) > 7 && (fTextureX*64) < 57 && aFlickrMap[iWallY][iWallX]) {

			var oFlickrDesc = aFlickrMap[iWallY][iWallX];

			oFlickrStyle = oLine.flickrimg.style;
			oFlickrImgDesc = oLine.flickrimg.imgdesc;

			oFlickrStyle.display = "block";

			if (oLine.curflickr != oFlickrDesc.imgidx) {
				oLine.flickrimg.src = aFlickrImages[oFlickrDesc.imgidx].src;
				oLine.curflickr = oFlickrDesc.imgidx;
			}
		

			bFlickr = true;

			var iFlickrHeight = Math.floor((iHeight - ((iTextureIdx == 21 ? 14 : 11)*fWallScale)));
			if (oFlickrImgDesc.height != iFlickrHeight) {
				oFlickrImgDesc.height = iFlickrHeight;
				oFlickrStyle.height = iFlickrHeight +"px";
			}
			if (oFlickrImgDesc.width != iWidth) {
				oFlickrImgDesc.width = iWidth;//
				oFlickrStyle.width = iWidth+"px";//
			}
			var iFlickrTop = Math.floor((iTextureIdx == 21 ? 8 : 5) * fWallScale);
			if (oFlickrImgDesc.top != iFlickrTop) {
				oFlickrImgDesc.top = iFlickrTop;
				oFlickrStyle.top = iFlickrTop + "px";
			}
			if (oFlickrImgDesc.left != iTexX) {
				oFlickrImgDesc.left = iTexX;
				oFlickrStyle.left = -iTexX + "px";
			}

			if (Math.round(iScreenWidth / i) == 2 && fDist < 256) {
				oLookingAtImg = aFlickrImages[oFlickrDesc.imgidx]; //oFlickrImgDesc.proto;
			}

		} else {
			if (Math.round(iScreenWidth / i) == 2 && iTextureIdx == 3 && fDist < 196) {
				setDescText("MIRACLE OF CHILE TEXT HERE")///////////////////////////////////////////text for a wall texture
			}

			oLine.flickrimg.style.display = "none";
		}

		if (oLineDesc.height != iHeight) {
			oLineDesc.height = iHeight;//
			oLineStyle.height = iHeight+"px";
			if (bTexturedWalls) oImgStyle.height = iNumWallTextures*iHeight+"px";
		}
		if (oLineDesc.width != iWidth) {
			oLineDesc.width = iWidth;
			if (bTexturedWalls) oImgStyle.width = (iWidth*2)+"px";
		}
		if (oLineDesc.top != iTop) {
			oLineDesc.top = iTop;
			oLineStyle.top = iTop+"px";
		}
		if (oLineDesc.imgtop != iImgTop) {
			oLineDesc.imgtop = iImgTop;
			if (bTexturedWalls) aLines[i].img.style.top = -iImgTop+"px";
		}
		if (oLineDesc.texxshade != iTexXShade) {
			oLineDesc.texxshade = iTexXShade;
			if (bTexturedWalls) oImgStyle.left = -iTexXShade+"px";
		}

	} else {
		if (oLineDesc.display) {
			oLineDesc.display = 0;
			oLineStyle.display = "none";
		}
	}

}

function addEvent(oObject, strEvent, fncAction) {
	if (oObject.addEventListener) { 
		oObject.addEventListener(strEvent, fncAction, false); 
	} else if (oObject.attachEvent) { 
		oObject.attachEvent("on" + strEvent, fncAction); 
	}
}


var fMaxSpeed = 256;
var fMaxRotInc = 120 * fDegRad;
var ROT;

//////////////////////////////////////////////////////////MOVE the HAND//////////////////////////////////////////////////////////////////////
function move(oEntity) {
var MyVar;
	var iTime = new Date().getTime();
	var fDeltaTime = Math.min((iTime - oEntity.lastmovetime) / 1000, 0.1);
	oEntity.lastmovetime = iTime;

	if (oEntity.rotincdir) {
		oEntity.rotinc += 180 * oEntity.rotincdir * fDegRad * fDeltaTime;
		//sky.style.backgroundPosition=(oEntity.rotinc+400)+"px 0";/////////////////ko  DOES CHANGE BG but not well
		
	} else {
		if (oEntity.rotinc < 0) { //moving left
			oEntity.rotinc = Math.min(0, oEntity.rotinc + 1 * fDegRad) * fDeltaTime;
		//	sky.style.backgroundPosition=(oEntity.rotinc+400)+"px 0";/////////////////ko  DOES CHANGE BG but not well
	
	
			
			
		}
		if (oEntity.rotinc > 0) { //moving right
			oEntity.rotinc = Math.max(0, oEntity.rotinc - 1 * fDegRad) * fDeltaTime;
				//var oEntity.rotincK = (1-oEntity.rotinc);
							
			
				
		}
//	MyVar=rotation;
	//	sky.style.backgroundPosition=(MyVar*400)+"px 0";
	
	}
	

	oEntity.rotinc = Math.min(oEntity.rotinc, fMaxRotInc);
	oEntity.rotinc = Math.max(oEntity.rotinc, -fMaxRotInc);
 
	oEntity.rotation += oEntity.rotinc * fDeltaTime;
	
	if (oEntity.rotation < 0) 
		oEntity.rotation += fTwoPI;

	
	if (oEntity.rotation > fTwoPI)
		oEntity.rotation -= fTwoPI;
				

	oEntity.speed += oEntity.speedinc * fDeltaTime;

	if (oEntity.speed > fMaxSpeed)
		oEntity.speed = fMaxSpeed;
	if (oEntity.speed < -fMaxSpeed)
		oEntity.speed = -fMaxSpeed;
  
	// move position
	var fMoveY = oEntity.speed * Math.sin(oEntity.rotation) * fDeltaTime;
	var fMoveX = oEntity.speed * Math.cos(oEntity.rotation) * fDeltaTime;

	var fNewPosX = oEntity.x + fMoveX;
	var fNewPosY = oEntity.y + fMoveY;

	moveTo(oEntity, fNewPosX, fNewPosY);
	if (oPlayer.rotincdir != 0) { 
	
	//	var playerDir = rotincdir;// iWallX
	//	playerDir+=2*pi;i
	//	playerDir%=2*pi;
	//	sky.style.backgroundPosition=Math.floor(-playerDir/(2*pi)*2400)+"px 0";//////////////////////////////////////////////////////////////////////////////////////////KO 
	}
	// decrease speed, if we're not accelerating, automatically decrease speed
	if (!oEntity.speedinc)
		oEntity.speed *= 0.5;

	if (Math.abs(oEntity.speed) < 0.05)
		oEntity.speed = 0;

	
	if (Math.abs(oEntity.speed) > 0.5) wobbleGun();//////////////////////////////////////////////////////////////////////////////////KO WOBBLE
	if (oEntity.rotinc < 0) background();
		
}
function wobbleGun(){
//	var mag=oEntity.speed;
	var mag=Math.random()*.02; 
	var total=5;
	overlay.style.backgroundPosition=(10+Math.cos(total/6.23)*mag*50)+"px "+(10+Math.cos(total/5)*mag*50)+"px";

        	
}
function background() {/////////////////////////////////////////sky
			//oEntity.rotinc +=2*pi;
	        	//oEntity.rotinc %=2*pi;
	//	sky.style.backgroundPosition=Math.floor(fMoveX/(2*pi)*2400)+100+"px 0";
		sky.style.backgroundPosition=(oEntity.rotation+10)+"px 0";
}

//end ko
function canMoveToBlock(x, y) {
	if (!aWalls[y]) return false;
	if (aWalls[y][x] != 0) {
		return false;
	}
	return true;
}


// move an entity from its current position to a new position
function moveTo(oEntity, fNewX, fNewY) {

	// new position same as old
	if (oEntity.x == fNewX && oEntity.y == fNewY) return;

	// we want to keep a certain distance to walls
	var iMinDist = 32;

	// moving right/left, up/down?
	var iDirX = (fNewX - oEntity.x) < 0 ? -1 : 1;
	var iDirY = (fNewY - oEntity.y) < 0 ? -1 : 1;

	// map block coords of old position
	var iOldX = Math.floor(oEntity.x / 64);
	var iOldY = Math.floor(oEntity.y / 64);

	// and for new position, with added "padding"
	var iNewX = Math.floor((fNewX + iMinDist*iDirX) / 64);
	var iNewY = Math.floor((fNewY + iMinDist*iDirY) / 64);
	

	// and for new position with added padding * 0.5
	var iNewX2 = Math.floor((fNewX + iMinDist*0.5*iDirX) / 64);
	var iNewY2 = Math.floor((fNewY + iMinDist*0.5*iDirY) / 64);

	var fMovePosX = oEntity.x;
	var fMovePosY = oEntity.y;


	// check if it's clear diagonally, if not, stop.
	if (canMoveToBlock(iNewX2, iNewY2)) {
		// if we can move to the new X position, do that
		if (canMoveToBlock(iNewX, iOldY)) {
			fMovePosX = fNewX;
			
		
				
		}
		// if we can move to the new Y position, do that
		if (canMoveToBlock(iOldX, iNewY)) {
			fMovePosY = fNewY;

		}
	
	}
	// this isn't quite right, we should be doing a sphere vs. box intersection thing,
	// but this works for now. If you move directly into a corner, you'll be stopped,
	// but you can still move/glide along walls

	oEntity.x = fMovePosX;
	oEntity.y = fMovePosY;


}


var oDisplayImage;

function checkLookingAtImage() {
	if (oDisplayImage) {
		$("mdc").removeChild(oDisplayImage);
		oDisplayImage = null;
	} else {
		if (oLookingAtImg) {
			oDisplayImage = new Image();
			oDisplayImage.className = "displayimage";
			oDisplayImage.src = oLookingAtImg.srchigh;
			$("mdc").appendChild(oDisplayImage);

			oDisplayImage.onclick = function() {
				$("mdc").removeChild(this);
				oDisplayImage = null;
			}

		}
	}
}


document.onkeydown = function(e) {

	if (!bRunning) return;
	e = e || window.event;

	if (e.keyCode == 32) { //////////////////////////////////////////////////////////////////////////// SPACE BAR
		checkLookingAtImage();
		return false;
	}

	if (!(e.ctrlKey||e.altKey)) {
		switch (e.keyCode) {
			case 38: // up
			case 87: // w
				oPlayer.speedinc = 512;	// acceleration, 512 units/s^2
				return (e.keyCode != 38);
			case 37: // left
			case 65: // a
				oPlayer.rotincdir = -1;	// direction of rotation
				
				return (e.keyCode != 37);
			case 39: // right
			case 68: // d
				oPlayer.rotincdir = 1;
				return (e.keyCode != 39);
			case 40: // down
			case 83: // s
				oPlayer.speedinc = -512; // acceleration, -512 units/s^2
				return (e.keyCode != 40);
		}
	}
}
////////////////////////////////////////////////////////////////Direction Keys/////////////////////////////////////////////////////////////// 
document.onkeyup = function(e) {
	
	if (!bRunning) return;
	e = e || window.event;
	switch (e.keyCode) {
		case 38: // up
		case 87: // w
			oPlayer.speedinc = 0;
			break;
		case 37: // left
		case 65: // a
			oPlayer.rotincdir = 0;
		
			break;
			
		case 39: // right
		case 68: // d
			oPlayer.rotincdir = 0;
			break;
		case 40: // down
		case 83: // s
			oPlayer.speedinc = 0;
			break;
	}

}

/////////////////////////////////////////////////// Flickr //////////////////////////////////////////////////////

function setDescText(strText) {
	$("description").innerHTML = strText;
}

var aFlickrImages = [];

function getFlickrImages(strUser, strSearch) {
	$("flickrusernamebtn").disabled = true;
	$("flickrsearchbtn").disabled = true;
	bRunning = false;

	Flickr.setAPIKey("8d9519088d3c85441d0d1e24ceadf3eb");//SET to miracleofchile.com domain...change if changing domains
                         
	if (strUser) {
		setDescText("Asking Flickr for user ID [\"" + strUser + "\"]...");

		Flickr.callMethod(
			"flickr.people.findByUsername", 
			{
				username : strUser
			}, 
			onUserFound
		);

	} else if (strSearch) {
		setDescText("Asking Flickr for \"" + strSearch + "\"...");

		Flickr.callMethod(
			"flickr.photos.search", 
			{
				text : strSearch,
				extras : "date_taken,owner_name",
				per_page : 25
			}, 
			onPhotosFound
		);
	}
	
	var strUserID = "";

	function onUserFound(oResponse) {
		if (oResponse.user) {
			setDescText("Getting Flickr photos from \"" + strUser + "\"...");

			strUserID = oResponse.user.id;
			Flickr.callMethod(
				"flickr.people.getPublicPhotos", 
				{
					user_id : strUserID,
					extras : "date_taken,owner_name",
					per_page : 60 ///////////////////////////////////////////////////////////////////////  FLICKR NUMBER IMAGES
				}, 
				onPhotosFound
			);
		} else {
			setDescText("User \"" + strUser + "\" not found!");
			setTimeout( function() {
				onPhotosFound({photos:{photo:[]}});
			}, 1000);
		}
	}

	function onPhotosFound(oResponse) {
		aFlickrImages = [];
		for (var i=0;i<oResponse.photos.photo.length;i++) {
			var oPhoto = oResponse.photos.photo[i];
			var strURL = "http://farm" + oPhoto.farm + ".static.flickr.com/" + oPhoto.server + "/" + oPhoto.id + "_" + oPhoto.secret + "_" + (bHighResFlickr ? "m" : "s") + ".jpg";
			var strURLHigh = "http://farm" + oPhoto.farm + ".static.flickr.com/" + oPhoto.server + "/" + oPhoto.id + "_" + oPhoto.secret + ".jpg";

			aFlickrImages.push(
				{
					src : strURL,
					title : oPhoto.title,
					owner : oPhoto.ownername || strUser || "unknown",
					srchigh : strURLHigh
				}
			);
		}
		loadFlickrImages();
	}
}

addEvent($("flickrusernamebtn"), "click",
	function() {
		if ($("flickrusername").value) {
			getFlickrImages($("flickrusername").value);
		}
	}
);

addEvent($("flickrsearchbtn"), "click",
	function() {
		if ($("flickrsearchquery").value) {
			getFlickrImages(null, $("flickrsearchquery").value);
		}
	}
);

function onLevelLoaded() {

	initScreen();
	drawMiniMap();

	setTimeout(function() {
	getFlickrImages("Milagro de Chile");//KO ->username here
	},500);
	
}

function drawMiniMap() {
	if (bRenderMap) {
		fTopMapScale = oTopMap.width / iLevelWidth;
	
		oTopMap.width=oTopMap.width;
		var oCtx = oTopMap.getContext("2d");
		for (var y=0;y<iLevelHeight;y++) {
			for (var x=0;x<iLevelWidth;x++) {
				if (aWalls[y][x] > 0) {
					if (aWalls[y][x] == 12 || aWalls[y][x] == 21) {
						oCtx.fillStyle = "rgb(255,255,200)";
					} else {
						oCtx.fillStyle = "rgb(200,200,200)";
					}
					oCtx.fillRect(x * fTopMapScale,y * fTopMapScale,fTopMapScale,fTopMapScale);
				}
			}
		}
	}
}


function loadFlickrImages() {

	var aImages = [];
	for (var i=0;i<aFlickrImages.length;i++) {
		aImages[i] = new Image();
		aImages[i].style.position = "absolute";
		aImages[i].style.left = "-10000px";
		aImages[i].src = aFlickrImages[i].src;
		document.body.appendChild(aImages[i]);
	}
	setDescText("Loading Flickr images...(0/" + aImages.length + ")");

	//var iInterval = setInterval(
	var fncCheck = function() {
		var iComplete = 0;
		var bAll = true;
		for (var i=0;i<aImages.length;i++) {
			if (!aImages[i].complete) {
				bAll = false;
			} else {
				iComplete++;
			}
		}
		if (bAll) {
			for (var i=0;i<aImages.length;i++) {
				aImages[i].ratio = aImages[i].offsetWidth / aImages[i].offsetHeight;
				aFlickrImages[i].img = aImages[i];
				document.body.removeChild(aImages[i]);
			}
			//clearInterval(iInterval);
			initFlickrImages();

			setTimeout(
				function() {
					setDescText("Milagro de Chile");
					startGame();
				}, 2000
			);
		} else {
			setDescText("Bajando fotos...(" + iComplete + "/" + aImages.length + ")");
			setTimeout(fncCheck, 50);
		}
	}
	fncCheck();
}


var aFlickrMap = [];

function initFlickrImages() {
	setDescText("Montando fotos al mundo...");

	aFlickrMap = [];
	for (var y=0;y<iLevelHeight;y++) {
		aFlickrMap[y] = [];
	}

	if (aFlickrImages.length) {
		var iIdx = 0;
		for (var y=0;y<iLevelHeight;y++) {
			for (var x=0;x<iLevelWidth;x++) {
				if (aWalls[y][x] == 12 || aWalls[y][x] == 21) {
					aFlickrMap[y][x] = {
						imgidx : iIdx,
						imgsrc : aFlickrImages[iIdx] // not used?
					}
					iIdx++;
					if (iIdx == aFlickrImages.length) {
						iIdx = 0;
					}
				}
			}
		}
	}

	for (var i=0;i<iScreenWidth;i+=iLineWidth) {
		var oLine = aLines[i];

		if (oLine.flickrimg)
			oLine.removeChild(oLine.flickrimg);


		var oFImg = new Image();
		oFImg.style.position = "absolute";
		oFImg.style.border = "none";
		oFImg.style.padding = "0px";
		oFImg.style.margin = "0px";
		oFImg.style.left = "0px";
		oFImg.style.width = "0px";//
		oFImg.style.height = "0px";
		oFImg.style.display = "none";
		oFImg.imgdesc = {};

		oLine.flickrimg = oFImg;
		oLine.appendChild(oFImg);
	}

}


addEvent($("lowreswalls"), "click",
	function() {
		bRunning = false;
		setDescText("Rebuilding screen...");
		$("lowreswalls").disabled = true;
		setTimeout(
			function() {
				var bLowRes = $("lowreswalls").checked;
				if (bLowRes) {
					iLineWidth = 6;
				} else {
					iLineWidth = 3;
				}
				initScreen();
				initFlickrImages();
				bRunning = true;
				$("lowreswalls").disabled = false;
			}, 10
		);
	}
);
//////////////////////////////////////////////////////////////////// End Flickr //////////////////////////////////////////////////////////////////
setDescText("Loading level...");
loadLevel("gallery");
sky.style.backgroundPosition=y+"px 0";
}

window.onload = MiracleOfChile;




