define(["three", "camera", "skySphere", "meshTree", "util", "random", "objects"],
    function(THREE, camera, skySphere, MeshTree, Util, Random, objects) {
        var scene = new THREE.Scene();

        var hat;

        var light, hemiLight
        var textMaterial;
        var textPlaneMesh;

        var frontLight;

        var hat;

        var sceneTime = 0;

        scene.init = function() {
            light = new THREE.SpotLight(0xFFFFFF, 2);
            light.position.set(-5, 10, 0);

            hemiLight = new THREE.HemisphereLight(0xFFFFFF, 0x666666, 1);
            frontLight = new THREE.PointLight(0xFFFFFF, 0.1, 150);
            frontLight.position.set(0, 0, 50);

            scene.add(frontLight);

            textPlaneMesh = objects.nipplePlane.clone();
            textPlaneMesh.position.set(-25, 0, 0);

            hat = objects.hat.clone();
            hat.position.y = 20;

            hat.material = new THREE.MeshPhongMaterial({
                ambient: 0x333333, color: 0xff00ee, specular: 0x999999, shininess: 2
            });

            textPlaneMesh.add(hat);

            scene.add(textPlaneMesh);
            scene.add(hemiLight);
            scene.add(skySphere.clone());
            scene.add(light);
        }

        scene.enter = function() {
            camera.position.set(-30, 0, 100);
            camera.rotation.set(0, -0.2, 0);

            sceneTime = 0;
        }

        scene.update = function(t, dt) {
            sceneTime += dt;

            var beatTime = Util.beatsToTime(130, {
                beats: 2
            });

            textPlaneMesh.position.x = (sceneTime * 15) - 60;
            textPlaneMesh.position.y = Math.sin(sceneTime * Util.PI2) * 5;

            this.fadeAmount = (1.0 - (sceneTime * 2)).clamp(0, 1);

            var fadeOutTime = Util.beatsToTime(130, {bars: 4});

            if(sceneTime >= fadeOutTime) {
                this.fadeColor = new THREE.Vector3(0, 0, 0);
                this.fadeAmount = ((t - fadeOutTime) * fadeOutTime / 8).clamp(0, 1);
            }
        }

        return scene;
    });
                  