
isTouch = 'ontouchstart' in window;

if( isTouch )
{
	downEvent = "touchstart";
	moveEvent = "touchmove";
	upEvent = "touchend";
}
else
{
	downEvent = "mousedown";
	moveEvent = "mousemove";
	upEvent = "mouseup";
}

function debug_log( str )
{
	try
	{
		console.log( str );
	}
	catch( e )
	{
	}
	
}

function googleAnalytics( type, value )
{
	_gaq.push(['_trackEvent', 'Game', type, value ]);
}

$(document).ready(function()
{
	$('#fontsize a').bind( 'mouseup', setGameFontSize );
	
	$(document).mousedown( function(e){ if( e.shiftKey ) completedGame() } );
	
});

function setGameFontSize()
{
	var size = $(this).attr('id');
	
	var $game = $('#gamearea');
	
	$game.removeClass('size_small size_medium size_large');
	
	$game.addClass('size_'+size);
}


function editorEvent( e )
{
	if( 'editorMouseDown' in window )
	{
		if( e.shiftKey )
		{
			e.stopImmediatePropagation();
			return false;
		}
		else
			return true;
	}
	else
		return false;
		
}

function gameMouseDown( e )
{
	if( editorEvent( e ) ) return;
}

function gameMouseMove( e )
{
	if( editorEvent( e ) ) return;
}

function gameMouseUp( e )
{
	if( editorEvent( e ) ) return;
}

function loadScene( path )
{
	fadeOutAndThen( function()
	{
		var $sceneDiv = $('#game #scene');
		
		if( $sceneDiv.length == 0 )
		{
			var $gameArea = $('#gamearea');
			
			$gameArea.empty();
			
			var $gameDiv = $('<div id="game"/>');
			$gameArea.append( $gameDiv );
			
			$sceneDiv = $('<div id="scene"/>');
			$gameDiv.append( $sceneDiv );
			
			$sceneDiv.bind('load', startScene );
			
			updateButtons();
		}
		
		$sceneDiv.load( path, {time:new Date().getTime()}, function(){ $(this).trigger('load') } );
		
	});
}

scriptObject = undefined;

function startScene()
{
	var $sceneDiv = $('#game #scene');
	
	//if( !scriptObject )
	{
		scriptObject = compile( $sceneDiv.find('pre').html() );
		scriptObject.currentObject = scriptObject;
	}
	
	scriptContinue( scriptObject );
}

