<commit_before>var camera, scene, renderer, controls;
var container;
window.onload = init;
var cubeSize = 20;
var lastAddedSnakePart;
var YouBitTheWrongStuff = false;
var FoodID;
var collidableMeshList = [];
var collidableMeshListIndex;
var windowWidth;
var	windowHeight;

	var views = [
	{
		left: 0,
		bottom: 0,
		width: 0.7,
		height: 1.0,
		background: new THREE.Color().setRGB( 0.5, 0.5, 0.7 ),
		eye: [ 0, 30, 18 ],
		up: [ 0, 1, 0 ],
		fov: 70,
		updateCamera: function ( camera, scene, obj ) {
		  //camera.position.x += mouseX * 0.05;
		  //camera.position.x = Math.max( Math.min( camera.position.x, 2000 ), -2000 );
		  camera.lookAt( scene.position );
		}
	},
	{
		left: 0.7,
		bottom: 0,
		width: 0.3,
		height: 0.5,
		background: new THREE.Color().setRGB( 0.7, 0.5, 0.5 ),
		eye: [ 0, 18, 0 ],
		up: [ 0, 0, 1 ],
		fov: 45,
		updateCamera: function ( camera, scene, obj) {
		  //camera.position.x -= mouseX * 0.05;
		  //camera.position.x = Math.max( Math.min( camera.position.x, 2000 ), -2000 );
		  camera.lookAt( camera.position.clone().setY( 0 ) );
		}
	},
	{
		left: 0.7,
		bottom: 0.5,
		width: 0.3,
		height: 0.5,
		background: new THREE.Color().setRGB( 0.5, 0.7, 0.7 ),
		eye: [ 7, 4, 7 ],
		up: [ 0, 1, 0 ],
		fov: 30,
		updateCamera: function ( camera, scene, obj ) {
		  //camera.position.y -= mouseX * 0.05;
		  //camera.position.y = Math.max( Math.min( camera.position.y, 1600 ), -1600 );
		  camera.lookAt( scene.position );
		}
	}
];

function init() {
	var clock = new THREE.Clock();
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(45 , window.innerWidth / window.innerHeight , 0.1, 1000);
    var renderer = new THREE.WebGLRenderer({
        alpha: true,
      });
    renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMapEnabled = true;

	//Create head of snake with texture
    var snakeHeadTexture = THREE.ImageUtils.loadTexture('snakehead.jpg');
    var snakeHeadGeometry = new THREE.SphereGeometry(1,5,5);
    var snakeHeadMaterial = new THREE.MeshPhongMaterial();
    snakeHeadMaterial.map = snakeHeadTexture;
    var snakeHead = new THREE.Mesh(snakeHeadGeometry, snakeHeadMaterial);

    //snakeHead.material.side = THREE.DoubleSide;
    snakeHead.material.map.wrapS = THREE.RepeatWrapping;
    snakeHead.material.map.wrapT = THREE.RepeatWrapping;
    snakeHead.material.map.repeat.set(1, 1);
    snakeHead.name ="Snake";
    snakeHead.position.y = -cubeSize/2 + 2;

    //snakeHead.name = "SnakeHead";
	collidableMeshList.push(snakeHead);

    var snaketexture = THREE.ImageUtils.loadTexture('snakeskin.jpg');
    var snakeGeometry = new THREE.SphereGeometry(1,5,5);
    var snakeMaterial = new THREE.MeshPhongMaterial();
    snakeMaterial.map = snaketexture;
    var snake = new THREE.Mesh(snakeGeometry, snakeMaterial);
	snake.name = "SnakeFirstPart";
    snake.material.map.wrapS = THREE.RepeatWrapping;
    snake.material.map.wrapT = THREE.RepeatWrapping;
    snake.material.map.repeat.set(1, 1);
    snake.position.z = 1;

    var test = new THREE.SphereGeometry(1,1,1)

    var testGeometry = new THREE.SphereGeometry(1,5,5);
    var testMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
    var test = new THREE.Mesh(testGeometry, testMaterial);
    test.position.z = -4;

    snakeHead.add(test);

    snakeHead.add(snake);
	// add the snakeparts to collidable Objects
	//collidableMeshList.push(snake);
	lastAddedSnakePart = snake;
	scene.add(snakeHead);

	//Kameras
	for (var ii =  0; ii < views.length; ++ii ) {
		var view = views[ii];
		camera = new THREE.PerspectiveCamera( view.fov, window.innerWidth / window.innerHeight, 1, 10000 );
		camera.position.x = view.eye[ 0 ];
		camera.position.y = view.eye[ 1 ];
		camera.position.z = view.eye[ 2 ];
		camera.up.x = view.up[ 0 ];
		camera.up.y = view.up[ 1 ];
		camera.up.z = view.up[ 2 ];
		view.camera = camera;
	}

	camera = views[0].camera;

    // create a playgroundCube
    var playgroundCubeGeometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);

    var playgroundCubeMaterial = new THREE.MeshLambertMaterial( {
            color: 0xffffff,
            opacity: 0.4,
            transparent: true,
    } );
    var playgroundCube = new THREE.Mesh(playgroundCubeGeometry, playgroundCubeMaterial);
    playgroundCube.material.side = THREE.DoubleSide;
    // position the cube
    playgroundCube.position.x = 0;
    playgroundCube.position.y = 0;
    playgroundCube.position.z = 0;
    // add the cube to the scene
    scene.add(playgroundCube);
	// add the cube to collidable Objects
	collidableMeshList.push(playgroundCube);

    var planeGeometry = new THREE.PlaneGeometry(cubeSize, cubeSize, cubeSize);
    var planeMaterial = new THREE.MeshLambertMaterial({
            color: 0x6F00FF,
            opacity: 0,
            transparent: true,
    });
    var plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.material.side = THREE.DoubleSide;
    plane.rotation.x =  Math.PI / 2;
    plane.position.x = 0;
    plane.position.y = -cubeSize/2;
    plane.position.z = 0;
    //playgroundCube.add(plane);
	//scene.add(plane);
	// add the plane to collidable Objects
	//collidableMeshList.push(plane);

    //Create space background is a large sphere
    var spacetexture = THREE.ImageUtils.loadTexture('space.jpg');
    var spacesphereGeometry = new THREE.SphereGeometry(60,60,60);
    var spacesphereMaterial = new THREE.MeshPhongMaterial();
    spacesphereMaterial.map = spacetexture;
    var spacesphere = new THREE.Mesh(spacesphereGeometry, spacesphereMaterial);
    //spacesphere needs to be double sided
    spacesphere.material.side = THREE.DoubleSide;
    spacesphere.material.map.wrapS = THREE.RepeatWrapping;
    spacesphere.material.map.wrapT = THREE.RepeatWrapping;
    spacesphere.material.map.repeat.set(5, 3);
    scene.add(spacesphere);

    // position and point the camera to the center of the scene
    camera.position.x = 0;
    camera.position.y = 0;
    camera.position.z = -50;
    camera.lookAt(scene.position);

    // add subtle ambient lighting
    var ambientLight = new THREE.AmbientLight(0x0c0c0c);
    scene.add(ambientLight);
    // add spotlight for scene
    var spotLight = new THREE.SpotLight(0xffffff);
    spotLight.position.set(-40, 60, -10);
    spotLight.castShadow = true;
    scene.add(spotLight);

    // add spotlight in cube
    var spotLightCube = new THREE.SpotLight(0xffffff);
    spotLightCube.position.set(0, -100, 0);
    spotLightCube.castShadow = true;
    playgroundCube.add(spotLightCube);

    var spotLightCube2 = new THREE.SpotLight(0xffffff);
    spotLightCube2.position.set(0, 0, 0);
    spotLightCube2.castShadow = true;
    playgroundCube.add(spotLightCube2);

    //playgroundCube.material.side = THREE.DoubleSide;
    var rotateCamera = true;
    var addNewFood = true;
    var addSnake = true;
    // add the output of the renderer to the html element
    //document.getElementById("WebGL-output"). append(renderer.domElement);
	container = document.createElement( 'div' );
	document.body.appendChild( container );

	// Fly Controls
	controls = new THREE.FlyControls( snakeHead );

	controls.movementSpeed = 1;
	controls.domElement = container;
	controls.rollSpeed = Math.PI / 24;
	controls.autoForward = false;
	controls.dragToLook = false;

	container.appendChild( renderer.domElement );

    // event listener for click on play
    var instruction = document.getElementById( 'instructions' );
    var blocker = document.getElementById( 'blocker' );
    instructions.addEventListener( 'click', function ( event ) {
        instructions.style.display = 'none';
        blocker.style.display = 'none';
        // set camera in block
        //camera.rotation.y = 45 * Math.PI/180;
        camera.position.x = 0;
        camera.position.y = 0;
        camera.position.z = 0;
        // stop rotation
        rotateCamera = false;
    }, false );

	//event listener to resize the scene
	window.addEventListener( 'resize', onWindowResize, false );

	function onWindowResize( event ) {

				SCREEN_HEIGHT = window.innerHeight;
				SCREEN_WIDTH  = window.innerWidth;

				renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );

				camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
				camera.updateProjectionMatrix();
	}

	function addToTail() {
	var snaketexture = THREE.ImageUtils.loadTexture('snakeskin.jpg');
    var snakeGeometry = new THREE.SphereGeometry(1,5,5);
    var snakeMaterial = new THREE.MeshPhongMaterial();
    snakeMaterial.map = snaketexture;
    var snakePart = new THREE.Mesh(snakeGeometry, snakeMaterial);
	snakePart.name = "SnakePartX";
    snakePart.material.map.wrapS = THREE.RepeatWrapping;
    snakePart.material.map.wrapT = THREE.RepeatWrapping;
    snakePart.material.map.repeat.set(1, 1);
    snakePart.position.z = 1;
    lastAddedSnakePart.add(snakePart);
	// add the snakeparts to collidable Objects
	lastAddedSnakePart = snakePart;
	}

	// Spawn new Food
	function getNewFood() {
    var foodGeometry = new THREE.BoxGeometry(1, 1, 1);
    var foodMaterial = new THREE.MeshLambertMaterial( {
            color: 0x315DFF,
            opacity: 1.0,
            transparent: false
        } );
    var food = new THREE.Mesh(foodGeometry, foodMaterial);
    food.position.x = Math.floor(Math.random() * ((cubeSize/2 - 1) + (cubeSize/2 - 1 + 1)) - (cubeSize/2));
    food.position.y = Math.floor(Math.random() * ((cubeSize/2 - 1) + (cubeSize/2 - 1 + 1)) - (cubeSize/2));
    food.position.z = Math.floor(Math.random() * ((cubeSize/2 - 1) + (cubeSize/2 - 1 + 1)) - (cubeSize/2));
	food.name = "Food";
	FoodID = food.id;
	collidableMeshList.push(food);	// adds food as a collidable object
	collidableMeshListIndex = collidableMeshList.length - 1;
    return food;
	}

	//	Collision Check
	function collision() {

		var originPoint = snakeHead.position.clone();

		for (var vertexIndex = 0; vertexIndex < snakeHead.geometry.vertices.length; vertexIndex++)
		{
		var localVertex = snakeHead.geometry.vertices[vertexIndex].clone();
		var globalVertex = localVertex.applyMatrix4( snakeHead.matrix );
		var directionVector = globalVertex.sub( snakeHead.position );

		var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize() );
		var collisionResults = ray.intersectObjects( collidableMeshList );
		if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() ) {
			if(collisionResults[0].object.name == "Food") {
				collidableMeshList.splice(collidableMeshListIndex,1);
				scene.remove(scene.getObjectById(FoodID));
				addToTail();
				scene.add(getNewFood());
				scene.add(snakeHead);
				}
			else {
				YouBitTheWrongStuff = true;
				}
			}
		}
	}

	function updateSize() {

		if ( windowWidth != window.innerWidth || windowHeight != window.innerHeight ) {

			windowWidth  = window.innerWidth;
			windowHeight = window.innerHeight;

			renderer.setSize ( windowWidth, windowHeight );

		}

	}

    render();
    function render() {
		updateSize();
        requestAnimationFrame(render);
		for ( var ii = 0; ii < views.length; ++ii ) {

			view = views[ii];
			camera = view.camera;

			view.updateCamera( camera, scene, test);

			var left   = Math.floor( windowWidth  * view.left );
			var bottom = Math.floor( windowHeight * view.bottom );
			var width  = Math.floor( windowWidth  * view.width );
			var height = Math.floor( windowHeight * view.height );
			renderer.setViewport( left, bottom, width, height );
			renderer.setScissor( left, bottom, width, height );
			renderer.setScissorTest( true );
			renderer.setClearColor( view.background );

			camera.aspect = width / height;
			camera.updateProjectionMatrix();

			if(ii==0){
				snakeHead.add(camera);
			}

			renderer.render( scene, camera );
	}

		camera = views[0].camera;

		//check collision
		if(YouBitTheWrongStuff==false) {
			collision();
		} else {
			controls.movementSpeed = 0;
			window.alert("You bit off more than you can chew! :(");
		}
		//Update the camera view
		var delta = clock.getDelta();
		controls.update( delta );
        // check rotation
        if (rotateCamera) {
            spacesphere.rotation.y += 0.001;
        }
        // check if new food has to be added
        if (addNewFood) {
            scene.add(getNewFood());
            addNewFood = false;
        }

        /*if (addSnake) {
            scene.add(showSnake());
            addSnake = false;
        }*/
        //renderer.render(scene, camera);
    }
}<commit_msg>add edgesGeomerty, add pointLight<commit_after>var camera, scene, renderer, controls;
var container;
window.onload = init;
var cubeSize = 20;
var lastAddedSnakePart;
var YouBitTheWrongStuff = false;
var FoodID;
var collidableMeshList = [];
var collidableMeshListIndex;
var windowWidth;
var	windowHeight;

	var views = [
	{
		left: 0,
		bottom: 0,
		width: 0.7,
		height: 1.0,
		background: new THREE.Color().setRGB( 0.5, 0.5, 0.7 ),
		eye: [ 0, 30, 18 ],
		up: [ 0, 1, 0 ],
		fov: 70,
		updateCamera: function ( camera, scene, obj ) {
		  //camera.position.x += mouseX * 0.05;
		  //camera.position.x = Math.max( Math.min( camera.position.x, 2000 ), -2000 );
		  camera.lookAt( scene.position );
		}
	},
	{
		left: 0.7,
		bottom: 0,
		width: 0.3,
		height: 0.5,
		background: new THREE.Color().setRGB( 0.7, 0.5, 0.5 ),
		eye: [ 0, 18, 0 ],
		up: [ 0, 0, 1 ],
		fov: 45,
		updateCamera: function ( camera, scene, obj) {
		  //camera.position.x -= mouseX * 0.05;
		  //camera.position.x = Math.max( Math.min( camera.position.x, 2000 ), -2000 );
		  camera.lookAt( camera.position.clone().setY( 0 ) );
		}
	},
	{
		left: 0.7,
		bottom: 0.5,
		width: 0.3,
		height: 0.5,
		background: new THREE.Color().setRGB( 0.5, 0.7, 0.7 ),
		eye: [ 7, 4, 7 ],
		up: [ 0, 1, 0 ],
		fov: 30,
		updateCamera: function ( camera, scene, obj ) {
		  //camera.position.y -= mouseX * 0.05;
		  //camera.position.y = Math.max( Math.min( camera.position.y, 1600 ), -1600 );
		  camera.lookAt( scene.position );
		}
	}
];

