// http://en.wikipedia.org/wiki/3D_projection#Perspective_projection

var PI = Math.PI;
var cos = Math.cos;
var sin = Math.sin;

var lightVector = new Vector(1.5, 3, -2).normalize();

var Canvas = new Class({

	initialize: function(element){
		this.element = $(element);
		this.ctx = this.element.getContext("2d");
		this.ctx.scale(this.element.width / 2, this.element.height / 2);
		this.ctx.translate(1, 1);
		this.ctx.lineJoin = 'round';
		this.ctx.lineWidth = 0.007;
	},
	
	triangle: function(a, b, c, color){
		var ctx = this.ctx;
		ctx.fillStyle = ctx.strokeStyle ="rgb(" + color.join(',') + ")";
		ctx.beginPath();
		ctx.moveTo(a.x, a.y);
		ctx.lineTo(b.x, b.y);
		ctx.lineTo(c.x, c.y);
		ctx.fill();
		ctx.stroke();
	}

});

window.addEvent('domready', function(){
	var objects = [];
	var frame = $('frame');
	var canvas = new Canvas(frame);
	var center = new Vector(0, -1, 0);
	var centerb = new Vector(0, .5, 0);
	var p1, p2;
	var sides = 16;
	var tops = [];
	for(var i = 0; i < sides; i++){
		p1 = new Vector(cos(i/sides * 2 * PI), -1, sin(i/sides * 2 * PI));
		p1b = new Vector(p1.x,p1.y + .5,p1.z);
		p2 = new Vector(cos((i + 1)/sides * 2 * PI), -1, sin((i + 1)/sides * 2 * PI));
		p2b = new Vector(p2.x,p2.y + .5,p2.z);
		var top = new Triangle(canvas, centerb, p1b, p2b);
		tops.push(top);
		objects.extend([
			new Triangle(canvas, p1, p1b, p2),
			new Triangle(canvas, p2, p1b, p2b),
			new Triangle(canvas, center, p1, p2),
			top]);
	}

	objects.sort(function(a,b){
		// TODO: not a good check...
		return b.getCenter().z - a.getCenter().z;
	});

	function repaint(){
		canvas.ctx.clearRect(-1, -1, 2, 2);
		objects.each(function(obj){
			obj.draw();
		});
	}
	
	repaint();
	
	var i = 0;
	(function(){
		i++;
		tops.each(function(top){
			top.p1.x = .5 * sin(5/360 * PI * i);
			top.p1.z = .5 * cos(5/360 * PI * i);
			top.p1.y = -cos(3/360 * PI * i) / 2;
		});
		repaint();
	}).periodical(50);
	
	frame.Oy = cam.O.y;
	frame.Ox = cam.O.x;
	var drag = new Drag(frame, {
		snap: 0,
		modifiers: {x: 'Oy', y: 'Ox'},
		style: false,
		onDrag: function(){
			cam.O.x = PI/180 * drag.value.now.y / 3;
			cam.O.y = PI/180 * drag.value.now.x / 3;
			// repaint();
		}
	});
	frame.addEvent('mousewheel', function(evt){
		cam.c.z += .1 * (evt.wheel > 1 ? 1 : -1);
		// repaint();
		return false;
	});

});