function scriptContinue( scriptObject )
{
	var anotherStep;
	var enterChildren;
	
	var isEditor = 'clickPlay' in window;
	
	do
	{
		anotherStep = true;
		enterChildren = false;
		
		var currentObject = scriptObject.currentObject;
		
		//console.log( currentObject );
		
		var objectValue = currentObject.value.toLowerCase();
		
		if( objectValue == 'script' )
		{
			enterChildren = true;
		}
		else if( objectValue == 'scene name' )
		{
			createTitle( getChildrenAsText( currentObject ) );
		}
		else if( objectValue == 'dialog' )
		{
			anotherStep = false;
				
			if( currentObject.selectedChoice )
			{
				if( currentObject.selectedChoice.value == 'incorrect' )
				{
					var $dialog = currentDialog();
					
					var message = $dialog.data('retryMessage');
					
					if( !message )
						message = 'Prøv igjen';
					
					$dialog.find('p.message').html( nl2br( message ) );
					
					currentObject.retry = true;
				}
				else
				{
					var $dialog = currentDialog();
					var dialogId = parseInt( $dialog.data('id') );
						
					if( currentObject.selectedChoice.type == 'correct_or_incorrect' && !currentObject.retry )
					{
						if( dialogId > 0 )
						{
							if( useFacebook )
							{
								$.getJSON( 'save_button.php', { dialog: dialogId }, savedButton );
							}
							else
							{
								collectedButtons[ dialogId ] = true;
								
								updateButtons();
							}
						}
					}
					else if( currentObject.selectedChoice.type == 'personality' )
					{
						if( dialogId > 0 )
						{
							if( useFacebook )
							{
								$.getJSON( 'save_personality.php', { dialog: dialogId, personality: currentObject.selectedChoice.value }, savedPersonality );
							}
						}
						
						if( personalityChoices )
							personalityChoices[ currentObject.selectedChoice.value ]++;
					}
				
					anotherStep = true;
					
					clearUI();
				}
			}
			else
			{
				clearUI();
				
				var title,message,retryMessage,question,fromPosition,fromSide,centerPosition,item,width,dialogId;
				var choices = [];
				var objects = [];
				
				width = 250;
				
				for( var n=0; n<currentObject.children.length; n++ )
				{
					var child = currentObject.children[ n ];
					var value = child.value.toLowerCase();
					
					if( value == 'title' )
						title = getChildrenAsText( child );
					else if( value == 'from' )
					{
						for( var m=0; m<child.children.length; m++ )
						{
							var str = child.children[ m ].value.toLowerCase();
							
							if( str == 'left' || str == 'right' )
								fromSide = str;
							else
							{
								var parts = str.split(',');
						
								if( parts.length == 2 )
									fromPosition = { left: parseInt( parts[0] ), top: parseInt( parts[1] ) };
							}
						}
						
						if( fromPosition && !fromSide )
							fromSide = ( fromPosition.left > $('#game').width() / 2 ) ? 'left':'right';
						
					}
					else if( value == 'center' )
					{
						var parts = getChildrenAsText( child ).split(',');
						
						if( parts.length == 2 )
							centerPosition = 
							{
								left: parseInt( parts[0] ),
								top: parseInt( parts[1] )
							};
					}
					else if( value == 'message' )
						message = getChildrenAsText( child );
					else if( value == 'help' )
						createBanner( getChildrenAsText( child ) );
					else if( value == 'question' )
						question = getChildrenAsText( child );
					else if( value == 'retry message' )
						retryMessage = getChildrenAsText( child );
					else if( value == 'correct' )
						choices.push( {
							type: 'correct_or_incorrect',
							value:'correct', 
							text: getChildrenAsText( child )
						} );
					else if( value == 'incorrect' )
						choices.push( {
							type: 'correct_or_incorrect',
							value:'incorrect', 
							text: getChildrenAsText( child )
						} );
					else if( value.indexOf('personality') == 0 )
					{
						choices.push( {
							type: 'personality',
							value: value.split(' ').pop().toLowerCase(), 
							text: getChildrenAsText( child )
						} );
					}
					else if( value.indexOf('choice') == 0 )
					{
						choices.push( {
							type: 'choice',
							value: value.split(' ').pop().toLowerCase(), 
							text: getChildrenAsText( child )
						} );
					}
					else if( value.indexOf('object') == 0 )
					{
						var objectName = getChildrenAsText( child );
						
						var $img = getObjectByName( objectName );
						
						if( $img )
						{
							var parts = value.split(' ');
							
							var choiceValue;
							
							if( parts.length > 1 )
								choiceValue = parts.pop().toLowerCase();
							
							glowInit( $img, 'choice', choiceValue );
						}
						else
						{
							console.error('Unknown object: '+objectName);
						}
					}
					else if( value.indexOf('zoom') == 0 )
					{
						var $img, path;
						
						for( var m=0; m<child.children.length; m++ )
						{
							var grandChild = child.children[ m ];
							
							var grandChildName = grandChild.value.toLowerCase();
							var grandChildValue = getChildrenAsText( grandChild );
							
							if( grandChildName == 'object' )
							{
								$img = getObjectByName( grandChildValue );
							}
							else if( grandChildName == 'image' )
							{
								path = getImagePathByName( grandChildValue );
							}
						}
						
						if( $img && path )
						{
							glowInit( $img, 'zoom', path );
						}
					}
					else if( value.indexOf('item') == 0 )
					{
						var $img, path, action;
						
						for( var m=0; m<child.children.length; m++ )
						{
							var grandChild = child.children[ m ];
							
							var grandChildName = grandChild.value.toLowerCase();
							var grandChildValue = getChildrenAsText( grandChild );
							
							if( grandChildName == 'object' )
							{
								$img = getObjectByName( grandChildValue );
							}
							else if( grandChildName == 'image' )
							{
								path = getImagePathByName( grandChildValue );
							}
							else if( grandChildName == 'action' )
							{
								action = grandChildValue;
							}
						}
						
						if( $img && path )
						{
							item = {};
							
							item.glow = glowInit( $img, 'item' );
							
							item.$img = $img;
							
							if( action )
								item.action = action;
							
							item.$div = $('<div class="inventory"><div class="image"/><p>Klikk og dra</p></div>');
							$('#game').append( item.$div );
							
							item.$div.css({
								marginLeft: -120,
								marginTop: 120
							});
							
							item.$div.animate({
								marginLeft: 0,
								marginTop: 0
							},'fast');
							
							item.$item = item.$div.find('.image');
							
							item.$item.css( 'backgroundImage', 'url('+path+')' );
							item.$item.bind( downEvent, createDelegate( item, itemDragStart ) );
						}
					}
					else if( value == 'continue' )
					{
						var text = getChildrenAsText( child );
						
						if( !text )
							text = 'Gå videre!';
						
						var $next = $('<div class="next"/>').html( text );
						
						$next.click( nextClicked );
						
						$('#game').append( $next );
					}
					else if( value == 'width' )
					{
						var specificWidth = parseInt( getChildrenAsText( child ) );
						
						if( specificWidth > 0 )
						{
							width = specificWidth;
						}
					}
					else if( value == 'id' )
					{
						var specificDialogId = parseInt( getChildrenAsText( child ) );
						
						if( specificDialogId > 0 )
						{
							dialogId = specificDialogId;
						}
					}
					else
					{
						console.error('Unknown dialog property: '+value);
					}
				}
				
				if( title || message || question || choices.length )
				{
					var $dialog = $('<div class="dialog"/>');
					
					$dialog.css( 'left', '-2000px' );
					$dialog.css( 'width', width+'px' );
					
					if( dialogId )
						$dialog.data({
							id: dialogId
						});
						
					if( title )
						$dialog.append( $('<h1/>').html( nl2br( title ) ) );
					
					if( fromPosition )
						$dialog.data({
							fromLeft: fromPosition.left,
							fromTop: fromPosition.top
						});
						
					if( fromSide )
						$dialog.data({
							fromSide: fromSide
						});
						
					if( centerPosition )
						$dialog.data({
							centerLeft: centerPosition.left,
							centerTop: centerPosition.top
						});
					
					if( message )
						$dialog.append( $('<p class="message"/>').html( nl2br( message ) ) );
					
					if( retryMessage )
						$dialog.data( 'retryMessage', retryMessage );
					
					if( question )
						$dialog.append( $('<p class="question"/>').html( nl2br( question ) ) );
					
					if( choices.length )
					{
						shuffle( choices );
					
						var $ul = $('<ul/>');
						$dialog.append( $ul );
						
						for( var n=0; n < choices.length; n++ )
						{
							var choice = choices[n];
							
							var $li = $('<li>'+choice.text+'</li>');
							$ul.append( $li );
							
							$li.click( clickedDialogChoice );
							$li.data({
								type: choice.type,
								value: choice.value
							});
						}
					}
					
					var $game = $('#game');
					
					$game.append( $dialog );
					
					setTimeout( createDelegate( $dialog, createdDialog ), 500 );
					
					if( item )
					{
						$dialog.css('display','none');
						//$dialog.addClass('hand');
					}
				}
			}
		}
		else if( objectValue.indexOf('if choice was ') == 0 )
		{
			var conditionValue = objectValue.split(' ').pop();
			
			var previousDialog;
			
			var checkObject = currentObject;
			
			while( checkObject )
			{
				if( checkObject.value.toLowerCase() == 'dialog' )
				{
					previousDialog = checkObject;
					break;
				}
				else
					checkObject = checkObject.previous;
			}
			
			if( previousDialog )
			{
				enterChildren = previousDialog.selectedChoice.value == conditionValue;
			}
		}
		else if( objectValue == 'show' || objectValue == 'hide' )
		{
			var visibility = objectValue == 'show';
			
			for( var n=0; n<currentObject.children.length; n++ )
			{
				var child = currentObject.children[ n ];
				
				var $img = getObjectByName( child.value );
				
				if( $img )
				{
					$img.css( 'display', visibility ? '' : 'none' );
				}
			}
		}
		else if( objectValue == 'change image' )
		{
			var $img;
			var path;
			
			for( var n=0; n<currentObject.children.length; n++ )
			{
				var child = currentObject.children[ n ];
				var name = child.value.toLowerCase();
				
				var value = child.children[0].value;
				
				if( name == 'object' )
				{
					$img = getObjectByName( value );
				}
				else if( name == 'image' )
				{
					path = getImagePathByName( value );
				}
			}
			
			if( $img && path )
			{
				var changeImage = {
					
					$img: $img,
					path: path
					
				};
				
				var preloader = new Image();
				preloader.onload = createDelegate( changeImage, function(){ this.$img.attr( 'src', this.path ) } );
				preloader.src = path;
			}
		}
		else if( objectValue == 'go to scene' )
		{
			anotherStep = false;
			
			clearUI();
			clearTitle();
			
			if( isEditor )
			{
				clickPlay();
			}
			else
			{
				var name = getChildrenAsText( currentObject );
			
				googleAnalytics( 'scene', name );

				loadScene( 'gamedata/' + name + '.html' );
			}
		}
		else if( objectValue == 'end of game' )
		{
			anotherStep = false;
			
			if( isEditor )
			{
				clickPlay();
			}
			else
			{
				completedGame();
			}
		}
		else
		{
			debug_log( 'Unknown script: ' + objectValue );
		}
		
		if( anotherStep )
		{
			if( enterChildren && currentObject.children )
			{
				scriptObject.currentObject = currentObject.children[ 0 ];
			}
			else
			{
				while( true )
				{
					if( currentObject.next )
						break;
					
					if( currentObject.parent )
						currentObject = currentObject.parent;
					else
						return false;
				}
				
				scriptObject.currentObject = currentObject.next;
			}
		}
	}
	while( anotherStep );
	
	return true;
}