function init() {
	var clock = new THREE.Clock();
    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera(45 , window.innerWidth / window.innerHeight , 0.1, 1000);
    var renderer = new THREE.WebGLRenderer({
        alpha: true,
      });
    renderer.setClearColor(new THREE.Color(0xEEEEEE, 1.0));
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.shadowMapEnabled = true;

	//Create head of snake with texture
    var snakeHeadTexture = THREE.ImageUtils.loadTexture('snakehead.jpg');
    var snakeHeadGeometry = new THREE.SphereGeometry(1,5,5);
    var snakeHeadMaterial = new THREE.MeshPhongMaterial();
    snakeHeadMaterial.map = snakeHeadTexture;
    var snakeHead = new THREE.Mesh(snakeHeadGeometry, snakeHeadMaterial);

    snakeHead.material.map.wrapS = THREE.RepeatWrapping;
    snakeHead.material.map.wrapT = THREE.RepeatWrapping;
    snakeHead.material.map.repeat.set(1, 1);
    snakeHead.name ="Snake";
    snakeHead.position.y = -cubeSize/2 + 2;

	collidableMeshList.push(snakeHead);

    var snaketexture = THREE.ImageUtils.loadTexture('snakeskin.jpg');
    var snakeGeometry = new THREE.SphereGeometry(1,5,5);
    var snakeMaterial = new THREE.MeshPhongMaterial();
    snakeMaterial.map = snaketexture;
    var snake = new THREE.Mesh(snakeGeometry, snakeMaterial);
	snake.name = "SnakeFirstPart";
    snake.material.map.wrapS = THREE.RepeatWrapping;
    snake.material.map.wrapT = THREE.RepeatWrapping;
    snake.material.map.repeat.set(1, 1);
    snake.position.z = 1;

    var test = new THREE.SphereGeometry(1,1,1)

    var testGeometry = new THREE.SphereGeometry(1,5,5);
    var testMaterial = new THREE.MeshLambertMaterial({color: 0xffffff});
    var test = new THREE.Mesh(testGeometry, testMaterial);
    test.position.z = -4;

    snakeHead.add(test);

    snakeHead.add(snake);
	// add the snakeparts to collidable Objects
	//collidableMeshList.push(snake);
	lastAddedSnakePart = snake;
	scene.add(snakeHead);

	//Kameras
	for (var ii =  0; ii < views.length; ++ii ) {
		var view = views[ii];
		camera = new THREE.PerspectiveCamera( view.fov, window.innerWidth / window.innerHeight, 1, 10000 );
		camera.position.x = view.eye[ 0 ];
		camera.position.y = view.eye[ 1 ];
		camera.position.z = view.eye[ 2 ];
		camera.up.x = view.up[ 0 ];
		camera.up.y = view.up[ 1 ];
		camera.up.z = view.up[ 2 ];
		view.camera = camera;
	}

	camera = views[0].camera;

    // create a playgroundCube
    var playgroundCubeGeometry = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);

    var playgroundCubeMaterial = new THREE.MeshLambertMaterial( {
            color: 0xffffff,
            opacity: 0.4,
            transparent: true,
            shading: THREE.FlatShading,
            outline: true,
    } );
    var playgroundCube = new THREE.Mesh(playgroundCubeGeometry, playgroundCubeMaterial);
    playgroundCube.material.side = THREE.DoubleSide;
    // position the cube
    playgroundCube.position.x = 0;
    playgroundCube.position.y = 0;
    playgroundCube.position.z = 0;
    // add the cube to the scene
    scene.add(playgroundCube);
	//add edges
	var edges= new THREE.EdgesGeometry( playgroundCubeGeometry ); // or WireframeGeometry( geometry )
	var edgeMaterial = new THREE.LineBasicMaterial( { color: 0xffffff, linewidth: 2 } );
	var cubeEdges = new THREE.LineSegments( edges, edgeMaterial );
	scene.add( cubeEdges );

	// add the cube to collidable Objects
	collidableMeshList.push(playgroundCube);

    var planeGeometry = new THREE.PlaneGeometry(cubeSize, cubeSize, cubeSize);
    var planeMaterial = new THREE.MeshLambertMaterial({
            color: 0x6F00FF,
            opacity: 0,
            transparent: true,
    });
    var plane = new THREE.Mesh(planeGeometry, planeMaterial);
    plane.material.side = THREE.DoubleSide;
    plane.rotation.x =  Math.PI / 2;
    plane.position.x = 0;
    plane.position.y = -cubeSize/2;
    plane.position.z = 0;
    //playgroundCube.add(plane);
	//scene.add(plane);
	// add the plane to collidable Objects
	//collidableMeshList.push(plane);

    //Create space background is a large sphere
    var spacetexture = THREE.ImageUtils.loadTexture('space.jpg');
    var spacesphereGeometry = new THREE.SphereGeometry(60,60,60);
    var spacesphereMaterial = new THREE.MeshPhongMaterial();
    spacesphereMaterial.map = spacetexture;
    var spacesphere = new THREE.Mesh(spacesphereGeometry, spacesphereMaterial);
    //spacesphere needs to be double sided
    spacesphere.material.side = THREE.DoubleSide;
    spacesphere.material.map.wrapS = THREE.RepeatWrapping;
    spacesphere.material.map.wrapT = THREE.RepeatWrapping;
    spacesphere.material.map.repeat.set(5, 3);
    scene.add(spacesphere);

    // position and point the camera to the center of the scene
    camera.position.x = 0;
    camera.position.y = 0;
    camera.position.z = -50;
    camera.lookAt(scene.position);

    // add subtle ambient lighting
    var ambientLight = new THREE.AmbientLight(0x0c0c0c);
    scene.add(ambientLight);
    // add spotlight for scene
    var spotLight = new THREE.SpotLight(0xffffff);
    spotLight.position.set(-40, 60, -10);
    spotLight.castShadow = true;
    scene.add(spotLight);

    // add spotlight in cube
    var spotLightCube = new THREE.SpotLight(0xffffff);
    spotLightCube.position.set(0, -100, 0);
    spotLightCube.castShadow = true;
    playgroundCube.add(spotLightCube);

    var pointLightCube = new THREE.PointLight(0xffffff);
    pointLightCube.position.set(0, 0, 0);
    pointLightCube.castShadow = true;
    playgroundCube.add(pointLightCube);

    //playgroundCube.material.side = THREE.DoubleSide;
    var rotateCamera = true;
    var addNewFood = true;
    var addSnake = true;
    // add the output of the renderer to the html element
    //document.getElementById("WebGL-output"). append(renderer.domElement);
	container = document.createElement( 'div' );
	document.body.appendChild( container );

	// Fly Controls
	controls = new THREE.FlyControls( snakeHead );

	controls.movementSpeed = 1;
	controls.domElement = container;
	controls.rollSpeed = Math.PI / 24;
	controls.autoForward = false;
	controls.dragToLook = false;

	container.appendChild( renderer.domElement );

    // event listener for click on play
    var instruction = document.getElementById( 'instructions' );
    var blocker = document.getElementById( 'blocker' );
    instructions.addEventListener( 'click', function ( event ) {
        instructions.style.display = 'none';
        blocker.style.display = 'none';
        // set camera in block
        //camera.rotation.y = 45 * Math.PI/180;
        camera.position.x = 0;
        camera.position.y = 0;
        camera.position.z = 0;
        // stop rotation
        rotateCamera = false;
    }, false );

	//event listener to resize the scene
	window.addEventListener( 'resize', onWindowResize, false );

	function onWindowResize( event ) {

				SCREEN_HEIGHT = window.innerHeight;
				SCREEN_WIDTH  = window.innerWidth;

				renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );

				camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
				camera.updateProjectionMatrix();
	}

	function addToTail() {
	var snaketexture = THREE.ImageUtils.loadTexture('snakeskin.jpg');
    var snakeGeometry = new THREE.SphereGeometry(1,5,5);
    var snakeMaterial = new THREE.MeshPhongMaterial();
    snakeMaterial.map = snaketexture;
    var snakePart = new THREE.Mesh(snakeGeometry, snakeMaterial);
	snakePart.name = "SnakePartX";
    snakePart.material.map.wrapS = THREE.RepeatWrapping;
    snakePart.material.map.wrapT = THREE.RepeatWrapping;
    snakePart.material.map.repeat.set(1, 1);
    snakePart.position.z = 1;
    lastAddedSnakePart.add(snakePart);
	// add the snakeparts to collidable Objects
	lastAddedSnakePart = snakePart;
	}

	// Spawn new Food
	function getNewFood() {
    var foodGeometry = new THREE.BoxGeometry(1, 1, 1);
    var foodMaterial = new THREE.MeshLambertMaterial( {
            color: 0x315DFF,
            opacity: 1.0,
            transparent: false
        } );
    var food = new THREE.Mesh(foodGeometry, foodMaterial);
    food.position.x = Math.floor(Math.random() * ((cubeSize/2 - 1) + (cubeSize/2 - 1 + 1)) - (cubeSize/2));
    food.position.y = Math.floor(Math.random() * ((cubeSize/2 - 1) + (cubeSize/2 - 1 + 1)) - (cubeSize/2));
    food.position.z = Math.floor(Math.random() * ((cubeSize/2 - 1) + (cubeSize/2 - 1 + 1)) - (cubeSize/2));
	food.name = "Food";
	FoodID = food.id;
	collidableMeshList.push(food);	// adds food as a collidable object
	collidableMeshListIndex = collidableMeshList.length - 1;
    return food;
	}

	function spawnSpaceTrees() {
		//TODO
	}

	//	Collision Check
	function collision() {

		var originPoint = snakeHead.position.clone();

		for (var vertexIndex = 0; vertexIndex < snakeHead.geometry.vertices.length; vertexIndex++)
		{
		var localVertex = snakeHead.geometry.vertices[vertexIndex].clone();
		var globalVertex = localVertex.applyMatrix4( snakeHead.matrix );
		var directionVector = globalVertex.sub( snakeHead.position );

		var ray = new THREE.Raycaster( originPoint, directionVector.clone().normalize() );
		var collisionResults = ray.intersectObjects( collidableMeshList );
		if ( collisionResults.length > 0 && collisionResults[0].distance < directionVector.length() ) {
			if(collisionResults[0].object.name == "Food") {
				collidableMeshList.splice(collidableMeshListIndex,1);
				scene.remove(scene.getObjectById(FoodID));
				addToTail();
				scene.add(getNewFood());
				scene.add(snakeHead);
				}
			else {
				YouBitTheWrongStuff = true;
				}
			}
		}
	}

	function updateSize() {

		if ( windowWidth != window.innerWidth || windowHeight != window.innerHeight ) {

			windowWidth  = window.innerWidth;
			windowHeight = window.innerHeight;

			renderer.setSize ( windowWidth, windowHeight );

		}

	}

    render();
    function render() {
		updateSize();
        requestAnimationFrame(render);
		for ( var ii = 0; ii < views.length; ++ii ) {

			view = views[ii];
			camera = view.camera;

			view.updateCamera( camera, scene, test);

			var left   = Math.floor( windowWidth  * view.left );
			var bottom = Math.floor( windowHeight * view.bottom );
			var width  = Math.floor( windowWidth  * view.width );
			var height = Math.floor( windowHeight * view.height );
			renderer.setViewport( left, bottom, width, height );
			renderer.setScissor( left, bottom, width, height );
			renderer.setScissorTest( true );
			renderer.setClearColor( view.background );

			camera.aspect = width / height;
			camera.updateProjectionMatrix();

			if(ii==0){
				snakeHead.add(camera);
			}

			renderer.render( scene, camera );
	}

		camera = views[0].camera;

		//check collision
		if(YouBitTheWrongStuff==false) {
			collision();
		} else {
			controls.movementSpeed = 0;

			window.alert("You bit off more than you can chew! :(");
		}
		//Update the camera view
		var delta = clock.getDelta();
		controls.update( delta );
        // check rotation
        if (rotateCamera) {
            spacesphere.rotation.y += 0.001;
        }
        // check if new food has to be added
        if (addNewFood) {
            scene.add(getNewFood());
            addNewFood = false;
        }

        /*if (addSnake) {
            scene.add(showSnake());
            addSnake = false;
        }*/
        //renderer.render(scene, camera);
    }
}<|endoftext|>


