
THREE.FloatingIsland = function (mode) {

	THREE.Object3D.call( this );

	this.mode = mode;

	this.type = 'FloatingIsland';

	// because == on floats...
	this.closeEnough = function(x, y)
	{
		if (x >= y-0.001 && x <= y+0.001)
			return true;
		return false;
	}

	var matGround = new THREE.MeshLambertMaterial({
		//ambient: 0x999999,
		color: 0x198515,
		//emissive: 0x222222,
		shading: THREE.FlatShading,
		wireframe: false
	});

	var red = new THREE.MeshLambertMaterial({ // debug material
		color: 0xff0000,
		shading: THREE.FlatShading,
		wireframe: true
	});

	this.boxHeight = 4;


	this.findGroundLevel = function(x,z)
	{
		return this.boxHeight/2 + noise.perlin2(x/5, z/5);
	}

	this.makeTop = function()
	{
		var box = new THREE.BoxGeometry(35,this.boxHeight,35,10,3,10);

		for (var i=0; i<box.vertices.length; i++)
		{
			var v = box.vertices[i];

			if (this.closeEnough(v.y, this.boxHeight/2))
			{
				box.vertices[i].y = this.findGroundLevel(v.x, v.z);
			}
		}
		return box;
	}


	// Make a box that is the ground. We'll shape the edges later
	var box = this.makeTop();

	// Make two cylinders to intersect the ground
	var cylinder = new THREE.CylinderGeometry(15.5, 13.5, 10, 7, 1);
	var cylinder2 = new THREE.CylinderGeometry(8.5, 17.5, 10, 7, 1); // beveled edge
	cylinder2.applyMatrix(new THREE.Matrix4().makeTranslation(0,3,0));

	/* debugging
	var test = new THREE.Mesh(cylinder,red);
	var test2 = new THREE.Mesh(cylinder2,red);
	this.add(test);
	this.add(test2);
	*/

	var csgBox = new ThreeBSP(box);
	var csgCylinder = new ThreeBSP(cylinder);
	var csgCylinder2 = new ThreeBSP(cylinder2);

	var shapedGround = csgBox.intersect(csgCylinder);
	shapedGround = shapedGround.intersect(csgCylinder2);

	this.island = shapedGround.toMesh(matGround);
	this.add(this.island);


	this.platform = new THREE.Platform();
	this.add(this.platform);

	// Add box to hide floating island rocks at the bottom.
	var rockHider = new THREE.Mesh(new THREE.BoxGeometry(5,5,5,1,1,1), new THREE.MeshBasicMaterial({color:0xd1f2e9}));
	rockHider.position.set(0,-150,0);
	this.add(rockHider);



	if (this.mode == 1)
	{
		// ================================================================================
		// Island 1 - just trees

		this.trees = [];

		this.trees.push(new THREE.Busk({seed:234, leafCount:4}) );
		this.trees.push(new THREE.Busk({seed:543, leafCount:5}) );
		this.trees.push(new THREE.Busk({seed:523, leafCount:6}) );
		this.trees.push(new THREE.Busk({seed:513, leafCount:6}) );
		
		Math.seedrandom(34701);
		for (var i=0; i<this.trees.length; i++)
		{
			var scale = 0.4 + Math.random()*0.2;
			this.trees[i].scale.set(scale, scale, scale);
			this.trees[i].position.x = (Math.random()-0.5)*2 * 10;
			this.trees[i].position.z = (Math.random()-0.5)*2 * 10;
			this.trees[i].position.y = this.findGroundLevel(this.trees[i].position.x, this.trees[i].position.z);
			this.add(this.trees[i]);
		}
		
		this.rocks = [];
		this.rocks.push(makeRock(2,4,5));
		this.rocks[0].position.x = 10;
		this.rocks[0].position.y = this.findGroundLevel(this.rocks[0].position.x, this.rocks[0].position.z);
		this.add(this.rocks[0]);

		this.rocks.push(makeRock(1.2,2,54));
		this.rocks[1].position.x = 3;
		this.rocks[1].position.z = -5;
		this.rocks[1].position.y = this.findGroundLevel(this.rocks[1].position.x, this.rocks[1].position.z);
		this.add(this.rocks[1]);

		this.rocks.push(makeRock(1.4,3,514));
		this.rocks[2].position.x = -6;
		this.rocks[2].position.z = 3;
		this.rocks[2].position.y = this.findGroundLevel(this.rocks[2].position.x, this.rocks[2].position.z);
		this.add(this.rocks[2]);
	}



	this.animate = function(n)
	{
		var bottomN = segmentTransition(0.0, 0.8, n);
		var topN = segmentTransition(0.4, 1.0, n);

		var rockN = segmentTransition(0.0, 1.0, bottomN);
		var islandN = segmentTransition(0.2, 0.55, bottomN);

		this.platform.animate(rockN);

		//var islandScale = easeOne('easeOutElastic', islandN) + 0.00000000001;
		var islandScale = easeOne('easeInOutQuad',islandN) + 0.00000000001;

		this.island.scale.set(islandScale,islandScale,islandScale);


		// First island, just trees
		if (this.mode == 1)
		{
			// ================================================================================
			// Island 1 - just trees

			this.trees[0].setAge(segmentTransition(0.0, 0.4,topN));
			this.trees[1].setAge(segmentTransition(0.2, 0.6,topN));
			this.trees[2].setAge(segmentTransition(0.4, 0.8,topN));
			this.trees[3].setAge(segmentTransition(0.6, 1.0,topN));


			var r1 = segmentTransition(0.1, 0.3,topN) + 0.00000001;
			var r2 = segmentTransition(0.4, 0.5,topN) + 0.00000001;
			var r3 = segmentTransition(0.5, 0.6,topN) + 0.00000001;

			this.rocks[0].scale.set(r1,r1,r1);
			this.rocks[1].scale.set(r2,r2,r2);
			this.rocks[2].scale.set(r3,r3,r3);

			/*Math.seedrandom(this.fitte++);
			console.log('seed is now: '+this.fitte);
			for (var i=0; i<this.trees.length; i++)
			{
				var scale = 0.4 + Math.random()*0.2;
				this.trees[i].scale.set(scale, scale, scale);
				this.trees[i].position.x = (Math.random()-0.5)*2 * 10;
				this.trees[i].position.z = (Math.random()-0.5)*2 * 10;
				this.trees[i].position.y = this.findGroundLevel(this.trees[i].position.x, this.trees[i].position.z);
			}*/
		}

	}

};

THREE.FloatingIsland.prototype = Object.create( THREE.Object3D.prototype);
THREE.FloatingIsland.prototype.constructor = THREE.FloatingIsland;