function getPlayerFacebookId()
{
	var response = FB.getAuthResponse();
	
	if( response )
		return response.userID;
	else
		return null;
}

function savedButton( response )
{
	if( response.buttons != undefined )
	{
		var playerFacebookId = getPlayerFacebookId();
		
		var user = users[ playerFacebookId ];
		
		if( !user ) user = users[ playerFacebookId ] = { id: playerFacebookId };
		
		user.buttons = response.buttons;
	}
	
	updateButtons();
}

function getNumberOfButtons()
{
	if( useFacebook )
	{
		var user = users[ getPlayerFacebookId() ];
		
		if( user )
			return user.buttons;
		else
			return 0;
	}
	else
	{
		var buttons = 0;
		
		for( var id in collectedButtons )
			buttons++;
			
		return buttons;
	}
}

function updateButtons( user )
{
	var buttons;
	
	if( useFacebook )
	{
		if( user )
		{
			buttons = user.buttons;
		}
		else
		{
			getUser( getPlayerFacebookId(), updateButtons );
			return;
		}
	}
	else
	{
		buttons = 0;
		
		for( var id in collectedButtons )
			buttons++;
	}
	
	var $badge = $('#game .badge');
	
	if( $badge.length == 0 )
	{
		$badge = $('<div class="badge"/>');
		$('#game').append( $badge );
		$badge.fadeIn('fast');
	}
	
	$badge.text( buttons );
}

function savedPersonality( response )
{
	// well that's just great.
}

function clearItem()
{
	$('#game .inventory').not(':animated').animate({
		marginLeft: -120,
		marginTop: 120
	},
	'fast',undefined,removeTarget);
}

function removeTarget()
{
	$(this).remove();
}