<commit_before>function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    gvm.projectId = $("#projectHeader").data('value');

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.competences = ko.observableArray([]);

    gvm.getProjectInfo = function() {
        $.getJSON('/api/project/' + gvm.projectId, function(data) {
            gvm.pageHeader(data[0].code + ' - ' + data[0].name);
        });
    };

    gvm.getAllData = function() {
         $.getJSON('/api/project/getAllData/' + gvm.projectId, function(data) {
            console.log(data);
         });
    };

    gvm.updateCompetence = function(id, code, description, max, weight) {
        var comp = new Competence(this, id, code, description, weight);
        gvm.competences.push(comp);
        return comp;
    };

    gvm.clearStructure = function() {
        gvm.competences.destroyAll();
    };
}

function initPage() {
    fetchProjectStructure();
    viewModel.getProjectInfo();
    viewModel.getAllData();

    $(".savePageBtn").click(function(){
        saveProjectScore();
    });
}

function fetchProjectScore()
{
    $.getJSON("/api/projectscore/" + projectid + "/" + studentid, function(data)
    {
        $.each(viewModel.competences(), function(i,item){
                    $.each(item.subcompetences(), function(i, subcomp)
                    {
                        $.each(subcomp.indicators(),function(i,indic)
                        {
                            for(var i = 0; i < data.length; i++) {
                            if (indic.id() == data[i].indicator) {
                                indic.score(data[i].score);
                                indic.scoreid(data[i].id);
                            }
                    }
                });
            });
        });
    });
}

function saveProjectScore()
{
    $.ajax({
        type: "POST",
        url: "/api/projectscore/" + projectid + "/" + studentid,
        data: ko.toJSON(viewModel.competences),
        success: function(){
            // TODO make multilangual and with modals
            alert("Saved projectscore to server");
            console.log(viewModel.competences());
            //window.location = "/assess/project/" + projectid + "/students";
        }
    });
}

function fetchProjectStructure() {
    viewModel.clearStructure();

    $.getJSON("/api/projectstructure/" + projectid, function(data){
        $.each(data, function(i, item){
            var competence = viewModel.updateCompetence(item.id, item.code, item.description);

            $.each(item.subcompetences, function(i, subcomp){
                var subcompetence = new SubCompetence(competence, subcomp.id, subcomp.code, subcomp.description);
                competence.subcompetences.push(subcompetence);

                $.each(subcomp.indicators, function(i, indic){
                    subcompetence.indicators.push(new Indicator(subcompetence, indic.id, indic.name, indic.description, 0,indic.id, indic.pointType));
                });
            });
        });
        fetchProjectScore();
    });
}

function Competence(viewmodel, id, code, name, subcompetences) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        subcompetences: ko.observableArray(subcompetences)
    };
}

function SubCompetence(parent, id, code, name, indicators) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        indicators: ko.observableArray(indicators)
    };
}

function Indicator(parent, id, name, description, score, scoreid,pointType, checked) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        description: ko.observable(description),
        score: ko.observable(score),
        scoreid: ko.observable(scoreid),
        pointType: ko.observable(pointType),
        checked : ko.observable(checked)
    };
}<commit_msg>Document Grading<commit_after>function pageViewModel(gvm) {
    // projecttitle
    gvm.projecttitle = ko.observable("");
    gvm.projectId = $("#projectHeader").data('value');

    // Page specific i18n bindings
    gvm.title = ko.computed(function (){i18n.setLocale(gvm.lang()); return gvm.app() + ' - ' + i18n.__("ProjectTitle") + ": " + gvm.projecttitle();}, gvm);
    gvm.pageHeader = ko.observable("Project");
    gvm.projectname = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("ProjectName");}, gvm);
    gvm.savePage = ko.computed(function(){i18n.setLocale(gvm.lang()); return i18n.__("SaveBtn");}, gvm);

    gvm.competences = ko.observableArray([]);

    gvm.getProjectInfo = function() {
        $.getJSON('/api/project/' + gvm.projectId, function(data) {
            gvm.pageHeader(data[0].code + ' - ' + data[0].name);
        });
    };

    gvm.getAllData = function() {
         $.getJSON('/api/project/getAllData/' + gvm.projectId, function(data) {
            console.log(data);
         });
    };

    gvm.updateCompetence = function(id, code, description, max, weight) {
        var comp = new Competence(this, id, code, description, weight);
        gvm.competences.push(comp);
        return comp;
    };

    gvm.clearStructure = function() {
        gvm.competences.destroyAll();
    };
}

function initPage() {
    fetchProjectStructure();
    viewModel.getProjectInfo();
    viewModel.getAllData();

    $(".savePageBtn").click(function(){
        saveProjectScore();
    });
}

function fetchProjectScore()
{
    $.getJSON("/api/projectscore/" + projectid + "/" + studentid, function(data)
    {
        $.each(viewModel.competences(), function(i,item){
                    $.each(item.subcompetences(), function(i, subcomp)
                    {
                        $.each(subcomp.indicators(),function(i,indic)
                        {
                            for(var i = 0; i < data.length; i++) {
                            if (indic.id() == data[i].indicator) {
                                indic.score(data[i].score);
                                indic.scoreid(data[i].id);
                            }
                    }
                });
            });
        });
    });
}

