/**
 * Ucren F1 赛车
 * FileName: core.js
 * Author: Dron
 * Date: 2009-02-04
 * Contact: ucren.com
 */

Ucren.onReady(function(){
	// road
	var road = {
		direction: 0,
		turn: function(){
			var t = function(n, thiz){
				if(thiz.direction > n)thiz.direction --;
				else if(thiz.direction < n)thiz.direction ++;
				else return true;
				thiz.film.play(thiz.direction + 5);
				thiz.turnTimer = setTimeout(function(){
					t(n, thiz);
				}, 200);
			};
			return function(n){
				if(!coordinator.running)return ;
				clearTimeout(this.turnTimer);
				t(n, this);
			};
		}(),
		restore: function(){
			if(!coordinator.running)return ;
			this.turn(0);
		},
		init: function(){
			var film = new Ucren.Film({
				width: 500, height: 150, image: "images/road.gif", container: "road", length: 11, timeout: 0
			});
			film.render();
			film.play(5);
			this.film = film;
		}
	};

	// mobile
	var mobile = {
		speed: 0,
		timeout: 10,
		getPath: function(){
			var pathl = [
				[[200, 300], [179, 319], [159, 339], [139, 359], [119, 379], [ 99, 399], [ 79, 419], [ 59, 439], [ 39, 459], [ 19, 479]],
				[[150, 250], [147, 278], [142, 306], [133, 333], [122, 360], [107, 385], [ 91, 409], [ 72, 434], [ 50, 455], [ 26, 478]],
				[[100, 200], [107, 237], [110, 275], [108, 308], [103, 340], [ 94, 371], [ 81, 399], [ 67, 428], [ 48, 453], [ 25, 477]],
				[[ 50, 150], [ 66, 197], [ 78, 241], [ 83, 282], [ 83, 321], [ 80, 356], [ 72, 390], [ 60, 422], [ 44, 449], [ 25, 476]],
				[[  0, 100], [ 25, 156], [ 44, 209], [ 58, 258], [ 65, 302], [ 66, 343], [ 63, 381], [ 55, 414], [ 41, 446], [ 23, 475]],
				[[ -1,  50], [ -1, 117], [ 12, 177], [ 32, 232], [ 46, 283], [ 52, 330], [ 53, 371], [ 48, 410], [ 38, 444], [ 22, 474]]
			];
			var pathr = [0];
			for(var i = 1, r, r1; i < pathl.length; i ++){
				r = pathl[i];
				r1 = [];
				for(var j = 0, jr; j < r.length; j ++){
					jr = r[j];
					r1.push([500 - jr[1], 500 - jr[0]]);
				};
				pathr.push(r1);
			};
			return function(){
				var d = road.direction;
				if(d <= 0)return pathl[-d];
				else return pathr[d];
			};
		}(),
		start: function(){
			this.interval = setInterval(this.move.createDelegate(this), this.timeout);
		},
		stop: function(){
			this.interval && clearInterval(this.interval);
		},
		move: function(){
			var hill = Ucren.get("hill", true).style;
			var rockl = Ucren.get("rockl", true).style;
			var rockr = Ucren.get("rockr", true).style;
			var hillScroll = 0;

			var rockn = 0, rocky = 0;
			return function(){
				if(!coordinator.running)return ;

				hillScroll = ((hillScroll -= road.direction) + 500) % 500;
				hill.backgroundPosition = hillScroll + "px 0";

				rockn = Math.floor(rocky / 15);
				var p = this.getPath()[rockn], l, nl, l2, nl2;
				var p1 = this.getPath()[rockn + 1];

				var rs = Math.floor(rocky / 150 * 50), yc = rocky % 15 / 15;
				var l = p[0] - rs;
				var nl = p1[0] - rs;
				var l2 = p[1];
				var nl2 = p1[1];
				l += Math.floor((nl - l) * yc);
				l2 += Math.floor((nl2 - l2) * yc);
				rockl.left = l + "px";
				rockr.left = l2 + "px";
				rockl.top =
				rockr.top = (350 + rocky - rs) + "px";
				rockl.width = rockl.height = rockr.width =
				rockr.height = rs + "px";

				if(Math.abs(car.position) >= 180)lifeControl.lose();
				else lifeControl.add();

				car2.fire();
				rocky += Math.ceil(Math.max(1, rocky) / 150 * 30);
				if(rocky > 130)rocky = 0;
			};
		}(),
		init: function(){

		}
	};

	// car
	var car = {
		speed: 0,
		direction: 0,
		position: 0,
		left: 0,

		turn: function(n){
			if(!coordinator.running)return ;
			this.film.play(n + 2);
			this.direction = n;
		},

		move: function(){
			var car = Ucren.get("car", true).style;
			return function(n){
				if(!coordinator.running)return ;
				this.position += n * 2;
				if(this.position < -185){
					this.position = -185;
				}else if(this.position > 185){
					this.position = 185;
				};
				car.left = (this.left = 193 + this.position) + "px";
			};
		}(),

		checkPosition: function(){
			var rd = road.direction;
			var cd = this.direction * 4 - rd * 2;
			if(cd == 0)return ;
			this.move(cd);
		},

		boom: function(){
			this.film.play(5);
		},

		init: function(){
			var film = new Ucren.Film({
				width: 114, height: 45, image: "images/car.gif", container: "car", length: 6, timeout: 0
			});
			film.render();
			film.play(2);
			this.film = film;
			this.checkInterval = setInterval(this.checkPosition.createDelegate(this), 100);
		}
	};

	// car 2
	var car2 = {
		running: false,
		left: 0, width: 0,
		ypos: 0,
		car: Ucren.get("car2", true).style,
		start: function(){
//			this.p = Math.random();
			this.p = 1 - (car.position + 180) / 360;
			this.car.display = "block";
			this.car.zIndex = 9;
			this.running = true;
			this.move();
		},
		stop: function(){
			this.car.display = "none";
			this.ypos = 0;
			this.running = false;
		},
		move: function(){
			var w, h, l, yp, pt, npt;
			if(!coordinator.running)return ;
			yp = Math.floor(this.ypos / 15);
			pt = mobile.getPath()[yp];
			npt = mobile.getPath()[Math.min(yp + 1, 9)];
			w = Math.floor(97 * this.ypos / 100);
			h = Math.floor(44 * this.ypos / 100);
			l = pt[0] + Math.floor((pt[1] - pt[0] - w) * this.p);
			nl = npt[0] + Math.floor((npt[1] - npt[0] - w) * this.p);
			l += (nl - l) * (this.ypos % 15 / 15);
			this.car.width = (this.width = w) + "px";
			this.car.height = h + "px";
			this.car.left = (this.left = l) + "px";
			this.car.top = 350 + this.ypos + "px";
			if(collision.check())return ; // 检查碰撞
			if(this.ypos > 100)this.car.zIndex = 11;
			this.ypos ++;
			if(yp < 9)setTimeout(this.move.createDelegate(this), 100);
			else this.stop();
		},
		fire: function(){
			if(this.running)return ;
			if(Math.random() > 0.002)return ;
			this.start();
		},
		boom: function(){
			var car = Ucren.get("car2", true);
			car.src = "images/boom.gif";
			-function(){
				this.stop();
				car.src = "images/car2.gif";
			}.defer(200, this);
		}
	};

	// map
	var map = {
		intent: 0,
		useRandom: function(){
			var h = [0, 0, 0];
			var change = function(){
				var r, h0, rn, dy = 2000; // 一次抽取，至少延时 2 秒
				h0 = Math.abs(h[0]);
				rn = Math.random();

				if(h0 == 3 && rn > 0.6){ // 从 3 到 4，至少 4 成的机会
					r = h[0] == 3 ? 4 : -4;
				}else if(h0 == 4 && Math.abs(h[1]) == 5){ // 如果历史呈现 5-4，则不能再选 5
					r = Ucren.randomNumber(7) - 3;
				}else if(h0 == 4 && rn > 0.9){ // 从 4 到 5，至少 1 成的机会
					r = h[0] == 4 ? 5 : -5;
				}else{
					r = Ucren.randomNumber(11) - 5;
					if(Math.abs(r) == 5 && rn > 0.5)r = 0; // 减少弯度 5 的机会
				}

				h.unshift(r); // 插入历史
				h.pop();
				road.turn(r);
				dy += 750 * Math.abs(r) + Ucren.randomNumber(2000); // 增加延时
				setTimeout(arguments.callee, dy);
			};
			change();
		}
	};

	// coordinator
	var coordinator = {
		envTurn: function(n){
			road.turn(n);
		},

		envRestore: function(){
			road.restore();
			mobile.restore();
		},

		registerEvent: function(){
			Ucren.addEvent(document, "keydown", this.keydown.createDelegate(this));
			Ucren.addEvent(document, "keyup", this.keyup.createDelegate(this));
		},

		keydown: function(e){
			if(!this.running)return ;
			e = Ucren.Event(e);
			var c = e.keyCode;
			if(c == this.lastKey)return ;
			if(c == 37){
				car.turn(-1);
				clearTimeout(this.leftTimer);
				this.leftTimer = setTimeout(function(){
					car.turn(-2);
				}, 750);
			}else if(c == 39){
				car.turn(1);
				clearTimeout(this.rightTimer);
				this.rightTimer = setTimeout(function(){
					car.turn(2);
				}, 750);
			};
			this.lastKey = c;
		},

		keyup: function(e){
			if(!this.running)return ;
			e = Ucren.Event(e);
			var c = e.keyCode;
			if(c == 37){
				clearTimeout(this.leftTimer);
				if(car.direction < 0)car.turn(0);
			}else if(c == 39){
				clearTimeout(this.rightTimer);
				if(car.direction > 0)car.turn(0);
			};
			this.lastKey = null;
		},

		start: function(){
			mobile.start();
			map.useRandom.defer(3000, map);
			this.running = true;
		},

		stop: function(){
			mobile.stop();
			this.running = false;
		},

		init: function(){
			lifeControl.init();
			road.init();
			mobile.init();
			car.init();
			this.registerEvent();
		}
	};

	// lifeControl
	var lifeControl = {
		life: 100,
		inner: Ucren.get("life-inner", true).style,
		show: function(){
			this.inner.width = Math.floor(this.life) + "%";
		},
		lose: function(n){
			n = n || 0.1;
			this.life -= n;
			this.life = Math.max(0, this.life);
			this.show();
			if(this.life < 0.1){
				car.boom();
				coordinator.stop();
			}
		},
		add: function(){
			this.life += 0.05;
			if(this.life > 100)this.life = 100;
			this.show();
		},
		init: function(){
			this.show();
		}
	};

	// collision
	var collision = {
		check: function(){
			if(car2.ypos > 63 && car2.ypos < 134 &&
				(car2.left + car2.width > car.left) &&
				(car2.left < car.left + 114)){
				car2.boom();
				lifeControl.lose(50);
				return true;
			}
		}
	};

	Ucren.loadingImage(["images/boom.gif"]);
	coordinator.init();

	Ucren.get("startb", true).disabled = false;
	window.startGame = function(ipt){
		coordinator.start();
		ipt.value = "游戏中"
		ipt.disabled = true;
		ipt.blur();
	};
});