function itemDragStart( e )
{
	//console.log( 'itemDragStart' );
	
	e.preventDefault();
	
	this.drag = 
	{
		fromMousePosition: getEventPosition( e ),
		fromImagePosition: this.$item.position()
	};
	
	this.dropRect = 
	{
		left: this.$img.offset().left,
		top: this.$img.offset().top,
		width: this.$img.width(),
		height: this.$img.height()
	};
	
	$(document).bind( moveEvent, createDelegate( this, itemDragMove ) );
	$(document).bind( upEvent, createDelegate( this, itemDragEnd ) );
	
	return false;
}

function itemDragMove( e )
{
	//console.log( 'itemDragMove' );
	
	e.preventDefault();
	
	var mousePosition = getEventPosition( e );
	
	this.$item.css({
		left: this.drag.fromImagePosition.left + ( mousePosition.left - this.drag.fromMousePosition.left ),
		top: this.drag.fromImagePosition.top + ( mousePosition.top - this.drag.fromMousePosition.top )
	});
	
	return false;
}

function itemDragEnd( e )
{
	//console.log( 'itemDragEnd' );
	
	e.preventDefault();
	
	$(document).unbind( moveEvent );
	$(document).unbind( upEvent );
	
	var mousePosition = getEventPosition( e );
	
	if( 
		mousePosition.left >= this.dropRect.left && 
		mousePosition.top >= this.dropRect.top && 
		mousePosition.left < this.dropRect.left + this.dropRect.width && 
		mousePosition.top < this.dropRect.top + this.dropRect.height 
	)
	{
		this.$item.unbind( downEvent );
		
		scriptObject.currentObject.selectedChoice = {
			type: 'drop'
		};
		
		this.$item.fadeOut('fast',itemDragEnded);
	}
	else
	{
		this.$item.animate({
			left: this.drag.fromImagePosition.left,
			top: this.drag.fromImagePosition.top
		},
		'fast');
	}
	
	return false;
}

function itemDragEnded()
{
	scriptContinue( scriptObject );
}

function nextClicked( e )
{
	clearUI();

	scriptObject.currentObject.selectedChoice = {
		type: 'next'
	};
	
	scriptContinue( scriptObject );
}

function clearNext()
{
	$('#game .next').remove();
}

glowMargin = 10;

function glowInit( $img, type, value )
{
	var glow = {};
	
	glow.$img = $img;
	glow.type = type;
	glow.$div = $('<div class="glow"/>');
	glow.$div.click( createDelegate( glow, glowClick ) );
	glow.interval = setInterval( createDelegate( glow, glowUpdate ), 1000 / 30 );
	glow.startShowTime = new Date().getTime() + 1000 * 2;
	
	if( value )
		glow.value = value;
	
	$('#game').append( glow.$div );
	
	return glow;
}

function glowUpdate()
{
	var glow = this;
	
	if( glow.$img.parent().length && glow.$div.parent().length )
	{
		var glowSrc = glow.$img.attr('src');
		var parts = glowSrc.split('.');
		var extension = parts.pop();
		parts.push('glow');
		parts.push( extension );
		glowSrc = parts.join('.');
		
		var frames = [0,1,2,3,2,1];
		
		var now = new Date().getTime();
		
		var frame = frames[ Math.floor( ( now - glow.startShowTime ) * .005 ) % frames.length ];
		
		var show = glow.$img.width() > 0 && now >= glow.startShowTime;
		
		if( show )
		{
			if( glow.$div.css('background-image').indexOf( glowSrc ) == -1 )
				glow.$div.css('background-image', 'url('+glowSrc+')' );
		}
		else
		{
			glow.$div.css( 'background-image', '' );
		}
		
		var url = show ? 'url('+glowSrc+')' : '';
		
		glow.$div.css({
			left: glow.$img.position().left - glowMargin,
			top: glow.$img.position().top - glowMargin,
			width: glow.$img.width() + glowMargin * 2,
			height: glow.$img.height() + glowMargin * 2,
			backgroundPosition: frame * 25 + '% 0%'
		});
	}
	else
	{
		glowRemove( glow );
	}
}

function glowRemove( glow )
{
	if(!glow)
		glow = this;
		
	clearGlow( glow );
	
	clearInterval( glow.interval );
}

function clearGlow( glow )
{
	var $div;
	
	if( glow )
		$div = glow.$div;
	else
		$div = $('#game .glow');
	
	$div.not(':animated').fadeOut('fast',removeTarget);
}

function glowClick( event )
{
	var glow = this;
	
	if( glow.type == 'choice' )
	{
		glowRemove( glow );
	
		scriptObject.currentObject.selectedChoice = {
			type: 'object',
			value: glow.value
		};
		
		scriptContinue( scriptObject );
	}
	else if( glow.type == 'zoom' )
	{
		var $game = $('#game');
		
		if( $game.find('.zoom').length )
		{
			closeZoom();
		}
		else
		{
			var $dialog = $game.find('.dialog').first();
			
			if( $dialog.length )
			{
				var $zoom = $('<div class="zoom"><div class="image"></div><div class="close"></div></div>');
				
				$zoom.find('.image').css('backgroundImage','url('+glow.value+')');
				$zoom.find('.close').click( closeZoom );
				
				var position = getEventPosition( event );
				
				var margin = 100;
				
				position.left = Math.max( margin, Math.min( $game.width() - margin, position.left ) ) - 60;
				position.top = Math.max( margin, Math.min( $game.height() - margin, position.top ) ) - 60;
				
				$zoom.css({
					left: position.left,
					top: position.top
				});
				
				$game.append( $zoom );
				$zoom.hide();
				$zoom.slideDown('fast');
			}
		}
	}
	else if( glow.type == 'item' )
	{
		var $dialog = $('#game .dialog');
		$dialog.slideDown('fast');
	}
}