function saveProjectScore()
{
    $.ajax({
        type: "POST",
        url: "/api/projectscore/" + projectid + "/" + studentid,
        data: ko.toJSON(viewModel.competences),
        success: function(){
            // TODO make multilangual and with modals
            alert("Saved projectscore to server");
            console.log(viewModel.competences);
            //window.location = "/assess/project/" + projectid + "/students";
        }
    });
}

function fetchProjectStructure() {
    viewModel.clearStructure();

    $.getJSON("/api/projectstructure/" + projectid, function(data){
        $.each(data, function(i, item){
            var competence = viewModel.updateCompetence(item.id, item.code, item.description);

            $.each(item.subcompetences, function(i, subcomp){
                var subcompetence = new SubCompetence(competence, subcomp.id, subcomp.code, subcomp.description);
                competence.subcompetences.push(subcompetence);

                $.each(subcomp.indicators, function(i, indic){
                    subcompetence.indicators.push(new Indicator(subcompetence, indic.id, indic.name, indic.description, 0,indic.id, indic.pointType));
                });
            });
        });
        fetchProjectScore();
    });
}

function Competence(viewmodel, id, code, name, subcompetences) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        subcompetences: ko.observableArray(subcompetences)
    };
}

function SubCompetence(parent, id, code, name, indicators) {
    return {
        id: ko.observable(id),
        code: ko.observable(code),
        name: ko.observable(name),
        indicators: ko.observableArray(indicators)
    };
}

function Indicator(parent, id, name, description, score, scoreid,pointType, checked) {
    return {
        id: ko.observable(id),
        name: ko.observable(name),
        description: ko.observable(description),
        score: ko.observable(score),
        scoreid: ko.observable(scoreid),
        pointType: ko.observable(pointType),
        checked : ko.observable(checked)
    };
}<|endoftext|>


<commit_before>// Copyright 2014-2018, University of Colorado Boulder

/**
 * shared constants for the Energy Forms and Changes simulation
 *
 * @author John Blanco
 */

define( function( require ) {
  'use strict';

  var energyFormsAndChanges = require( 'ENERGY_FORMS_AND_CHANGES/energyFormsAndChanges' );

  // modules
  var Color = require( 'SCENERY/util/Color' );
  var LinearFunction = require( 'DOT/LinearFunction' );
  var ScreenView = require( 'JOIST/ScreenView' );
  var Util = require( 'DOT/Util' );
  var Vector2 = require( 'DOT/Vector2' );

  // constants used for creating projections that have a 3D-ish look.
  var Z_TO_X_OFFSET_MULTIPLIER = -0.25;
  var Z_TO_Y_OFFSET_MULTIPLIER = -0.25;

  // physical temperature constants
  var ROOM_TEMPERATURE = 296; // in degrees Kelvin
  var WATER_FREEZING_POINT_TEMPERATURE = 273.15; // in degrees Kelvin

  // constants that define physical parameters of various rectangular objects.
  var BRICK_DENSITY = 3300; // in kg/m^3, source = design document plus some tweaking to keep chunk numbers reasonable
  var BRICK_SPECIFIC_HEAT = 840; // in J/kg-K, source = design document
  var BLOCK_SURFACE_WIDTH = 0.045;

  // brick constants needed for energy chunk mapping
  var BRICK_ENERGY_AT_ROOM_TEMPERATURE = Math.pow( BLOCK_SURFACE_WIDTH, 3 ) * BRICK_DENSITY * BRICK_SPECIFIC_HEAT * ROOM_TEMPERATURE; // In joules.
  var BRICK_ENERGY_AT_FREEZING_TEMPERATURE = Math.pow( BLOCK_SURFACE_WIDTH, 3 ) * BRICK_DENSITY * BRICK_SPECIFIC_HEAT * WATER_FREEZING_POINT_TEMPERATURE; // In joules.

  // constants for temperature-energy mapping functions
  var LOW_ENERGY_FOR_MAP_FUNCTION = BRICK_ENERGY_AT_FREEZING_TEMPERATURE;
  var HIGH_ENERGY_FOR_MAP_FUNCTION = BRICK_ENERGY_AT_ROOM_TEMPERATURE;
  var NUM_ENERGY_CHUNKS_IN_BRICK_AT_FREEZING = 1.25;
  var NUM_ENERGY_CHUNKS_IN_BRICK_AT_ROOM_TEMP = 2.4; // close to rounding to 3 so that little energy needed to transfer first chunk

  // time values for normal and fast-forward motion
  var FRAMES_PER_SECOND = 60.0;
  var SIM_TIME_PER_TICK_NORMAL = 1 / FRAMES_PER_SECOND;
  var FAST_FORWARD_MULTIPLIER = 4;

  // colors
  var NOMINAL_WATER_OPACITY = 0.75;
  var FIRST_SCREEN_BACKGROUND_COLOR = new Color( 255, 255, 255 );
  var SECOND_SCREEN_BACKGROUND_COLOR = new Color( 255, 255, 225 );

  // mapping function that maps the energy to the number of energy chunks
  var MAP_ENERGY_TO_NUM_CHUNKS = new LinearFunction(
    LOW_ENERGY_FOR_MAP_FUNCTION,
    HIGH_ENERGY_FOR_MAP_FUNCTION,
    NUM_ENERGY_CHUNKS_IN_BRICK_AT_FREEZING,
    NUM_ENERGY_CHUNKS_IN_BRICK_AT_ROOM_TEMP
  );

  // mapping function that maps the number of chunks of energy to the energy value
  var MAP_NUM_CHUNKS_TO_ENERGY = new LinearFunction(
    NUM_ENERGY_CHUNKS_IN_BRICK_AT_FREEZING,
    NUM_ENERGY_CHUNKS_IN_BRICK_AT_ROOM_TEMP,
    LOW_ENERGY_FOR_MAP_FUNCTION,
    HIGH_ENERGY_FOR_MAP_FUNCTION
  );

  var EFACConstants = {

    // physical temperature constants
    ROOM_TEMPERATURE: 296, // in degrees Kelvin
    WATER_FREEZING_POINT_TEMPERATURE: WATER_FREEZING_POINT_TEMPERATURE, // in degrees Kelvin
    WATER_BOILING_POINT_TEMPERATURE: 373.15, // in degrees Kelvin
    OLIVE_OIL_BOILING_POINT_TEMPERATURE: 572.04, // in degrees Kelvin, need to confirm

    // mapping function that maps the energy to the number of energy chunks
    MAP_ENERGY_TO_NUM_CHUNKS: MAP_ENERGY_TO_NUM_CHUNKS,

    // mapping function that maps the number of chunks of energy to the energy value
    MAP_NUM_CHUNKS_TO_ENERGY: MAP_NUM_CHUNKS_TO_ENERGY,

    // time values for normal and fast-forward motion
    FRAMES_PER_SECOND: FRAMES_PER_SECOND,
    SIM_TIME_PER_TICK_NORMAL: 1 / FRAMES_PER_SECOND,
    FAST_FORWARD_MULTIPLIER: FAST_FORWARD_MULTIPLIER,
    SIM_TIME_PER_TICK_FAST_FORWARD: SIM_TIME_PER_TICK_NORMAL * FAST_FORWARD_MULTIPLIER,
    MAX_HEAT_EXCHANGE_TIME_STEP: SIM_TIME_PER_TICK_NORMAL,

    MAP_Z_TO_XY_OFFSET: function( zValue ) {
      return new Vector2( zValue * Z_TO_X_OFFSET_MULTIPLIER, zValue * Z_TO_Y_OFFSET_MULTIPLIER );
    },

    // for comparing temperatures
    SIGNIFICANT_TEMPERATURE_DIFFERENCE: 1E-3, // in degrees Kelvin

    ENERGY_TO_NUM_CHUNKS_MAPPER: function( energy ) {
      return Math.max( Util.roundSymmetric( MAP_ENERGY_TO_NUM_CHUNKS( energy ) ), 0 );
    },

    ENERGY_PER_CHUNK: MAP_NUM_CHUNKS_TO_ENERGY( 2 ) - MAP_NUM_CHUNKS_TO_ENERGY( 1 ),

    // threshold for deciding when two temperatures can be considered equal
    TEMPERATURES_EQUAL_THRESHOLD: 1E-6, // in degrees Kelvin

    // Constant used by all of the "energy systems" in order to keep the amount of energy generated, converted, and
    // consumed consistent.
    MAX_ENERGY_PRODUCTION_RATE: 10000, // in joules/sec

    // colors
    NOMINAL_WATER_OPACITY: 0.7,
    WATER_COLOR_OPAQUE: new Color( 175, 238, 238 ),
    WATER_COLOR_IN_BEAKER: new Color( 175, 238, 238, NOMINAL_WATER_OPACITY ),
    OLIVE_OIL_COLOR_IN_BEAKER: new Color( 227, 207, 88 ),
    FIRST_SCREEN_BACKGROUND_COLOR: FIRST_SCREEN_BACKGROUND_COLOR,
    SECOND_SCREEN_BACKGROUND_COLOR: SECOND_SCREEN_BACKGROUND_COLOR,
    CONTROL_PANEL_BACKGROUND_COLOR: new Color( 229, 236, 255 ), // Pale gray purple. AP, AR, and CK like this.

    // appearance of controls
    CONTROL_PANEL_OUTLINE_LINE_WIDTH: 1.5,
    CONTROL_PANEL_OUTLINE_STROKE: new Color( 120, 120, 120 ),
    CLOCK_CONTROL_BACKGROUND_COLOR: new Color( 120, 120, 120 ),
    ENERGY_SYMBOLS_PANEL_CORNER_RADIUS: 6,
    CONTROL_PANEL_CORNER_RADIUS: 10,
    RESET_ALL_BUTTON_RADIUS: 20,

    // model-view transform scale factor for Energy Systems tab
    ENERGY_SYSTEMS_MVT_SCALE_FACTOR: 2200,

    // constants that control the speed of the energy chunks
    ENERGY_CHUNK_VELOCITY: 0.04, // in meters/sec

    // constants that define physical parameters of various rectangular objects
    WATER_SPECIFIC_HEAT: 3000, // In J/kg-K.  The real value for water is 4186, but this was adjusted so that there
                               // aren't too many chunks and so that a chunk is needed as soon as heating starts.
    WATER_DENSITY: 1000.0, // In kg/m^3, source = design document (and common knowledge).
    OLIVE_OIL_SPECIFIC_HEAT: 1411, // In J/kg-K. real value is 1970 (need to confirm) but this is scaled to match water
    OLIVE_OIL_DENSITY: 916.0, // In kg/m^3, need to confirm with design doc
    BRICK_DENSITY: 3300, // in kg/m^3, source = design document plus some tweaking to keep chunk numbers reasonable
    BRICK_SPECIFIC_HEAT: 840, // in J/kg-K, source = design document
    BLOCK_SURFACE_WIDTH: 0.045,
    BLOCK_PERSPECTIVE_EDGE_PROPORTION: Math.sqrt( Math.pow( Z_TO_X_OFFSET_MULTIPLIER, 2 ) +
                                                  Math.pow( Z_TO_Y_OFFSET_MULTIPLIER, 2 ) ),
    BLOCK_PERSPECTIVE_ANGLE: Math.atan2( -Z_TO_Y_OFFSET_MULTIPLIER, -Z_TO_X_OFFSET_MULTIPLIER ),

    // constants for the burners.
    INITIAL_FLUID_LEVEL: 0.5,
    BURNER_EDGE_TO_HEIGHT_RATIO: 0.2, // multiplier empirically determined for best look
    BURNER_PERSPECTIVE_ANGLE: Math.PI / 4, // positive is counterclockwise, a value of 0 produces a non-skewed rectangle

    // constants used for creating projections that have a 3D-ish look
    Z_TO_X_OFFSET_MULTIPLIER: Z_TO_X_OFFSET_MULTIPLIER,
    Z_TO_Y_OFFSET_MULTIPLIER: Z_TO_Y_OFFSET_MULTIPLIER,

    // use the default layout bounds
    SCREEN_LAYOUT_BOUNDS: ScreenView.DEFAULT_LAYOUT_BOUNDS
  };

  energyFormsAndChanges.register( 'EFACConstants', EFACConstants );

  return EFACConstants;
} );<commit_msg>Round control panel button corners, see https://github.com/phetsims/phet-io-wrappers/issues/143<commit_after>// Copyright 2014-2018, University of Colorado Boulder

