//////////////////////////////////////////////////////////////////////////////
//                                                                          //
// Wii Opera SDK/HullBreach SDK - Mode7 Class v0.9 2009-02-15               //
// (c) 2007-2009 Daniel Gump. All Rights Reserved.                          //
// http://wiioperasdk.com, http://hullbreachonline.com                      //
// hullbreach@hullbreachonline.com                                          //
//                                                                          //
//  Wii is a trademark of Nintendo Co., Ltd.                                //
//  Opera is a trademark of Opera, ASA.                                     //
//  This software package is not associated with either company             //
//  but was created to support users of both.  Its alternative name         //
//  when supporting other products is the HULLBREACH SDK.                   //
//                                                                          //
//  Redistribution and use in source and binary forms, with or without      //
//  modification, are permitted provided that the following conditions      //
//  are met:                                                                //
//    * Redistributions of source code must retain the above copyright      //
//      notice, this list of conditions and the following disclaimer.       //
//    * Redistributions in binary form must reproduce the above copyright   //
//      notice, this list of conditions and the following disclaimer in     //
//      the documentation and/or other materials provided with the          //
//      distribution.                                                       //
//    * Neither the names HULLBREACH ONLINE nor WII OPERA SDK nor the names //
//      of its contributors may be used to endorse or promote products      //
//      derived from this software without specific prior written           //
//      permission.                                                         //
//    * If the explicit purpose of the software is not to support the       //
//      Nintendo Wii or the Opera Web browser, then the names of such must  //
//      not be used in any derived product. The name shall be the           //
//      HULLBREACH SDK with a reference link to http://hullbreachonline.    //
//                                                                          //
//  THIS SOFTWARE IS PROVIDED BY Daniel Gump ''AS IS'' AND ANY EXPRESS OR   //
//  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED          //
//  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  //
//  DISCLAIMED. IN NO EVENT SHALL Daniel Gump BE LIABLE FOR ANY DIRECT,     //
//  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES      //
//  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR      //
//  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)      //
//  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,     //
//  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING   //
//  IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE      //
//  POSSIBILITY OF SUCH DAMAGE.                                             //
//////////////////////////////////////////////////////////////////////////////

function Mode7(){
	this.CANVASBUFFER = document.createElement("CANVAS");
	this.CANVASBUFFER.width=320;
	this.CANVASBUFFER.height=160;
	this.BUFFERCONTEXT=this.CANVASBUFFER.getContext("2d");
	this.BUFFERCONTEXT.translate(160,160);

	this.ROTATESPEED = Math.PI/32;
	this.SPEED = 15;
	this.SCALE = 8;
	this.FOV = 1;
	
	this.width=800;
	this.height=480;
	this.half_width=this.width>>1;
	this.half_height=this.height>>1;
	
	this.ANGLE = 0;
	this.player_x = 128;
	this.player_z = 600;

	this.strip_width = Math.sqrt(this.width/this.half_height)/this.FOV;
}
Mode7.prototype.moveLeft = function(){
	this.player_z += this.SPEED*Math.sin(this.ANGLE)|0;
	this.player_x -= this.SPEED*Math.cos(this.ANGLE)|0;
}
Mode7.prototype.moveRight = function(){
	this.player_z -= this.SPEED*Math.sin(this.ANGLE)|0;
	this.player_x += this.SPEED*Math.cos(this.ANGLE)|0;
}
Mode7.prototype.moveBackward = function(){
	this.player_z += this.SPEED*Math.cos(this.ANGLE)|0;
	this.player_x += this.SPEED*Math.sin(this.ANGLE)|0;
}
Mode7.prototype.moveForward = function(){
	this.player_z -= this.SPEED*Math.cos(this.ANGLE)|0;
	this.player_x -= this.SPEED*Math.sin(this.ANGLE)|0;
}
Mode7.prototype.rotateLeft = function(){
	if((this.ANGLE+=this.ROTATESPEED)>6.28318530717958646) this.ANGLE-=6.28318530717958646;
	this.left_cos = Math.cos(this.ANGLE-Math.PI/4);
	this.left_sin = Math.sin(this.ANGLE-Math.PI/4);
	this.right_cos = Math.cos(this.ANGLE+Math.PI/4);
	this.right_sin = Math.sin(this.ANGLE+Math.PI/4);
}
Mode7.prototype.rotateRight = function(){
	if((this.ANGLE-=this.ROTATESPEED)<0) this.ANGLE+=6.28318530717958646;
	this.left_cos = Math.cos(this.ANGLE-Math.PI/4);
	this.left_sin = Math.sin(this.ANGLE-Math.PI/4);
	this.right_cos = Math.cos(this.ANGLE+Math.PI/4);
	this.right_sin = Math.sin(this.ANGLE+Math.PI/4);
}
Mode7.prototype.animate = function(canvas){
	canvas = canvas.getContext("2d");
	canvas.fillStyle = "rgb(128,192,255)";
	canvas.fillRect(0,0, this.width,this.height>>1);
	
	this.BUFFERCONTEXT.save();
	this.BUFFERCONTEXT.rotate(this.ANGLE);
	this.BUFFERCONTEXT.translate(-160,-160);
	var mapx=0;
	for(z=-160-(this.player_z&127); z<=480; z+=128){
		var mapz = (this.player_z+z)>>7;
		for(x=-160-(this.player_x&127); x<=480; x+=128){
			if(mapz>=0 && (mapx=(this.player_x+x)>>7)>=0 && mapz<Level.length && mapx<Level[mapz].length){
				this.BUFFERCONTEXT.drawImage(Textures[Level[mapz][mapx]], x,z);
			}else{
				this.BUFFERCONTEXT.drawImage(Default, x,z);
			}
		}
	}
	this.BUFFERCONTEXT.restore();

	for(var y=this.half_height; y<=this.height; y+=this.SCALE){
		canvas.drawImage(this.CANVASBUFFER, 0,(159*Math.sqrt(y/this.half_height-1))|0, 319,1, this.half_width-(dx=(y*this.strip_width)|0),y, dx<<1,this.SCALE);
	}
}