function closeZoom()
{
	$('#game .zoom').not(':animated').slideUp('fast',removeTarget);
}

function getObjectByName( name )
{
	name = name.toLowerCase();
	
	var $img;
	
	$('#scene img').each( function( i, img )
	{
		var id = $(img).attr('id');
		
		if( id && id.toLowerCase() == name )
			$img = $(img);
	});
	
	return $img;
}

function getImagePathByName( name )
{
	var parts = name.split('.');
	
	if( parts.length == 1 )
		parts.push('png');

	return 'gamedata/'+parts.join('.');
}

function clearUI()
{
	clearDialog();
	clearBanner();
	clearGlow();
	closeZoom();
	clearItem();
	clearNext();
}

function clearDialog()
{
	$('#game .dialog').not(':animated').slideUp('fast',removeTarget);
}

function clearBanner()
{
	$('#game .banner').not(':animated').slideUp('fast',removeTarget);
}

function createBanner( str )
{
	clearBanner();
	
	var $banner = $('<p class="banner"/>').html( nl2br( str ) );
	
	$('#game').append( $banner );
	
	$banner.hide();
	$banner.slideDown('fast');
}

function clearTitle()
{
	$('#game').find('.title').remove();
}

function createTitle( str )
{
	clearTitle();
	
	var $title = $('<h1 class="title"/>').html( nl2br( str ) );
	
	$('#game').append( $title );
}

function currentDialog()
{
	return $('#game .dialog').first();
}

function createdDialog( )
{
	var $dialog = this;
	
	var $game = $dialog.closest('#game');
	
	var width = $dialog.outerWidth();
	var height = $dialog.outerHeight();
	
	var border = 12;
		
	if( $dialog.data('fromSide') )
	{
		var side = $dialog.data('fromSide');
		
		var oppositeSide = (side == 'left') ? 'right' : 'left';
		
		var position = {
			
			left: parseInt( $dialog.data('fromLeft') ),
			top: parseInt( $dialog.data('fromTop') )
			
		};
		
		var $from = $('<div class="from"/>');
		
		$dialog.prepend( $from );
		
		var distanceY = 28;
		
		var distanceX = distanceY * .8;
		
		var radius = 12;
		
		var offsetY = 15;
		
		$from.css({
			position: 'absolute',
			left: ( side == 'right' ) ? -(distanceX + radius*2 + border) : width + (border-2),
			top: 0,
			width: distanceX + radius*2,
			height: height + distanceY - offsetY + radius * 2,
			backgroundPosition: oppositeSide+' bottom',
			backgroundImage: 'url(gfx/dialogfrom_down_'+side+'.png)',
			backgroundRepeat: 'no-repeat'
		});
		
		$dialog.css( 'border-'+oppositeSide+'-width', border+'px' );
		
		$dialog.css({
			
			top: position.top - height - distanceY + offsetY - radius
			
		});
		
		if( side == 'left' )
		{
			$dialog.css({
			
				left: position.left - width - distanceX - radius - (border-2)
				
			});
		}
		else
		{
			$dialog.css({
				
				left: position.left + distanceX + radius
				
			});
		}
		
	}
	else
	{
		$dialog.css( 'borderLeftWidth', border+'px' );
	
		if( $dialog.data('centerLeft') )
		{
			$dialog.css({
			
				left: $dialog.data('centerLeft') - ( width / 2 ),
				top: $dialog.data('centerTop') - ( height / 2 )
				
			});
		}
		else
		{
			$dialog.css({
			
				left: ( $game.width() - width ) / 2,
				top: ( $game.height() - height ) / 2
				
			});
		}
	}
	
	if( $dialog.is(':visible') )
	{
		$dialog.hide();
		$dialog.slideDown('fast');
	}
}

function clickedDialogChoice()
{
	var $chosenChoice = $(this);
	
	scriptObject.currentObject.selectedChoice = {
		type: $chosenChoice.data('type'),
		value: $chosenChoice.data('value')
	};
	
	scriptContinue( scriptObject );
}

function getChildrenAsText( parent )
{
	var paragraphs = [];
	
	if( parent.children )
	{
		for( var n=0; n<parent.children.length; n++ )
		{
			paragraphs.push( parent.children[ n ].value );
		}
	}
	
	return paragraphs.join('\n\n');
}

function nl2br( str )
{
	return str.replace( /\n/g, '<br/>');
}