/**
 * shared constants for the Energy Forms and Changes simulation
 *
 * @author John Blanco
 */

define( function( require ) {
  'use strict';

  var energyFormsAndChanges = require( 'ENERGY_FORMS_AND_CHANGES/energyFormsAndChanges' );

  // modules
  var Color = require( 'SCENERY/util/Color' );
  var LinearFunction = require( 'DOT/LinearFunction' );
  var ScreenView = require( 'JOIST/ScreenView' );
  var Util = require( 'DOT/Util' );
  var Vector2 = require( 'DOT/Vector2' );

  // constants used for creating projections that have a 3D-ish look.
  var Z_TO_X_OFFSET_MULTIPLIER = -0.25;
  var Z_TO_Y_OFFSET_MULTIPLIER = -0.25;

  // physical temperature constants
  var ROOM_TEMPERATURE = 296; // in degrees Kelvin
  var WATER_FREEZING_POINT_TEMPERATURE = 273.15; // in degrees Kelvin

  // constants that define physical parameters of various rectangular objects.
  var BRICK_DENSITY = 3300; // in kg/m^3, source = design document plus some tweaking to keep chunk numbers reasonable
  var BRICK_SPECIFIC_HEAT = 840; // in J/kg-K, source = design document
  var BLOCK_SURFACE_WIDTH = 0.045;

  // brick constants needed for energy chunk mapping
  var BRICK_ENERGY_AT_ROOM_TEMPERATURE = Math.pow( BLOCK_SURFACE_WIDTH, 3 ) * BRICK_DENSITY * BRICK_SPECIFIC_HEAT * ROOM_TEMPERATURE; // In joules.
  var BRICK_ENERGY_AT_FREEZING_TEMPERATURE = Math.pow( BLOCK_SURFACE_WIDTH, 3 ) * BRICK_DENSITY * BRICK_SPECIFIC_HEAT * WATER_FREEZING_POINT_TEMPERATURE; // In joules.

  // constants for temperature-energy mapping functions
  var LOW_ENERGY_FOR_MAP_FUNCTION = BRICK_ENERGY_AT_FREEZING_TEMPERATURE;
  var HIGH_ENERGY_FOR_MAP_FUNCTION = BRICK_ENERGY_AT_ROOM_TEMPERATURE;
  var NUM_ENERGY_CHUNKS_IN_BRICK_AT_FREEZING = 1.25;
  var NUM_ENERGY_CHUNKS_IN_BRICK_AT_ROOM_TEMP = 2.4; // close to rounding to 3 so that little energy needed to transfer first chunk

  // time values for normal and fast-forward motion
  var FRAMES_PER_SECOND = 60.0;
  var SIM_TIME_PER_TICK_NORMAL = 1 / FRAMES_PER_SECOND;
  var FAST_FORWARD_MULTIPLIER = 4;

  // colors
  var NOMINAL_WATER_OPACITY = 0.75;
  var FIRST_SCREEN_BACKGROUND_COLOR = new Color( 249, 244, 205 );
  var SECOND_SCREEN_BACKGROUND_COLOR = new Color( 249, 244, 205 );

  // mapping function that maps the energy to the number of energy chunks
  var MAP_ENERGY_TO_NUM_CHUNKS = new LinearFunction(
    LOW_ENERGY_FOR_MAP_FUNCTION,
    HIGH_ENERGY_FOR_MAP_FUNCTION,
    NUM_ENERGY_CHUNKS_IN_BRICK_AT_FREEZING,
    NUM_ENERGY_CHUNKS_IN_BRICK_AT_ROOM_TEMP
  );

  // mapping function that maps the number of chunks of energy to the energy value
  var MAP_NUM_CHUNKS_TO_ENERGY = new LinearFunction(
    NUM_ENERGY_CHUNKS_IN_BRICK_AT_FREEZING,
    NUM_ENERGY_CHUNKS_IN_BRICK_AT_ROOM_TEMP,
    LOW_ENERGY_FOR_MAP_FUNCTION,
    HIGH_ENERGY_FOR_MAP_FUNCTION
  );

  var EFACConstants = {

    // physical temperature constants
    ROOM_TEMPERATURE: 296, // in degrees Kelvin
    WATER_FREEZING_POINT_TEMPERATURE: WATER_FREEZING_POINT_TEMPERATURE, // in degrees Kelvin
    WATER_BOILING_POINT_TEMPERATURE: 373.15, // in degrees Kelvin
    OLIVE_OIL_BOILING_POINT_TEMPERATURE: 572.04, // in degrees Kelvin, need to confirm

    // mapping function that maps the energy to the number of energy chunks
    MAP_ENERGY_TO_NUM_CHUNKS: MAP_ENERGY_TO_NUM_CHUNKS,

    // mapping function that maps the number of chunks of energy to the energy value
    MAP_NUM_CHUNKS_TO_ENERGY: MAP_NUM_CHUNKS_TO_ENERGY,

    // time values for normal and fast-forward motion
    FRAMES_PER_SECOND: FRAMES_PER_SECOND,
    SIM_TIME_PER_TICK_NORMAL: 1 / FRAMES_PER_SECOND,
    FAST_FORWARD_MULTIPLIER: FAST_FORWARD_MULTIPLIER,
    SIM_TIME_PER_TICK_FAST_FORWARD: SIM_TIME_PER_TICK_NORMAL * FAST_FORWARD_MULTIPLIER,
    MAX_HEAT_EXCHANGE_TIME_STEP: SIM_TIME_PER_TICK_NORMAL,

    MAP_Z_TO_XY_OFFSET: function( zValue ) {
      return new Vector2( zValue * Z_TO_X_OFFSET_MULTIPLIER, zValue * Z_TO_Y_OFFSET_MULTIPLIER );
    },

    // for comparing temperatures
    SIGNIFICANT_TEMPERATURE_DIFFERENCE: 1E-3, // in degrees Kelvin

    ENERGY_TO_NUM_CHUNKS_MAPPER: function( energy ) {
      return Math.max( Util.roundSymmetric( MAP_ENERGY_TO_NUM_CHUNKS( energy ) ), 0 );
    },

    ENERGY_PER_CHUNK: MAP_NUM_CHUNKS_TO_ENERGY( 2 ) - MAP_NUM_CHUNKS_TO_ENERGY( 1 ),

    // threshold for deciding when two temperatures can be considered equal
    TEMPERATURES_EQUAL_THRESHOLD: 1E-6, // in degrees Kelvin

    // Constant used by all of the "energy systems" in order to keep the amount of energy generated, converted, and
    // consumed consistent.
    MAX_ENERGY_PRODUCTION_RATE: 10000, // in joules/sec

    // colors
    NOMINAL_WATER_OPACITY: 0.7,
    WATER_COLOR_OPAQUE: new Color( 175, 238, 238 ),
    WATER_COLOR_IN_BEAKER: new Color( 175, 238, 238, NOMINAL_WATER_OPACITY ),
    OLIVE_OIL_COLOR_IN_BEAKER: new Color( 255, 210, 0 ),
    FIRST_SCREEN_BACKGROUND_COLOR: FIRST_SCREEN_BACKGROUND_COLOR,
    SECOND_SCREEN_BACKGROUND_COLOR: SECOND_SCREEN_BACKGROUND_COLOR,
    CONTROL_PANEL_BACKGROUND_COLOR: new Color( 229, 236, 255 ), // Pale gray purple. AP, AR, and CK like this.

    // appearance of controls
    CONTROL_PANEL_OUTLINE_LINE_WIDTH: 1.5,
    CONTROL_PANEL_OUTLINE_STROKE: new Color( 120, 120, 120 ),
    CLOCK_CONTROL_BACKGROUND_COLOR: new Color( 120, 120, 120 ),
    ENERGY_SYMBOLS_PANEL_CORNER_RADIUS: 6,
    CONTROL_PANEL_CORNER_RADIUS: 10,
    RESET_ALL_BUTTON_RADIUS: 20,

    // model-view transform scale factor for Energy Systems tab
    ENERGY_SYSTEMS_MVT_SCALE_FACTOR: 2200,

    // constants that control the speed of the energy chunks
    ENERGY_CHUNK_VELOCITY: 0.04, // in meters/sec

    // constants that define physical parameters of various rectangular objects
    WATER_SPECIFIC_HEAT: 3000, // In J/kg-K.  The real value for water is 4186, but this was adjusted so that there
                               // aren't too many chunks and so that a chunk is needed as soon as heating starts.
    WATER_DENSITY: 1000.0, // In kg/m^3, source = design document (and common knowledge).
    OLIVE_OIL_SPECIFIC_HEAT: 1411, // In J/kg-K. real value is 1970 (need to confirm) but this is scaled to match water
    OLIVE_OIL_DENSITY: 916.0, // In kg/m^3, need to confirm with design doc
    BRICK_DENSITY: 3300, // in kg/m^3, source = design document plus some tweaking to keep chunk numbers reasonable
    BRICK_SPECIFIC_HEAT: 840, // in J/kg-K, source = design document
    BLOCK_SURFACE_WIDTH: 0.045,
    BLOCK_PERSPECTIVE_EDGE_PROPORTION: Math.sqrt( Math.pow( Z_TO_X_OFFSET_MULTIPLIER, 2 ) +
                                                  Math.pow( Z_TO_Y_OFFSET_MULTIPLIER, 2 ) ),
    BLOCK_PERSPECTIVE_ANGLE: Math.atan2( -Z_TO_Y_OFFSET_MULTIPLIER, -Z_TO_X_OFFSET_MULTIPLIER ),

    // constants for the burners.
    INITIAL_FLUID_LEVEL: 0.5,
    BURNER_EDGE_TO_HEIGHT_RATIO: 0.2, // multiplier empirically determined for best look
    BURNER_PERSPECTIVE_ANGLE: Math.PI / 4, // positive is counterclockwise, a value of 0 produces a non-skewed rectangle

    // constants used for creating projections that have a 3D-ish look
    Z_TO_X_OFFSET_MULTIPLIER: Z_TO_X_OFFSET_MULTIPLIER,
    Z_TO_Y_OFFSET_MULTIPLIER: Z_TO_Y_OFFSET_MULTIPLIER,

    // use the default layout bounds
    SCREEN_LAYOUT_BOUNDS: ScreenView.DEFAULT_LAYOUT_BOUNDS
  };

  energyFormsAndChanges.register( 'EFACConstants', EFACConstants );

  return EFACConstants;
} );<|endoftext|>


<commit_before>"use strict";

App.controller("LoginCtrl", ["$scope", "$rootScope", "$http", "$location", "$route",
        function ($scope, $rootScope, $http, $location, $route) {

            $scope.user = {};

            $scope.login = function () {
                $http.post('http://todotasks.apphb.com/Token', {
                    username: $scope.user.username,
                    password: $scope.user.password
                })
                    .success(function(user){
                        // authentication OK
                        $rootScope.user = user;
                        //$rootScope.$emit('userChanged');
                        //$location.url('/');
                        console.log(user);
                    })
                    .error(function (errors) {
                        console.log(errors)
                    });
            };
        }
    ])
    .controller("RegisterCtrl", ["$scope", "$http", "$location", "$route",
        function ($scope, $http, $location, $route) {
            //delete $http.defaults.headers.common['X-Requested-With'];

            $scope.user = {};

            $scope.register = function () {
                $http.post('http://todotasks.apphb.com/api/Account/register',
                {
                    UserName: $scope.user.username,
                    Password: $scope.user.password,
                    ConfirmPassword: $scope.user.confirmPassword,
                    Email: $scope.user.email
                })
                .success(function (user) {
                    console.log(user);
                })
                .error(function (errors) {
                    console.log(errors);
                });
            };
        }
    ]);<commit_msg>fixing register post method<commit_after>"use strict";

App.controller("LoginCtrl", ["$scope", "$rootScope", "$http", "$location", "$route", "$window",
        function ($scope, $rootScope, $http, $location, $route, $window) {

            $scope.user = {};

            $scope.login = function () {
                $http({
                    url: 'http://localhost:56841/Token',
                    method: "POST",
                    data: {
                        username: $scope.user.email,
                        password: $scope.user.password
                    },
                    withCredentials: true
                })
                .success(function(data){
                    // authentication OK
                    //$rootScope.user = user;
                    //$rootScope.$emit('userChanged');
                    //$location.url('/');
                    console.log(data);
                })
                .error(function (errors) {
                    console.log(errors)
                });
            };
        }
    ])
    .controller("RegisterCtrl", ["$scope", "$http", "$location", "$route",
        function ($scope, $http, $location, $route) {

            $scope.user = {};

            $scope.register = function () {
                $http({
                    url: 'http://localhost:56841/api/Account/register',
                    method: "POST",
                    data: {
                        UserName: $scope.user.username,
                        Password: $scope.user.password,
                        ConfirmPassword: $scope.user.confirmPassword,
                        Email: $scope.user.email
                    },
                    withCredentials: false
                })
                .success(function (user) {
                    console.log(user);
                })
                .error(function (errors) {
                    console.log(errors);
                });
            };
        }
    ]);<|endoftext|>


<commit_before>/**
 *
 */
App.ProductsController = Ember.ArrayController.extend(
{
  needs: ['user', 'application', 'product', 'products', 'products.show', 'action', 'program'],

  page: 1,
  perPage: 24,
  lastPage: false,
  keywords: false,
  loadingMore: false,
  currentCategory: null,
  currentProduct: null,
  category: '',
  categories: null,
  categoryMap: Ember.ArrayProxy.create({ content: [] }),

  actions:
  {
    loadProduct: function(id)
    {
      this.get('controllers.user').send('healthCheck');
      this.get('controllers.products').set('keywords', false);
      this.transitionToRoute('products.show', id);
    },
    loadProducts: function(cat)
    {
      this.get('controllers.user').send('healthCheck');
      this.get('controllers.products').set('page', 1);
      this.get('controllers.products').set('lastPage', false);
      this.get('controllers.products').set('keywords', false);
      this.transitionToRoute('products', cat.get('urlName'));
    },
    loadCategories: function(transition)
    {
      console.log('loadCategories')
      console.log(transition.params);
      console.log('===========================================================');

      var category = null;
      var self = this;

      var controller = self.get('controllers.products');

      if (controller.get('categoryMap').content.length > 0)
      {
        // nothing to do anymore, we got the cats meanwhile
        return;
      }

      if (transition.params)
      {
        category = transition.params.category;
      }

      // load categories
      controller.set('categories', this.store.find('category', { display: 'tree', filter: 'all', personal: App.personalizedContent, maxlevel: 1 }));
      // map out categories
      controller.get('categories').then(function(data)
      {
        controller.get('categoryMap').set('content', []);

        data.content.forEach(function(item, index, enumerable)
        {
          controller.get('categoryMap').pushObject(item);

          if (category && item.get('urlName') == category)
          {
            controller.set('currentCategory', item);
          }
          item.get('subcategories').forEach(function(_item, _index, _enum)
          {
            controller.get('categoryMap').pushObject(_item);
            if (category && _item.get('urlName') == category)
            {
              controller.set('currentCategory', _item);
            }
          }, item);
        });

        console.log('currentCategory: ' + controller.get('currentCategory'));

        if (transition)
        {
          self.get('controllers.application').set('previousTransition', null);
          console.log('retry transition');
          console.log(transition);
          transition.retry();
        }

        console.log('loadCategories end =========================================================');
        // TODO: this is too expensive
        //~ controller.get('categoryMap').forEach(
          //~ function(item, index, enumerable)
          //~ {
            //~ // fetch all programs who have content in this category
            //~ var vars =
            //~ {
              //~ catid: item.get('id'),
              //~ application:
              //~ {
                //~ master_uid: App.apiHost,
                //~ master_apikey: App.apiKey
              //~ }
            //~ };
            //~ controller.get('categoryMap').objectAt(index)['programs'] = self.store.find('program', vars);
          //~ });
      });

      return controller.get('categories');
    },
    /**
     *
     */
    getMore: function()
    {
      if (this.get('loadingMore') || this.get('lastPage'))
      {
        return;
      }

      var controller = this.get('controllers.products');
      var nextPage = controller.get('page') + 1;
      var perPage = controller.get('perPage');

      if (! controller.get('lastPage'))
      {
        Ember.$('.loading').show();

        if (controller.get('keywords'))
        {
          controller.send('search', controller.get('keywords'), nextPage, perPage);
        }
        else
        {
          controller.send('fetchPage', nextPage, perPage);
        }
      }
      return;
    },
    fetchPage: function(page, perPage)
    {
      var controller = this.get('controllers.products');
      controller.set('keywords', false);
      controller.set('loadingMore', true);

      var catId = this.get('controllers.products').get('categoryMap').findBy('urlName', this.get('controllers.products').get('category')).get('id');

      if (page == '' || ! page)
      {
        page = 1;
      }
      if (page == 1)
      {
        Ember.$('div.product-grid').scrollTop(0);
      }
      this.get('controllers.user').send('healthCheck');

      var results = this.store.find('product', { catid: catId, page: page });

      if (results)
      {
        controller.send('pageResults', page, results);
      }

      return;
    },
    search: function(keywords, page, perPage)
    {
      var controller = this.get('controllers.products');

      if (page == '' || ! page)
      {
        page = 1;
      }

      if (keywords != '')
      {
        controller.set('keywords', keywords);
      }

      this.get('controllers.user').send('healthCheck');

      controller.set('perPage', perPage);
      controller.set('lastPage', false);

      if (page == 1)
      {
        Ember.$('div.product-grid').scrollTop(0);
        this.transitionToRoute('products.search', 'all');
      }
      else
      {
        var results = this.store.findQuery('product', { keywords: keywords, page: page, per_page: perPage });
        controller.send('pageResults', page, results);
      }
      return;
    },
    pageResults: function(page, collection)
    {
      self = this;

      collection.then(function(data)
      {
        var lastPage = false;
        var controller = self.get('controllers.products');

        Ember.$('.loading').hide();
        self.set('loadingMore', false);

        if (data.content.length)
        {
          if (data.content.length < controller.get('perPage'))
          {
            lastPage = true;
          }
          controller.set('page', page);
          controller.get('model').addObjects(collection);
        }
        else
        {
          lastPage = true
        }

        if (lastPage)
        {
          controller.set('lastPage', true);
        }
      });
    }
  }
});

App.ProductsIndexController = Ember.ObjectController.extend(
{
  needs: ['user', 'application', 'products'],
});

App.ProductsShowController = Ember.ObjectController.extend(
{
  needs: ['user', 'application', 'products'],
});
<commit_msg>determine cancelled transition locally<commit_after>/**
 *
 */