function compile( scriptString )
{
	var scriptObject = { value:'script' };
	
	var scriptObjects = [ scriptObject ];
	
	var lineNr = 0;
	
	scriptString = scriptString.replace(/\r\n?/g,'\n');
	
	while( scriptString.length && lineNr++ < 1000 )
	{
		var eolIndex = scriptString.indexOf('\n');
		
		if( eolIndex == -1 )
			eolIndex = scriptString.length;
			
		var line = scriptString.substr( 0, eolIndex );
		
		scriptString = scriptString.substr( eolIndex+1 );
		
		var level = 1;
	
		while( line.charAt(0)=='\t' )
		{
			level++;
			line = line.substr(1);
		}
		
		line = $.trim( line );
		
		if( line.length == 0 )
			continue;
			
		if( line.indexOf('#') == 0 )
			continue;
			
		if( line.indexOf('--') == 0 )
			continue;
			
		if( line.indexOf('//') == 0 )
			continue;
		
		var lineObject = { value:line, line:lineNr };
		
		var parentObject;
		
		while( level <= scriptObjects.length - 1 )
		{
			scriptObjects.pop();
		}
		
		if( level == scriptObjects.length )
		{
		}
		else if( level == scriptObjects.length + 1 )
		{
			parentObject = scriptObjects[ scriptObjects.length-1 ];
			
			parentObject = parentObject.children[ parentObject.children.length - 1 ];
			
			scriptObjects.push( parentObject );
		}
		else
		{
			debug_log('tab error on line '+lineNr);
			continue;
		}
		
		var parentObject = scriptObjects[ level-1 ];
		
		if( 'children' in parentObject )
		{
			var previousObject = parentObject.children[ parentObject.children.length-1 ];
			
			previousObject.next = lineObject;
			lineObject.previous = previousObject;
		}
		else
			parentObject.children = [];
			
		lineObject.parent = parentObject;
		
		parentObject.children.push( lineObject );
	}
	
	
	return scriptObject;
}

function createDelegate( o, f )
{
	return function(){ return f.apply( o, arguments ); };
}

function getEventPosition( e )
{
	if( isTouch )
	{
		var touch = e.originalEvent.changedTouches[ 0 ];
		return { target: touch.target, left: touch.pageX, top: touch.pageY };
	}
	else
		return { target: e.target, left: e.pageX, top: e.pageY };
}


function showInfo( id )
{
	var $infoBox = $('#'+id);
	
	if( $infoBox.find('.close').length )
		$infoBox.click( closeInfo );
	
	$infoBox.fadeIn('fast');
}

function closeInfo( e )
{
	var $infoBox = $(this);
	
	$infoBox.click( null );
	
	if( $(e.target).is('.infobox, .close') )
		$infoBox.fadeOut('fast');
}

function startGameOrConnect()
{
	showInfo('facebook_choice');
}

function getBaseURL()
{
	var baseURL = location.toString();
	baseURL = baseURL.replace( location.search.toString(), '' );
	baseURL = baseURL.replace( location.hash.toString(), '' );
	baseURL = baseURL.replace( /\w*\.php/, '' );
	
	if( baseURL.charAt( baseURL.length-1 ) == '#' )
		baseURL = baseURL.substr( 0, baseURL.length-1 );
	
	return baseURL;
}

function facebookShare( heading, text, imageURL )
{
	var baseURL = getBaseURL();
	
	FB.ui
	(
		{
			'method': 'feed',
			'name': heading,
			'link': baseURL,
			'picture': imageURL,
			'description': text,
			'display': 'popup'
		}
	);
}

function getUserPersonalityType( user )
{
	return getSortedPersonalityTypes( user )[ 0 ].type;
}

function getPersonalityTypeText( type )
{
	switch( type )
	{
		case 'tough': 		return 'tøff';
		case 'caring': 		return 'omsorgsfull';
		case 'creative': 	return 'kreativ';
		default: 			return '[TYPE]';
	}
}

function getUserMedalType( user )
{
	return getMedalTypeForButtons( user.buttons );
}

function getMedalTypeForButtons( buttons )
{
	if( buttons >= 24 )
		return 'gold';
	else if( buttons >= 12 )
		return 'silver';
	else if( buttons >= 6 )
		return 'bronze';
	else
		return 'blue';
/*
Gullmedalje, 24 buttons
Sølvmedalje, 12 buttons
Bronsemedalje, 6 buttons
Medalje, 5 buttons
*/
}

function getMedalTypeText( type )
{
	switch( type )
	{
		case 'gold': 	return 'gullmedalje';
		case 'silver': 	return 'sølvmedalje';
		case 'bronze': 	return 'bronsemedalje';
		default: 		return 'en medalje';
	}
}

function shareGame()
{
	facebookShare( 
	'Er du en hverdagshelt? Ta testen her!', 
	'I spillet “Er du en hverdagshelt?” kan du hjelpe mennesker til å få det bedre. Ta testen og finn ut hvilken mennesketype du er og om du passer som helsefagarbeider.',
	getImageUrl('share')
	);
}

function shareResult()
{
	var type = getUserPersonalityType( personalityChoices );
	
	var typeText = getPersonalityTypeText( type );
	
	facebookShare( 
	'Jeg er en '+typeText+' hverdagshelt!', 
	'Jeg har testet meg selv, og ble en '+typeText+' hverdagshelt som vil bli en god helsefagarbeider. Hva blir du? Husk at du kan spille flere ganger. Lykke til!',
	getImageUrl('share_'+type)
	);
}

function shareMedal()
{
	var typeText = getPersonalityTypeText( getUserPersonalityType( personalityChoices ) );
	
	var medal = getMedalTypeForButtons( getNumberOfButtons() );
	var medalText = getMedalTypeText( medal );
	
	facebookShare( 
	'Jeg er en '+typeText+' hverdagshelt og har mottatt '+medalText+'!', 
	'Jeg har mottatt '+medalText+' i “Er du en hverdagshelt?”! Husk at du kan spille flere ganger for å samle buttons. Hvor mange buttons klarer du å samle?  Lykke til!',
	getMedalImageUrl(medal,'share')
	);
}

function startWithFacebook()
{
	var response = FB.getAuthResponse();
	
	if( response )
		startGame( true );
	else
		FB.login( loggedIn );
}

function loggedIn( response )
{
	if( response.authResponse )
	{
		startGame( true );
	}
}

function startWithoutFacebook()
{
	startGame( false );
}

function resetGame()
{
	loadPage('game_start.html',initStart);
}

function initStart()
{
	$.getJSON( 'get_user_data.php', {type:'latest'}, gotPlayers );
	
	
}


function gotPlayers( dataUsers )
{
	gotDataBatch( dataUsers );
	
	var $playersDiv = $('#gamearea .facebook_players > div');
	
	$playersDiv.empty();
	
	for( var facebookId in dataUsers )
	{
		var $playerDiv = $('<div>');
		
		$playersDiv.append( $playerDiv );
		
		getUser( facebookId, createDelegate( $playerDiv, gotPlayer ) );
		
	}
}

function gotPlayer( user )
{
	var $playerDiv = this;
	
	var type = getUserPersonalityType( user );
	var medal = getUserMedalType( user );
	
	$playerDiv.empty();
	$playerDiv.append( '<img src="'+user.picture+'" class="user"/>' );
	$playerDiv.append( '<strong class="'+type+'">'+ucFirst( getPersonalityTypeText( type ) )+'</strong> '+user.name+'&nbsp;&nbsp; ' );
	$playerDiv.append( '<span class="buttons"><img src="'+getMedalImageUrl( medal, 'micro' )+'" class="medal"/>&nbsp;'+user.buttons+'&nbsp;buttons</span>' );
}

function completedGame()
{
	loadPage('game_complete.html',initCompleted);
}

function initCompleted()
{
	
	if( useFacebook )
	{
		$.getJSON( 'save_user_data.php', personalityChoices, savedUserPersonality );
	}
	else
	{
		var $playersDiv = $('#gamearea .facebook_players > div');
		$playersDiv.empty();
	
		var $playersHeading = $('#gamearea .facebook_players > h2');
		$playersHeading.text('Spillere på Facebook');
	
		$.getJSON( 'get_user_data.php', {type:'latest'}, gotPlayers );
	}
	
	
	
	var sortedTypes = getSortedPersonalityTypes( personalityChoices );
	
	var bigType = sortedTypes[ 0 ].type;
	
	googleAnalytics( 'personality', name );
				
	var $results = $('.results');
	
	$results.addClass( bigType );
	
	var totalCount = 0;
	
	for( var n=0; n<sortedTypes.length; n++ )
		totalCount += sortedTypes[n].count;
	
	var $stats = $('.stats');
	
	for( var n=sortedTypes.length-1; n>=0; n-- )
	{
		var sortedType = sortedTypes[n];
		var $stat = $stats.find('.stat.'+sortedType.type);
				
		$stats.prepend( $stat );
		
		var fullWidth;
		
		if( $stat.hasClass( bigType ) )
		{
			fullWidth = 207;
			$stat.addClass('big');
			$stat.removeClass('small');
		}
		else
		{
			fullWidth = 170;
			$stat.addClass('small');
			$stat.removeClass('big');
		}
		
		var fill = ( sortedType.count / totalCount );
		
		var offset = Math.round( fullWidth * fill );
		
		$stat.css( 'backgroundPosition', offset+'px 0px' );
	}
	
	
	googleAnalytics( 'buttons', getNumberOfButtons() );
	
	var medal = getMedalTypeForButtons( getNumberOfButtons() );
	
	$('.medal').css( 'backgroundImage', 'url('+getMedalImageUrl( medal )+')' );
	$('.medal').addClass( medal );
	$('.medal .buttons').text( getNumberOfButtons() );
	
}

function savedUserPersonality( data )
{
	var playerFacebookId = getPlayerFacebookId();
	
	var playerUser = users[ playerFacebookId ];
	
	if( !playerUser )
		playerUser = users[ playerFacebookId ] = { id:playerFacebookId };
		
	for( var field in data )
		playerUser[ field ] = data[ field ];
	
	var $playersDiv = $('#gamearea .facebook_players > div');
	$playersDiv.empty();
	
	for( var facebookId in users )
	{
		var user = users[ facebookId ];
		
		if( user.installed && ( user.friend || facebookId == playerFacebookId ) )
		{
			var $playerDiv = $('<div>');
			
			$playersDiv.append( $playerDiv );
			
			getUser( facebookId, createDelegate( $playerDiv, gotPlayer ) );
		}
	}
}

function getImageUrl( name )
{
	return getBaseURL() + 'gfx/'+name+'.png';
}

function getMedalImageUrl( type, suffix )
{
	var parts = ['medal'];
	
	parts.push( type );
	
	if( suffix )
		parts.push(suffix);
	
	return getImageUrl( parts.join('_') );
}