App.ProductsController = Ember.ArrayController.extend(
{
  needs: ['user', 'application', 'product', 'products', 'products.show', 'action', 'program'],

  page: 1,
  perPage: 24,
  lastPage: false,
  keywords: false,
  loadingMore: false,
  currentCategory: null,
  currentProduct: null,
  category: '',
  categories: null,
  categoryMap: Ember.ArrayProxy.create({ content: [] }),

  actions:
  {
    loadProduct: function(id)
    {
      this.get('controllers.user').send('healthCheck');
      this.get('controllers.products').set('keywords', false);
      this.transitionToRoute('products.show', id);
    },
    loadProducts: function(cat)
    {
      this.get('controllers.user').send('healthCheck');
      this.get('controllers.products').set('page', 1);
      this.get('controllers.products').set('lastPage', false);
      this.get('controllers.products').set('keywords', false);
      this.transitionToRoute('products', cat.get('urlName'));
    },
    loadCategories: function()
    {
      console.log('loadCategories')

      var transition = this.get('controllers.application').get('previousTransition');

      if (transition)
      {
        console.log(transition.params);
        console.log('===========================================================');
      }
      var category = null;
      var self = this;

      var controller = self.get('controllers.products');

      if (controller.get('categoryMap').content.length > 0)
      {
        // nothing to do anymore, we got the cats meanwhile
        return;
      }

      if (transition && transition.params)
      {
        category = transition.params.category;
      }

      // load categories
      controller.set('categories', this.store.find('category', { display: 'tree', filter: 'all', personal: App.personalizedContent, maxlevel: 1 }));
      // map out categories
      controller.get('categories').then(function(data)
      {
        controller.get('categoryMap').set('content', []);

        data.content.forEach(function(item, index, enumerable)
        {
          controller.get('categoryMap').pushObject(item);

          if (category && item.get('urlName') == category)
          {
            controller.set('currentCategory', item);
          }
          item.get('subcategories').forEach(function(_item, _index, _enum)
          {
            controller.get('categoryMap').pushObject(_item);
            if (category && _item.get('urlName') == category)
            {
              controller.set('currentCategory', _item);
            }
          }, item);
        });

        console.log('currentCategory: ' + controller.get('currentCategory'));

        if (transition)
        {
          self.get('controllers.application').set('previousTransition', null);
          console.log('retry transition');
          console.log(transition);
          transition.retry();
        }

        console.log('loadCategories end =========================================================');
        // TODO: this is too expensive
        //~ controller.get('categoryMap').forEach(
          //~ function(item, index, enumerable)
          //~ {
            //~ // fetch all programs who have content in this category
            //~ var vars =
            //~ {
              //~ catid: item.get('id'),
              //~ application:
              //~ {
                //~ master_uid: App.apiHost,
                //~ master_apikey: App.apiKey
              //~ }
            //~ };
            //~ controller.get('categoryMap').objectAt(index)['programs'] = self.store.find('program', vars);
          //~ });
      });

      return controller.get('categories');
    },
    /**
     *
     */
    getMore: function()
    {
      if (this.get('loadingMore') || this.get('lastPage'))
      {
        return;
      }

      var controller = this.get('controllers.products');
      var nextPage = controller.get('page') + 1;
      var perPage = controller.get('perPage');

      if (! controller.get('lastPage'))
      {
        Ember.$('.loading').show();

        if (controller.get('keywords'))
        {
          controller.send('search', controller.get('keywords'), nextPage, perPage);
        }
        else
        {
          controller.send('fetchPage', nextPage, perPage);
        }
      }
      return;
    },
    fetchPage: function(page, perPage)
    {
      var controller = this.get('controllers.products');
      controller.set('keywords', false);
      controller.set('loadingMore', true);

      var catId = this.get('controllers.products').get('categoryMap').findBy('urlName', this.get('controllers.products').get('category')).get('id');

      if (page == '' || ! page)
      {
        page = 1;
      }
      if (page == 1)
      {
        Ember.$('div.product-grid').scrollTop(0);
      }
      this.get('controllers.user').send('healthCheck');

      var results = this.store.find('product', { catid: catId, page: page });

      if (results)
      {
        controller.send('pageResults', page, results);
      }

      return;
    },
    search: function(keywords, page, perPage)
    {
      var controller = this.get('controllers.products');

      if (page == '' || ! page)
      {
        page = 1;
      }

      if (keywords != '')
      {
        controller.set('keywords', keywords);
      }

      this.get('controllers.user').send('healthCheck');

      controller.set('perPage', perPage);
      controller.set('lastPage', false);

      if (page == 1)
      {
        Ember.$('div.product-grid').scrollTop(0);
        this.transitionToRoute('products.search', 'all');
      }
      else
      {
        var results = this.store.findQuery('product', { keywords: keywords, page: page, per_page: perPage });
        controller.send('pageResults', page, results);
      }
      return;
    },
    pageResults: function(page, collection)
    {
      self = this;

      collection.then(function(data)
      {
        var lastPage = false;
        var controller = self.get('controllers.products');

        Ember.$('.loading').hide();
        self.set('loadingMore', false);

        if (data.content.length)
        {
          if (data.content.length < controller.get('perPage'))
          {
            lastPage = true;
          }
          controller.set('page', page);
          controller.get('model').addObjects(collection);
        }
        else
        {
          lastPage = true
        }

        if (lastPage)
        {
          controller.set('lastPage', true);
        }
      });
    }
  }
});

App.ProductsIndexController = Ember.ObjectController.extend(
{
  needs: ['user', 'application', 'products'],
});

App.ProductsShowController = Ember.ObjectController.extend(
{
  needs: ['user', 'application', 'products'],
});
<|endoftext|>


<commit_before>/** @jsx React.DOM */
define([
    'underscore', 'jquery', 'react', 'kendo',
    '../util/debug',
    '../ControlCommon'
], function (_, $, React, kendo, debug, ControlCommon) {
    'use strict';

    var KendoNumber = React.createClass({

        fieldClass: 'formFieldNumeric',

        getDefaultProps: function () {
            return {
                value: undefined,
                onChange: function () {},
                id: undefined,

                placeholder: '',
                decimals: undefined,
                format: '',
                spinners: false,

                disabled: false,
                isValid: [true, ''],
                readonly: false,
                noControl: false
            };
        },

        /*jshint ignore:start */
        render: function () {
            return (this.props.noControl
                ? ({kendo.toString(this.props.value, this.props.format)})
                // KendoNumeric requires multiple onChange handlers, because kendo change event doesn't happen
                // until blur. We need an event on each keyup on the input, as well as spin events on the widget.
                : (<input id={this.props.id} type="text" onChange={this.onInputChange} />));
        },
        /*jshint ignore:end */

        componentDidMount: function (rootNode) {
            var $el = $(rootNode);
            debug.verify($el);

            if (this.props.noControl) {
                // Everything was done in JSX.
                return;
            }

            $el.kendoNumericTextBox({
                format: this.props.format,
                min: this.props.min,
                max: this.props.max,
                spinners: this.props.spinners,
                // No change event - we get change events from the underlying react <input>,
                // because react gives us an onChange for each keystroke which is needed for flux
                spin: this.onSpinChange
            });
        },

        onSpinChange: function (event) {
            var val = event.sender.value();
            this.props.onChange(val);
        },

        onInputChange: function (event) {
            if (this.props.readonly) {
                return;
            }
            var val = event.target.value;
            this.props.onChange(val);
        }
    });

    return KendoNumber;

});
<commit_msg>TMF-4976: KendoNumber now receives the step prop correctly<commit_after>/** @jsx React.DOM */
define([
    'underscore', 'jquery', 'react', 'kendo',
    '../util/debug',
    '../ControlCommon'
], function (_, $, React, kendo, debug, ControlCommon) {
    'use strict';

    var KendoNumber = React.createClass({

        fieldClass: 'formFieldNumeric',

        getDefaultProps: function () {
            return {
                value: undefined,
                onChange: function () {},
                id: undefined,

                placeholder: '',
                decimals: undefined,
                format: '',
                spinners: false,
                step: 1,

                disabled: false,
                isValid: [true, ''],
                readonly: false,
                noControl: false
            };
        },

        /*jshint ignore:start */
        render: function () {
            return (this.props.noControl
                ? ({kendo.toString(this.props.value, this.props.format)})
                // KendoNumeric requires multiple onChange handlers, because kendo change event doesn't happen
                // until blur. We need an event on each keyup on the input, as well as spin events on the widget.
                : (<input id={this.props.id} type="text" onChange={this.onInputChange} />));
        },
        /*jshint ignore:end */

        componentDidMount: function (rootNode) {
            var $el = $(rootNode);
            debug.verify($el);

            if (this.props.noControl) {
                // Everything was done in JSX.
                return;
            }

            $el.kendoNumericTextBox({
                format: this.props.format,
                min: this.props.min,
                max: this.props.max,
                step: this.props.step,
                spinners: this.props.spinners,
                // No change event - we get change events from the underlying react <input>,
                // because react gives us an onChange for each keystroke which is needed for flux
                spin: this.onSpinChange
            });
        },

        onSpinChange: function (event) {
            var val = event.sender.value();
            this.props.onChange(val);
        },

        onInputChange: function (event) {
            if (this.props.readonly) {
                return;
            }
            var val = event.target.value;
            this.props.onChange(val);
        }
    });

    return KendoNumber;

});
<|endoftext|>


<commit_before>define(["js/core/Base"],
    function (Base) {

        /***
         * @param {arguments} eventTypes
         * */
        Function.prototype.on = function () {
            var events = Array.prototype.slice.call(arguments, 0);
            this._events = [];
            for (var i = 0; i < events.length; i++) {
                var event = events[i];
                this._events.push(event);
            }
            return this;
        };

        /***
         * @param {arguments} changeEvents results in change:eventName
         * */
        Function.prototype.onChange = function () {
            var events = Array.prototype.slice.call(arguments, 0);
            this._events = [];
            for (var i = 0; i < events.length; i++) {
                var event = events[i];
                event = "change:" + event;
                this._events.push(event);
            }
            return this;
        };

        var undefinedValue;

        var EventDispatcher = Base.inherit("js.core.EventDispatcher",
            /** @lends EventDispatcher# */
            {

                /**
                 * Description of constructor.
                 * @class Description of class.
                 * @constructs
                 */
                ctor: function () {
                    this.callBase();
                    this._eventHandlers = {};
                },
                /**
                 * Binds a callback and a scope to a given eventType
                 * @param {String} eventType The name of the event
                 * @param {Function} callback The callback function
                 * @param {Object} [scope]  This sets the scope for the callback function
                 */
                bind: function (eventType, callback, scope) {
                    scope = scope || this;
                    // get the list for the event
                    var list = this._eventHandlers[eventType] || (this._eventHandlers[eventType] = []);
                    // and push the callback function
                    list.push(new EventDispatcher.EventHandler(callback, scope));

                    return this;
                },
                /**
                 * Triggers an event
                 * @param {String} eventType
                 * @param {js.core.EventDispatcher.Event|Object} event If you use an Object the object is wrapped in an js.core.EventDispatcher.Event
                 * @param caller
                 */
                trigger: function (eventType, event, caller) {

                    if (this._eventHandlers[eventType]) {
                        if (!(event instanceof EventDispatcher.Event)) {
                            event = new EventDispatcher.Event(event);
                        }

                        if (!caller) {
                            caller = arguments.callee.caller;
                        }

                        event.type = eventType;

                        var list = this._eventHandlers[eventType];
                        for (var i = 0; i < list.length; i++) {
                            if (list[i]) {
                                var result = list[i].trigger(event, caller);

                                if (result !== undefinedValue) {
                                    ret = result;
                                    if (result === false) {
                                        event.preventDefault();
                                        event.stopPropagation();
                                    }
                                }

                                if (event.isImmediatePropagationStopped) {
                                    break;
                                }
                            }
                        }
                    }

                    return event;
                },
                /***
                 * Unbinds callbacks for events
                 * @param {String} eventType
                 * @param {Function} callback
                 */
                unbind: function (eventType, callback) {
                    if (!eventType) {
                        // remove all events
                        this._eventHandlers = {};
                    } else if (!callback) {
                        // remove all callbacks for these event
                        this._eventHandlers[eventType] = [];
                    } else if (this._eventHandlers[eventType]) {
                        var list = this._eventHandlers[eventType];
                        for (var i = list.length - 1; i >= 0; i--) {
                            if (list[i].$callback == callback) {
                                list.splice(i, 1);  // delete callback
                            }
                        }
                    }
                }
            });

        EventDispatcher.Event = Base.inherit(
            /** @lends EventDispatcher.Event# */
            {
                /**
                 * Description of constructor.
                 * @class Description of class.
                 * @constructs
                 */
                ctor: function (attributes) {
                    this.$ = attributes;

                    this.isDefaultPrevented = false;
                    this.isPropagationStopped = false;
                    this.isImmediatePropagationStopped = false;

                },
                preventDefault: function () {
                    this.isDefaultPrevented = true;

                    var e = this.orginalEvent;

                    if (e) {
                        if (e.preventDefault) {
                            e.preventDefault();
                        } else {
                            e.returnValue = false;  // IE
                        }
                    }
                },
                stopPropagation: function () {
                    this.isPropagationStopped = true;

                    var e = this.originalEvent;
                    if (e) {
                        if (e.stopPropagation) {
                            e.stopPropagation();
                        }
                        e.cancelBubble = true;
                    }
                },
                stopImmediatePropagation: function () {
                    this.isImmediatePropagationStopped = true;
                    this.stopPropagation();
                }
            });

        EventDispatcher.EventHandler = Base.inherit({
            ctor: function (callback, scope) {
                this.scope = scope;
                this.$callback = callback;
            },
            trigger: function (event, caller) {
                this.$callback.call(this.scope, event, caller);
            }
        });

        return EventDispatcher;
    }
);<commit_msg>Function binding properties now chainable<commit_after>define(["js/core/Base"],
    function (Base) {

        /***
         * @param {arguments} eventTypes
         * */
        Function.prototype.on = function () {

            var events = Array.prototype.slice.call(arguments, 0);
            this._events = this._events || [];
            for (var i = 0; i < events.length; i++) {
                var event = events[i];
                this._events.push(event);
            }

            return this;
        };

        /***
         * @param {arguments} changeEvents results in change:eventName
         * */
        Function.prototype.onChange = function () {
            var events = Array.prototype.slice.call(arguments, 0);
            this._events = this._events || [];
            for (var i = 0; i < events.length; i++) {
                var event = events[i];
                event = "change:" + event;
                this._events.push(event);
            }
            return this;
        };

        var undefinedValue;

        var EventDispatcher = Base.inherit("js.core.EventDispatcher",
            /** @lends EventDispatcher# */
            {

                /**
                 * Description of constructor.
                 * @class Description of class.
                 * @constructs
                 */
                ctor: function () {
                    this.callBase();
                    this._eventHandlers = {};
                },
                /**
                 * Binds a callback and a scope to a given eventType
                 * @param {String} eventType The name of the event
                 * @param {Function} callback The callback function
                 * @param {Object} [scope]  This sets the scope for the callback function
                 */
                bind: function (eventType, callback, scope) {
                    scope = scope || this;
                    // get the list for the event
                    var list = this._eventHandlers[eventType] || (this._eventHandlers[eventType] = []);
                    // and push the callback function
                    list.push(new EventDispatcher.EventHandler(callback, scope));

                    return this;
                },
                /**
                 * Triggers an event
                 * @param {String} eventType
                 * @param {js.core.EventDispatcher.Event|Object} event If you use an Object the object is wrapped in an js.core.EventDispatcher.Event
                 * @param caller
                 */
                trigger: function (eventType, event, caller) {

                    if (this._eventHandlers[eventType]) {
                        if (!(event instanceof EventDispatcher.Event)) {
                            event = new EventDispatcher.Event(event);
                        }

                        if (!caller) {
                            caller = arguments.callee.caller;
                        }

                        event.type = eventType;

                        var list = this._eventHandlers[eventType];
                        for (var i = 0; i < list.length; i++) {
                            if (list[i]) {
                                var result = list[i].trigger(event, caller);

                                if (result !== undefinedValue) {
                                    ret = result;
                                    if (result === false) {
                                        event.preventDefault();
                                        event.stopPropagation();
                                    }
                                }

                                if (event.isImmediatePropagationStopped) {
                                    break;
                                }
                            }
                        }
                    }

                    return event;
                },
                /***
                 * Unbinds callbacks for events
                 * @param {String} eventType
                 * @param {Function} callback
                 */
                unbind: function (eventType, callback) {
                    if (!eventType) {
                        // remove all events
                        this._eventHandlers = {};
                    } else if (!callback) {
                        // remove all callbacks for these event
                        this._eventHandlers[eventType] = [];
                    } else if (this._eventHandlers[eventType]) {
                        var list = this._eventHandlers[eventType];
                        for (var i = list.length - 1; i >= 0; i--) {
                            if (list[i].$callback == callback) {
                                list.splice(i, 1);  // delete callback
                            }
                        }
                    }
                }
            });

        EventDispatcher.Event = Base.inherit(
            /** @lends EventDispatcher.Event# */
            {
                /**
                 * Description of constructor.
                 * @class Description of class.
                 * @constructs
                 */
                ctor: function (attributes) {
                    this.$ = attributes;

                    this.isDefaultPrevented = false;
                    this.isPropagationStopped = false;
                    this.isImmediatePropagationStopped = false;

                },
                preventDefault: function () {
                    this.isDefaultPrevented = true;

                    var e = this.orginalEvent;

                    if (e) {
                        if (e.preventDefault) {
                            e.preventDefault();
                        } else {
                            e.returnValue = false;  // IE
                        }
                    }
                },
                stopPropagation: function () {
                    this.isPropagationStopped = true;

                    var e = this.originalEvent;
                    if (e) {
                        if (e.stopPropagation) {
                            e.stopPropagation();
                        }
                        e.cancelBubble = true;
                    }
                },
                stopImmediatePropagation: function () {
                    this.isImmediatePropagationStopped = true;
                    this.stopPropagation();
                }
            });

        EventDispatcher.EventHandler = Base.inherit({
            ctor: function (callback, scope) {
                this.scope = scope;
                this.$callback = callback;
            },
            trigger: function (event, caller) {
                this.$callback.call(this.scope, event, caller);
            }
        });

        return EventDispatcher;
    }
);<|endoftext|>


<commit_before>'use strict';

angular.module('arachne.directives')

/**
 * @author: Jan G. Wieners
 */
.directive('entitymap', ['$location', '$filter',
function($location, $filter) {
    return {
        restrict: 'A',
        scope: {
            places:"="
        },
        link: function(scope, element, attrs) {

            var map = L.map('entitymap').setView([40, -10], 3);

            // Disable dragging functionality if outside of container bounds
            L.Draggable.prototype._freeze=false;
            L.Draggable.prototype._updatePosition= function () {
                if(this._freeze) {
                    return;
                }

                this.fire('predrag');
                L.DomUtil.setPosition(this._element, this._newPos);
                this.fire('drag');
            };

            map.on('mouseout', function() {
                map.dragging._draggable._freeze=true;
            });
            map.on('mouseover', function() {
                map.dragging._draggable._freeze=false;
            });
            // / Disable dragging functionality if outside of container bounds

            var layer = L.tileLayer('http://{s}.tile.thunderforest.com/landscape/{z}/{x}/{y}.png', {
                maxZoom: 18,
                minZoom: 2
            });

            map.addLayer(layer);
            map.trackResize = true;
            L.Icon.Default.imagePath = 'img';

            var markers = [];

            var loadMarkers = function() {

                var group = new L.featureGroup();
                if(scope.places){
                    for(var place in scope.places){
                        var curplace = scope.places[place];

                        var name = curplace.name;
                        var relation = curplace.relation;
                        var location = curplace.location;

                        var title = "";
                        if (relation) title += "" + relation + "
";
                        title += "" + name + "";
                        var text = name;
                        var newMarker = L.marker(new L.LatLng(location.lat, location.lon), { title: text });
                        newMarker.bindPopup(title);
                        markers.push(newMarker);
                        map.addLayer(newMarker);
                    }

                }
                var mark = L.featureGroup(markers);

                // workaround, see https://github.com/Leaflet/Leaflet/issues/2021
                map.whenReady(function () {
                    window.setTimeout(function () {
                        if (markers.length > 1) map.fitBounds(mark.getBounds(), { padding: [20, 20] });
                        else {
                            map.fitBounds(mark.getBounds(), { maxZoom: 5 });
                            map.setMaxBounds(mark.getBounds());
                        }
                    }.bind(this), 200);
                }, this);

                map._onResize();
            };

            loadMarkers();

        }
    };
}]);
<commit_msg>Ensure that marker stays in focus until map has been dragged (implements #2892).<commit_after>'use strict';

angular.module('arachne.directives')

/**
 * @author: Jan G. Wieners
 */
    .directive('entitymap', ['$location', '$filter',
        function ($location, $filter) {
            return {
                restrict: 'A',
                scope: {
                    places: "="
                },
                link: function (scope, element, attrs) {

                    var map = L.map('entitymap').setView([40, -10], 3);

                    // Disable dragging functionality if outside of container bounds
                    L.Draggable.prototype._freeze = false;
                    L.Draggable.prototype._updatePosition = function () {
                        if (this._freeze) {
                            return;
                        }

                        this.fire('predrag');
                        L.DomUtil.setPosition(this._element, this._newPos);
                        this.fire('drag');
                    };

                    map.on('mouseout', function () {
                        map.dragging._draggable._freeze = true;
                    });
                    map.on('mouseover', function () {
                        map.dragging._draggable._freeze = false;
                    });
                    // / Disable dragging functionality if outside of container bounds

                    var layer = L.tileLayer('http://{s}.tile.thunderforest.com/landscape/{z}/{x}/{y}.png', {
                        maxZoom: 18,
                        minZoom: 2
                    });

                    map.addLayer(layer);
                    map.trackResize = true;
                    L.Icon.Default.imagePath = 'img';

                    var markers = [];

                    var loadMarkers = function () {

                        var group = new L.featureGroup();
                        if (scope.places) {
                            for (var place in scope.places) {
                                var curplace = scope.places[place];

                                var name = curplace.name;
                                var relation = curplace.relation;
                                var location = curplace.location;

                                var title = "";
                                if (relation) title += "" + relation + "
";
                                title += "" + name + "";
                                var text = name;
                                var newMarker = L.marker(new L.LatLng(location.lat, location.lon), {title: text});
                                newMarker.bindPopup(title);
                                markers.push(newMarker);
                                map.addLayer(newMarker);
                            }

                        }
                        var mark = L.featureGroup(markers);

                        // workaround, see https://github.com/Leaflet/Leaflet/issues/2021
                        map.whenReady(function () {
                            window.setTimeout(function () {
                                if (markers.length > 1) map.fitBounds(mark.getBounds(), {padding: [20, 20]});
                                else {
                                    map.fitBounds(mark.getBounds(), {maxZoom: 5});

                                    // Ensure that marker stays in focus until map has been dragged
                                    map.setMaxBounds(mark.getBounds());

                                    map.on('drag', function() {
                                        map.setMaxBounds(null);
                                    });
                                }
                            }.bind(this), 200);
                        }, this);

                        map._onResize();
                    };

                    loadMarkers();

                }
            };
        }]);
<|endoftext|>