function getSortedPersonalityTypes( typeCounts )
{
	var sortedTypes = [];
	
	var types = ['tough','caring','creative'];
	
	for( var n=0; n<types.length; n++ )
	{
		var type = types[ n ];
		
		sortedTypes.push( { type: type, count: typeCounts[ type ] } );
	}
	
	sortedTypes.sort( function(a,b){
		var c = a.count - b.count;
		
		if( c < 0 )
			return 1;
		else if( c > 0 )
			return -1;
		else
			return a.name < b.name;
	} );
	
	return sortedTypes;
}



function loadPage( page, callback )
{
	fadeOutAndThen( function()
	{
		$('#gamearea').load( page, callback );
	});
}

function fadeOutAndThen( callback )
{
	var $gamearea = $('#gamearea');
	
	if( $gamearea.find('*').length == 0 )
	{
		callback();
	}
	else
	{
		var $fade = $('<div class="fade"/>');
		$gamearea.after( $fade );
		$fade.hide();
		$fade.fadeIn( 'normal', function(){ $(this).fadeOut( 'normal',removeTarget ); callback(); } );
	}
}

users = {};

facebookFields = 'fields=name,id,picture,installed';
		
useFacebook = false;

collectedButtons = {};

personalityChoices = null;

function startGame( _useFacebook )
{
	useFacebook = _useFacebook;
	
	if( useFacebook )
	{
		FB.api('me?'+facebookFields,gotFacebookMe);
		FB.api('me/friends?'+facebookFields,gotFacebookFriends);
	}
	
	personalityChoices = {
		tough: 0,
		caring: 0,
		creative: 0
	};
	
	loadScene('gamedata/scene1.html');
}

function gotFacebookMe( response )
{
	addFacebookUsers( [ response ] );
}

function gotFacebookFriends( response )
{
	addFacebookUsers( response.data, true );
}

function gotFacebookUsers( response )
{
	addFacebookUsers( response );
}

function addFacebookUsers( facebookUsers, friends )
{
	for( n in facebookUsers )
	{
		var facebookUser = facebookUsers[ n ];
		
		var user = users[ facebookUser.id ];
		
		if( !user )
			user = users[ facebookUser.id ] = {};
		
		if( friends )
			user.friend = true;
		
		for( var field in facebookUser )
			user[ field ] = facebookUser[ field ];
			
		user.facebookStatus = 'loaded';
		
		checkUser( user );
	}
}

facebookBatchTimeout = 0;
dataBatchTimeout = 0;

function getUser( facebookIds, callback )
{
	if( typeof( facebookIds ) != 'object' )
		facebookIds = [ facebookIds ];
		
	for( var n=0; n<facebookIds.length; n++ )
	{
		var facebookId = facebookIds[ n ];
		
		var user = users[ facebookId ];
		
		if(!user)
			user = users[ facebookId ] = { id: facebookId };
			
		if( !user.facebookStatus )
		{
			user.facebookStatus = 'starting';
			
			if( facebookBatchTimeout )
				clearTimeout( facebookBatchTimeout );
				
			facebookBatchTimeout = setTimeout( makeFacebookBatch, 100 );
		}
		
		if( !user.dataStatus )
		{
			user.dataStatus = 'starting';
			
			if( dataBatchTimeout )
				clearTimeout( dataBatchTimeout );
				
			dataBatchTimeout = setTimeout( makeDataBatch, 100 );
		}
		
		if( callback )
		{
			if( !user.callbacks )
				user.callbacks = [];
				
			user.callbacks.push( callback );
		}
		
		checkUser( user );
	}
}

function checkUser( user )
{
	if( user.facebookStatus == 'loaded' && user.dataStatus == 'loaded' )
	{
		if( user.callbacks )
		{
			for( var n=0; n<user.callbacks.length; n++ )
			{
				var callback = user.callbacks[ n ];
				
				callback( user );
			}
			
			user.callbacks = undefined;
		}
	}
}


function makeFacebookBatch()
{
	var ids = [];
	
	for( var n in users )
	{
		var user = users[ n ];
		
		if( user.facebookStatus == 'starting' )
		{
			user.facebookStatus = 'loading';
			ids.push( user.id );
		}
	}
	
	//console.log('makeFacebookBatch',ids);
	
	FB.api('?ids='+ids.join(',')+'&'+facebookFields,gotFacebookUsers);
}

function makeDataBatch()
{
	var ids = [];
	
	for( var n in users )
	{
		var user = users[ n ];
		
		if( user.dataStatus == 'starting' )
		{
			user.dataStatus = 'loading';
			ids.push( user.id );
		}
	}
	
	//console.log('makeDataBatch',ids);
	
	$.getJSON( 'get_user_data.php', {facebook_ids: ids.join(',')}, gotDataBatch );
}

function gotDataBatch( dataUsers )
{
	for( var facebookId in dataUsers )
	{
		var dataUser = dataUsers[ facebookId ];
		
		var user = users[ facebookId ];
		
		if( !user )
			user = users[ facebookId ] = { id: facebookId };
			
		user.dataStatus = 'loaded';
			
		for( var field in dataUser )
			user[ field ] = dataUser[ field ];
			
		checkUser( user );
	}
}

function ucFirst( str )
{
	return str.charAt( 0 ).toUpperCase() + str.substr( 1 );
}

function shuffle(array)
{
    var tmp, current, top = array.length;

    if(top) while(--top) {
        current = Math.floor(Math.random() * (top + 1));
        tmp = array[current];
        array[current] = array[top];
        array[top] = tmp;
    }

    return array;
}



