//init variables
var isPaid = false;
//settings variables
var sound = true;
var narration = true;
var rated = false;
//levels variables
var wordLevels = new Array(19);
var imageLevels = new Array(19);
var bonusLevels = new Array(19);
var levelsScore = {
	word : [0],
	image : [0],
	bonus : [0]
};
var powerUps = {
	freeze : 2,
	reveal : 2,
	locate : 2
};
//variables used by timer, progress bar, popups, etc. (there is no need to store them in local storage)
var levelMode = null;
// var beforeBonus = null;
//the game mode which player has choosed
var playedLevel = 0; //current level
var levelsPlayed = 0; //played levels
var leftPrevs = []; //previews
var currentScore = 0;

var skin = 'stmpunk';

var clicked = null;
var scl = null;

//global handlers
$(window).ready(function() { //on app starts
	scaleScreen();
	//handle window visibility
	document.addEventListener("visibilitychange", function() {
		if(document.hidden && (sbTimer.isStarted || sbTimer.isFreezed)) {
			pause();
		}else if(document.hidden) {
			$("#include").css("opacity", "0.05");
			$("#dark_screen, #loading_bar").show();
			soundPlayer.mute(1, true); //mute theme sound
		}else { //the document is no more hidden
			showScreen(5000);
			if(sound) soundPlayer.mute(1, false); //mute theme sound
		}
	}, false);
	checkApp();
	$("#more_games_ads").on('mousedown touchstart', '*', tapDown)
	.on('mouseup touchend', '*', tapUp)
	.on('dragstart', function() { return false;});
	$("#more_games_ads_close").on('tap', closeAds); //it is global element, so we just bind in at the beginning
});
//load menu
function loadMenu(change) {
	//if the game is started for the first time or if there is a change in his paid status we need to change levels
	if(typeof (Storage) !== "undefined" && !$.isEmptyObject(localStorage) && localStorage.hasOwnProperty('levelsScore["bonus"]')) {
		loadPropertiesFromLS();
	} else {
		loadInitProperties();
	}
	loadLevels((typeof wordLevels[0]=='undefined' && typeof imageLevels[0]=='undefined'), change);	//at least one of these two flags must be true to load levels again
	//show secretbuilders logo
	$("#splash > img").show();
	setTimeout(function() {
		setPage({data : {next : "main_menu.html"}});
		//load device info
		loadApplicationData("/res/config/firefoxos.properties");
	}, 2000);
}
//init properties
function loadInitProperties() {
	//store in local storage
	if ( typeof (Storage) !== "undefined") {
		changeLS('sound', sound);
		changeLS('rated', rated);
		changeLS('narration', narration);
		changeLS('powerUps["freeze"]', powerUps.freeze);
		changeLS('powerUps["reveal"]', powerUps.reveal);
		changeLS('powerUps["locate"]', powerUps.locate);
		changeLS('levelsScore["word"]', levelsScore.word);
		changeLS('levelsScore["image"]', levelsScore.image);
		changeLS('levelsScore["bonus"]', levelsScore.bonus);
	}
}

//local storage
function loadPropertiesFromLS() {
	try {
		isPaid = JSON.parse(localStorage.getItem("isPaid"));

		sound = JSON.parse(localStorage.getItem("sound"));
		rated = JSON.parse(localStorage.getItem("rated"));
		narration = JSON.parse(localStorage.getItem("narration"));

		wordLevels = JSON.parse(localStorage.getItem("wordLevels"));
		imageLevels = JSON.parse(localStorage.getItem("imageLevels"));
		bonusLevels = JSON.parse(localStorage.getItem("bonusLevels"));

		levelsScore.word = JSON.parse(localStorage.getItem('levelsScore["word"]'));
		levelsScore.image = JSON.parse(localStorage.getItem('levelsScore["image"]'));
		levelsScore.bonus = JSON.parse(localStorage.getItem('levelsScore["bonus"]'));

		powerUps.freeze = JSON.parse(localStorage.getItem('powerUps["freeze"]'));
		powerUps.reveal = JSON.parse(localStorage.getItem('powerUps["reveal"]'));
		powerUps.locate = JSON.parse(localStorage.getItem('powerUps["locate"]'));
	} catch (e) {
		console.log("Missing member in local storage");
	}
}

function changeLS(member, value) {
	try {
		localStorage.setItem(member, JSON.stringify(value));
	} catch (e) {
		console.log("There is no such member! " + e);
	}
}

//check installation - verify receipts
function checkApp() {
	//check is app installed
	var request = navigator.mozApps.getSelf();
	request.onsuccess = function() {
		if (request.result == null) { //not installed
			handleVerification(false);
		} else if (request.result.receipts != "" && request.result.receipts != null) { //have receipt and is installed
			// alert(request.result.receipts);
			handleVerification(false);
		} else { //no receipt - free app
			changeLS('isPaid', isPaid);
			//isPaid = false here
			loadMenu(false);
			//there is not change of isPaid
		}
	};
	request.onerror = function() {
		console.log(request.error.name);
	};
}

function handleVerification(checkRefund) {
	var old = isPaid;
	var verifier = new mozmarket.receipts.Verifier({
		typsAllowed : ['purchase-receipt', 'developer-receipt', 'reviewer-receipt'],
		refundWindow : 1800000 //30 mins
	});
	verifier.verify(function(verifier) {
		if (verifier.state instanceof verifier.states.OK) {
			var appProps = window.navigator.mozApps.getSelf();
			appProps.onsuccess = function() {
				//check if user can make refund
				if (appProps.result.installTime + verifier.refundWindow > Date.now()) {
					//the user still can make a refund, so set timeout and check app again after some time
					var refundTimeLeft = verifier.refundWindow - (Date.now() - appProps.result.installTime);
					setTimeout(function() {
						handleVerification(true);
						//check for refund
					}, refundTimeLeft);
				}
			};
			isPaid = true;
		} else {
			isPaid = false;
		}
		changeLS('isPaid', isPaid);
		if(!checkRefund) {//we're not making a refund check
			loadMenu(isPaid !== old);
			//if there has change - true, else - false
		}else {
			loadLevels(false, isPaid !== old);
			//we're making a refund check, so check if there is a change
			//if we have a change, this means that the user has made a refund,
			//so we have to load levels for free app only
		}
	});
}

//load levels
function loadLevels(neverLoaded, changed) {//we use changed only to know that we need to load levels again
	if (!(neverLoaded || changed)) return; //there has no need of loading levels again
	if (isPaid) {
		for (var i = 0; i < wordLevels.length; i++) { //load levels, there is no way to upgrade the game from free to paid, only the oposite is possible
			if (i == 0) {
				wordLevels[i] = 0;
				imageLevels[i] = 0;
				bonusLevels[i] = -1;
			} else if (i > 0) {
				wordLevels[i] = -1;
				imageLevels[i] = -1;
				bonusLevels[i] = -1;
			}
		}
	} else {
		for (var i = 0; i < wordLevels.length; i++) {
			if (i == 0 && neverLoaded) { //first level
				wordLevels[i] = 0;
				imageLevels[i] = 0;
				bonusLevels[i] = -1;
			} else if (i < 3 && neverLoaded) { //level 2 and 3
				wordLevels[i] = -1;
				imageLevels[i] = -1;
				bonusLevels[i] = -1;
			} else if (i > 2) { //other levels
				wordLevels[i] = -2;
				imageLevels[i] = -2;
				bonusLevels[i] = -2;
			}
		}
	}
	//save changes
	changeLS('wordLevels', wordLevels);
	changeLS('imageLevels', imageLevels);
	changeLS('bonusLevels', bonusLevels);
}

//scale screen size
function scaleScreen() {
	var w = $(window).width();
	var h = $(window).height();
	//compare to 1280x800 - base screen
	var scale = Math.min(w / 1280, h / 800);
	if(scale > 1) scale = 1;
	scale = scale.toFixed(3);
	var offset = $("body").offset();
	var pos = null;
	if (w / 1280 < h / 800) {//change y-axis transform-origin
		pos = "0 " + ((1 - scale) * ((h / scale) - 800)) + "px 0";
	} else {//change x-axis transform-origin
		pos = ((1 - scale) * ((w / scale) - 1280)) + "px 0 0";
	}
	scl = scale;
	//scale and place
	$("body").width(w).height(h);
	//set width and height like viewport
	changeCSS("body", "left", -1 * offset.left);
	changeCSS("body", "top", -1 * offset.top);
	changeCSS("#wrapper", "transform", "scale(" + scale + ")");
	changeCSS("#wrapper", "transform-origin", pos);
}

function changeCSS(selector, property, value) {
	var rules = document.styleSheets[0]['cssRules'];
	for (var i = 0; i < rules.length; i++) {//change css class property
		if (rules[i].selectorText == selector) {
			$(rules[i]).css(property, value);
			break;
		}
	}
}
//prepare methods
function prepareButtons() {
	soundPlayer.start(1);
	//prepare buttons
	if(isPaid) {
		$("#get_full_game").remove();
		$("#coins").show();
		if(skin == 'stmpunk') {
			$("#play, #more_games").css("margin-top", "50px");
			$("#settings").css("left", "210px");
			$("#help").css("left", "325px");
			$("#book_menu").css("left", "440px");
		}
	}
	if(skin == 'blue') {
		var buttons = ( isPaid ? ['#play', '#more_games', '#settings', '#help', '#book_menu', '#coins'] : ['#play', '#more_games', '#get_full_game', '#settings', '#help', '#book_menu']);
		for(var i = 0; i < buttons.length; i++) {
			loadButtons(buttons[i], i);
		}
	}
}

function loadButtons(obj, i) {
	$(obj).delay(150 * i);
	var lef = 0;
	if (obj == "#play") {
		lef = 120;
	} else if (obj == "#more_games") {
		lef = isPaid ? 150 : 30;
	} else if (obj == "#get_full_game") {
		lef = 320;
	} else if (obj == "#settings") {
		lef = 60;
	} else if (obj == "#help") {
		lef = 180;
	} else if (obj == "#book_menu") {
		lef = 300;
	} else if (obj == "#coins") {
		lef = 420;
	}
	$(obj).animate({
		left : (i == 0 ? lef - 100 : lef + 100)
	}, 'medium', function() {
		//play sound with buttons
		if (obj == '#play' || obj == '#more_games' || obj == '#get_full_game') {
			soundPlayer.start(5);
		} else {
			soundPlayer.start(4);
		}
		//animate objects
		$(obj).animate({
			left : lef
		}, 'fast');
	});
}

//Ads API
var Application = {
	id : null,
	secret : null
};
var DeviceInfo = {
	model : "fxosDevice",
	dpi : 96,
	screen_resolution : {
		yRes : $(window).height(),
		xRes : $(window).width()
	},
	os_code : 5,
	os_version : 0,
	country : "US",
	language : "en",
	uuid : null
};
var un = 0;
var sid = null;

//uuid from receipt
function setUuid() {
	if (!isPaid) {//free application uuid
		var receipt = "no-or-invalid-receipt-free-application";
		DeviceInfo.uuid = getHmac(receipt, Application.secret);
	} else {
		var request = navigator.mozApps.getSelf();
		request.onsuccess = function() {
			if (request.result != null) {
				if (request.result.receipts != null) {
					DeviceInfo.uuid = getHmac(request.result.receipts, Application.secret);
				}
			}
		};
	}
}

function loadApplicationData(src) {
	var file = new XMLHttpRequest();
	file.open("GET", src, true);
	file.onreadystatechange = function() {
		if (file.readyState === 4 && (file.status === 200 || file.status == 0)) {
			var text = file.responseText.split("\n");
			Application.id = parseInt(text[0].replace("app_id=", ""));
			Application.secret = text[1].replace("app_secret=", "").replace("\r", "");
			//DeviceInfo model
			var model = navigator.userAgent;
			model = model.slice(model.indexOf("Mobile"), model.indexOf("rv")).replace("Mobile; ", "");
			if (model != 'undefined' && model != null && model != '')
				DeviceInfo.model = model;
			setUuid();
		}
	};
	file.send();
}

function getHmac(map, secret) {
	var message = getOrderedPairs(map, "");
	message = customReplace(message, ",", "");
	return CryptoJS.HmacMD5(message, secret).toString();
}

function getOrderedPairs(map, arr) {
	map = sortByKey(map);
	for (k in map) {
		var obj = map[k];
		if ( obj instanceof Object) {
			arr += k;
			arr = getOrderedPairs(obj, arr);
		} else {
			arr += k + "," + (obj != null ? obj + "," : "");
		}
	}
	return arr;
}

function sortByKey(map) {
	var keys = [];
	var sorted = {};
	for (key in map) {
		if (map.hasOwnProperty(key)) {
			keys.push(key);
		}
	}
	// sort keys
	keys.sort();
	// create new array based on Sorted Keys
	$.each(keys, function(i, key) {
		sorted[key] = map[key];
	});
	return sorted;
};
function customReplace(str, regex, replacer) {
	var result = "";
	for (var i = 0; i < str.length; i++) {
		if (str[i] != regex) {
			result += str[i];
		} else {
			result += replacer;
		}
	}
	return result;
}

function createCORSRequest(method, url) {
	var xhr = new XMLHttpRequest();
	if ("withCredentials" in xhr) {
		xhr.open(method, url, true);
	} else if ( typeof XDomainRequest != "undefined") {
		xhr = new XDomainRequest();
		xhr.open(method, url);
	} else {
		xhr = null;
	}
	return xhr;
}

function putMethod(url, data, success) {
	var xhr = createCORSRequest('PUT', url);
	if (!xhr) {
		console.log('CORS not supported');
		return;
	}
	xhr.setRequestHeader("Content-Type", "application/json");
	xhr.setRequestHeader("X-Rworld-Header", "rworld-sb");
	xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
	xhr.onload = function() {
		success(xhr.responseText);
	};
	xhr.onerror = function(e) {
		console.log("Error:" + e.responseText);
		//reward only
		if (document.getElementById("get_reward_label") != null)
			$("#get_reward_label").html("INVALID USER OR<br/>WRONG PASSWORD");
	};
	xhr.send(data);
}

function postMethod(url, data) {
	var xhr = createCORSRequest('POST', url);
	if (!xhr) {
		console.log('CORS not supported');
		return;
	}
	xhr.setRequestHeader("Content-Type", "application/json");
	xhr.setRequestHeader("X-Rworld-Header", "rworld-sb");
	xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
	xhr.onload = function() {
		// console.log(xhr.responseText);
	};
	xhr.onerror = function(e) {
		console.log("Error:" + e.responseText);
	};
	xhr.send(data);
}

//handle reward
function checkReward() {
	//check if the user can still make a refund
	var appProps = window.navigator.mozApps.getSelf();
	appProps.onsuccess = function() {
		//check if user can make refund
		if (appProps.result.installTime + 1800000 > Date.now()) {
			//the user still can make a refund, so set timeout and check app again after some time
			var refTimeLeft = 1800000 - (Date.now() - appProps.result.installTime);
			$("#check_reward").hide();
			document.getElementById("time_left").innerHTML = (refTimeLeft / (60 * 1000)).toFixed(0);
			$("#wait_for_reward").show();
		} else {
			putMethod("http://secretbuilders.com/MobileNetwork/mobile/reward/info/" + Application.id, DeviceInfo.uuid, handleReward);
		}
	};
}

function handleReward(resp) {
	resp = JSON.parse(resp);
	if (resp.hasOwnProperty("available")) {//we can receive a reward
		if (!resp.available) {
			$("#check_reward").hide();
			$("#already_received").show();
			return;
		}
		$("#check_reward").hide();
		$("#get_reward").show();
		$("#get_reward_btn").on('tap', function() {
			var reward = {
				appId : Application.id,
				deviceId : DeviceInfo.uuid,
				userId : $("#user").val(),
				password : $("#password").val()
			};
			reward.hmac3 = getHmac(reward, Application.secret);
			putMethod("http://secretbuilders.com/MobileNetwork/mobile/reward/reward/" + Application.id, JSON.stringify(reward), receiveReward);
			//show message to user
			$("#get_reward_label").text("GETTING REWARD...");
		});
	} else {
		$("#check_reward").hide();
		$("#already_received").show();
	}
}

function receiveReward(data) {//show reward received screen
	$("#get_reward").hide();
	$("#reward_received").show();
}

//handle ads popups
function showAds(e) { //call first request and get app - id and secret
	var data = JSON.stringify({hmac2:getHmac({device_info:DeviceInfo}, Application.secret),device_info:DeviceInfo});
	if(e != null && e.target != null) {
		$(e.target).addClass('disable_pe');
		//show popup
		$("#more_games_content_inside").append('<div id="ads_inside" class="text_regular">Loading...</div>');
		$("#more_games_ads").css("visibility", "visible");
		//send request
		putMethod("http://secretbuilders.com/MobileNetwork/mobile/app/" + Application.id, data, getAds);
	}else if(e == "complete") {
		putMethod("http://secretbuilders.com/MobileNetwork/mobile/app/" + Application.id, data, getAd);
	}
}

function getAds(data) {//make next call and get all data needed for the ads
	soundPlayer.start(5);
	//play sound
	$("#dark_screen").show();
	data = JSON.parse(data);
	//set sid and un
	un = data.un;
	sid = data.sid;
	var params = {
		count : 6,
		ad_size : calcAdSize('banner'),
		ad_type : 0
	};
	putMethod("http://secretbuilders.com/MobileNetwork/mobile/ads/" + sid, JSON.stringify(params), loadAds);
}

function getAd(data) {
	data = JSON.parse(data);
	//set sid and un
	un = data.un;
	sid = data.sid;
	var params = {
		count : 1,
		ad_size : calcAdSize('banner'),
		ad_type : 0
	};
	putMethod("http://secretbuilders.com/MobileNetwork/mobile/ads/" + sid, JSON.stringify(params), loadAd);
	if (isFullScreen()) {
		$("#include").off('tap', '#next').on('tap', '#next', data, fullScreenAd);
	}
}

function loadAd(data) {//show 1 ad
	var obj = JSON.parse(data)[0];
	if(obj) {
		var img = document.createElement("img");
		img.src = obj.picture_url;
		$(img).on('tap', function() {
			//send request to server that the image has clicked
			adsHandler(obj, "click");
			window.open(obj.onclick_url, "_blank", false);
		});
		$(img).css("display", "none");
		//make image to load at once
		if (isFullScreen() && obj.ad_type == 1) {
			$("#loading_bar").show();
			var offset = $("#wrapper").height() - obj.height;
			$(img).attr({
				"width" : obj.width + 'px',
				"height" : obj.height + 'px'
			}).css({"margin-top": offset/2, "margin-left": "58px"}); //58px is the width of the close button
			$("#full_screen_ad").append(img).show();
			$(img).load(function() {
				$("#loading_bar").hide();
				$(img).show();
				adsHandler(obj, "view");
			});
		} else {
			$(img).attr({
				"width" : obj.width + 'px',
				"height" : obj.height + 'px'
			});
			$("#ad_holder").append(img);
			$(img).load(function() {
				$(img).fadeIn("fast");
				adsHandler(obj, "view");
			});
		}
	}else {
		if(isFullScreen()) $("#include").off('tap', '#next').on('tap', '#next', nextLevel);
	}
	//show rate it popup
	if (canRateIt()) {
		$("#get_more").show();
		$("#rate_popup").show();
		togglePopup("#rate_popup", true);
		soundPlayer.start(5);
		//play sound
	}
}

function loadAds(data) {//make ads (print them on the screen)
	var flag = true;
	var arr = JSON.parse(data);
	for (var i = 0; i < arr.length; i++) {
		var img = document.createElement("img");
		img.src = arr[i].picture_url;
		$(img).on('tap', function() {//send request to the server that the image has clicked
			for (var j = 0; j < arr.length; j++) {//find this image info
				if (this.src.indexOf(arr[j].picture_url) > -1) {
					window.open(arr[j].onclick_url, "_blank", false);
					adsHandler(arr[j], "click");
					break;
				}
			}
		});
		$(img).attr({
			"width" : arr[i].width + 'px',
			"height" : arr[i].height + 'px'
		});
		$("#ads_inside").remove(); //remove loading...
		$("#more_games_content_inside").append(img);
		//resize the ads window
		$(img).load(function() {
			if (flag) {//resize window once
				flag = false;
				$("#more_games_ads_close").css("right", "220px");
				$("#more_games_top").width(820).css("background-size", "820px 360px");
				$("#more_games_ads_content").width(820);
				$("#more_games_content_inside").width(810);
			} else {//resize window for every other ad
				$("#more_games_ads").css("top", parseInt($("#more_games_ads").css("top")) - 40);
				$("#more_games_ads_content").height($("#more_games_ads_content").height() + 97);
				$("#more_games_content_inside").height($("#more_games_content_inside").height() + 97);
			}
			$(this).fadeIn();
			//send request to server that the image has viewed
			for (var j = 0; j < arr.length; j++) {//find this image info
				if (this.src.indexOf(arr[j].picture_url) > -1) {
					adsHandler(arr[j], "view");
					break;
				}
			}
		}).error(function() {
			$("#ads_inside").remove();
			if ($("#more_games_content_inside").children().length < 1) {
				$("#more_games_content_inside").append('<div id="ads_inside" class="text_regular">There are no available Games yet!</div>');
			}
		});
	}
	if(arr.length < 1) {
		$("#ads_inside").remove(); //remove loading...
		$("#more_games_content_inside").append('<div id="ads_inside" class="text_regular">There are no available Games yet!</div>'); //there are no available ads
	}
}

function adsHandler(obj, type) {
	var adInf = {
		// adInfo: null, //set it only because of hmac
		ad_type : obj.ad_type,
		app_id : Application.id,
		height : obj.height,
		id : obj.id,
		onclick_url : obj.onclick_url,
		picture_url : obj.picture_url,
		width : obj.width
	};
	var data = {
		adInfo : adInf,
		uniqueNumber : ++un,
	};
	var hmac = getHmac(data, Application.secret);
	data.hmac2 = hmac;
	// delete adInf.adInfo; //remove useless property
	data.adInfo = adInf;
	postMethod("http://secretbuilders.com/MobileNetwork/mobile/ads/" + sid + "/" + type, JSON.stringify(data));
}

function calcAdSize(type) {
	var width = 800;
	var height = type == 'full' ? 1280 : 110;
	var size = height;
	size = size << 16;
	size = size | width;
	return size;
}

function isFullScreen() {
	return (levelsPlayed % 4 == 0 && levelsPlayed != 0);
	//fullscreen
}

function canRateIt() {
	return (levelsPlayed % 3 == 0 && levelsPlayed != 0 && !rated);
}

function closeAds() {
	$(".disable_pe").removeClass('disable_pe'); //enable the buttons which cals showAds
	$("#dark_screen").hide(); //hide dark screen
	//remove all banners
	$("#more_games_content_inside").find("*").remove();
	//return old style
	$("#more_games_ads_close").removeAttr('style');
	$("#more_games_ads").removeAttr('style');
	$("#more_games_top").removeAttr('style');
	$("#more_games_ads_content").removeAttr('style');
	$("#more_games_content_inside").removeAttr('style');
}

function getGame(e) {
	if(e!="undefined" && e == "rateIt") { //the url of the game "write review"
		window.open("https://marketplace.firefox.com/app/arabian-nights-hidden-free/ratings/add", "_blank", false);
	}else { //url of the game, set when build the game
		window.open("https://marketplace.firefox.com/app/arabian-nights-hidden-object", "_blank", false);
	}
}

function getAll() {
	if (!canSlide)
		return;
	//we just sliding, no need to show popup
	soundPlayer.start(5);
	//play sound
	$("#get_more").show();
	if (isPaid) {
		$("#comming_soon").show();
		togglePopup("#comming_soon", true);
	} else {
		$("#full_game").show();
		togglePopup("#full_game", true);
	}
}

function getMoreGames(evn) {
	showAds(null);
	closePopup(evn);
}

function getFullGame(evn) {
	if(evn.data.parent.id == "rate_it") {
		doNotRate(evn.data.parent);
	}else {
		closePopup(evn);
	}
	soundPlayer.start(5); //play sound
	getGame("rateIt");
}

function fullScreenAd(evn) {
	var data = evn.data;
	//set sid and un
	sid = data.sid;
	un = data.un;
	if (isFullScreen()) {
		var params = {
			count : 1,
			ad_size : calcAdSize('full'),
			ad_type : 1
		};
		putMethod("http://secretbuilders.com/MobileNetwork/mobile/ads/" + sid, JSON.stringify(params), loadAd);
	} else {
		nextLevel();
	}
}

function togglePopup(obj, shown) {
	$(obj).animate({
		borderSpacing : ( shown ? 0.25 : 0)
	}, {
		step : function(now, fx) {
			$(this).css("transform", "scale(" + (1 - now) + ")");
		},
		duration : "fast"
	}, "linear");
}

function closePopup(evn) {
	$("#get_more").hide();
	togglePopup(evn.data.parent, false);
}

function doNotRate() {
	rated = true;
	changeLS("rated", rated);
	closePopup({data : {parent : $("#rate_popup").parent()}});
}

//buttons actions and events
//Settings.html
function exitSettings() {
	changeLS('sound', sound);
	changeLS('narration', narration);
	if(sbTimer.isPaused) {
		setPage({data : {next : 'pause.html'}});
	}else {
		setPage({data : {next : 'main_menu.html'}});
	}
}

function changeSound() {
	var sfx = document.getElementById("sound_on");
	if(sfx == null) sfx = document.getElementById("sound_off");
	if(sfx.id == "sound_on") {
		sfx.id = "sound_off";
		soundPlayer.mute(1, true); //mute the theme sound
		sound = false;
	}else {
		sfx.id = "sound_on";
		soundPlayer.mute(1, false); //unmute the theme sound
		sound = true;
	}
}

function changeNarration() {
	var narr = document.getElementById("narration_on");
	if(narr == null) narr = document.getElementById("narration_off");
	if(narr.id == "narration_on") {
		narr.id = "narration_off";
		soundPlayer.mute(6, true); //mute narration
		narration = false;
	}else {
		narr.id = "narration_on";
		soundPlayer.mute(6, false); //unmute narration
		narration = true;
	}
}
//level_select.html
function selectLevel(evn) {
	levelMode = evn.data.mode;
	// beforeBonus = levelMode;
	setPage({data : {next : 'level_select.html'}});
}

//main menu
function loadFB() {
	window.open("http://facebook.com/secretbuilders", "_blank", false);
}

//common used
function setPage(evn) {
	closeAds(); //if the user opens ads and succeed with clicking on other button
	$("#include").css("opacity", 0.05);
	//hide the whole content
	var page = evn.data.next;
	$("#dark_screen, #loading_bar").show();
	//load new page and unbind all event listeners
	$("#include").load(page, function() {
		var imgReady = 1;
		var imgs = $("#include img");
		//all images
		var checkReady = function() {
			if (imgReady == 0) {//images are loaded
				//everything is ready
				loadPage(page);
			}
		};
		for (var i = 0; i < imgs.length; ++i) {
			++imgReady;
			imgs[i].onload = function() {
				--imgReady;
				checkReady();
			};
		}
		--imgReady;
		checkReady();
	}).find("*").andSelf().off().unbind();
}
function showScreen(del) {
	setTimeout(function() {
		$("#include").animate({opacity: 1}, 'fast', function() { $("#dark_screen, #loading_bar").hide();});
	}, del);
}
function loadPage(page) {
	//button click sound
	var playButtonClick = function(e) {
		e.preventDefault();
		soundPlayer.start(3);
	};
	//add event listeners
	if (page == 'main_menu.html') {
		$("#include").ready(function() {
			prepareButtons();
			showScreen(700);
			setTimeout(function() {$("#splash").remove();}, 1500);
		})
		.on('tap', '#fburl', loadFB).on('tap', '#play', {next : 'game_modes.html'}, setPage)
		.on('tap', '#more_games', showAds)
		.on('tap', '#get_full_game', getGame)
		.on('tap', '#settings', {next : 'settings.html'}, setPage)
		.on('tap', '#help', {next : 'help.html'}, setPage)
		.on('tap', '#book_menu', {next : 'book.html'}, setPage)
		.on('tap', '#coins', {next : 'coins.html'}, setPage)
		.on('tap', '#play,#get_full_game,#settings,#help,#book_menu,#coins', playButtonClick);
	} else if (page == 'game_modes.html') {
		$("#include").ready(function() {
			showScreen(500);
			printStars();
		})
		.on('tap', '#back_btn', {next : 'main_menu.html'}, setPage)
		.on('tap', '#word_mode', {mode : 'word'}, selectLevel)
		.on('tap', '#image_mode', {mode : 'image'}, selectLevel)
		.on('tap', '#bonus_mode', {mode : 'bonus'}, selectLevel)
		.on('tap', '#back_btn, #word_mode, #image_mode, #bonus_mode', playButtonClick);
	} else if (page == 'settings.html') {
		$("#include").ready(function() {
			showScreen(500);
			printStars();
			syncOptions();
		})
		.on('tap', '#back_btn', exitSettings)
		.on('tap', '#sound_on', changeSound)
		.on('tap', '#sound_off', changeSound)
		.on('tap', '#narration_on', changeNarration)
		.on('tap', '#narration_off', changeNarration)
		.on('tap', '#credits', {next : 'credits.html'}, setPage)
		.on('tap', '#back_btn, #sound_off, #narration_on, #narration_off, #credits', playButtonClick);
	} else if (page == 'credits.html') {
		$("#include").ready(function() {showScreen(500);})
		.on('tap', '#back_btn', {next : 'settings.html'}, setPage)
		.on('tap', '#back_btn', playButtonClick);
	} else if (page == 'help.html') {
		$("#include").ready(function() { showScreen(500);})
		.on('tap', '#back_btn', {next : 'main_menu.html'}, setPage)
		.on('tap', '#back_btn', playButtonClick);
	} else if (page == 'book.html') {
		$("#include").ready(function(){ showScreen(500);})
		.on('tap', '#back_btn', {next : 'main_menu.html'}, setPage)
		.on('tap', '#buy_book', function() {
			window.open("http://elt.oup.com/catalogue/items/global/graded_readers/dominoes/starter/9780194247160", "_blank", false);})
		.on('tap', '#back_btn,#buy_book', playButtonClick);
	} else if (page == 'coins.html') {
		$("#include").ready(function() {
			showScreen(500);
			checkReward();	
		})
		.on('tap', '#more_games_ads_close', closeRewardScreen);
	} else if (page == 'level_select.html') {
		$("#include").ready(function() {
			showScreen(500);
			printStars();
			printLevels();
			printPages();
			handleSlide();
		}).on('tap', '#back_btn', {next : 'game_modes.html'}, setPage)
		.on('tap', '#get_full_popup_btn', {parent : $("#get_full_popup_btn").parent()}, getFullGame)
		.on('tap', '.no_thanks_big_popup_btn', {parent : $(".no_thanks_big_popup_btn").parent()}, closePopup)
		.on('tap', '#more_games_popup_btn', {parent : $("#more_games_popup_btn").parent()}, getMoreGames)
		.on('tap', '#go_left', slidePrevious)
		.on('tap', '#go_right', slideNext).on('tap', '#back_btn', playButtonClick);
	} else if (page == 'gameplay.html') {
		$("#include").ready(function() {loadLevel();})
		.on('tap', '#hint', function() {
			sbTimer.hintTime = 30;
			hint("#hint", 30, null, 0);
		}).on('tap', '.power_up:first', function() { powerUp('freeze', 20);})
		.on('tap', '.power_up:odd', function() { powerUp('reveal', 5);})
		.on('tap', '.power_up:last', function() { powerUp('locate', 5);})
		.on('tap', '#locate_popup', closeLocate)
		.on('tap', '#pause_up', pause)
		.on('tap', '#magnifier_icon', toggleMagnifier)
		.on('tap', '#pause_up', playButtonClick);
		if(sbTimer.isStopped) $("#include").one('tap', '#magnifier_icon', function() { //handle first click on the magnifier
			if(playedLevel == 1) {
				$("#dialogue_screen").css("visibility", "visible");
				if(levelMode=='bonus') $("#dialogue").css("opacity", 1);
				sbTimer.pause(); //stop the timer
				//write help info
				document.getElementById("dialogue_content").innerHTML = "Get a closer look with the</br>magnifying glass!</br></br>" +
					"Use your finger to move the</br>magnifying glass around.</br></br>" +
					"If you find an object, you can</br>touch it through the glass.";
				//prepare buttons
				$("#back_arrow").hide(); //hide back arorw, we don't need it
				$("#start").attr("class", "dialogue_start");
				$("#start, #dialogue_close").off().on('tap', function() {
					sbTimer.start(); //resume the timer
					$("#dialogue_screen").remove(); //remove the dialogue screen
				});
			}
		});
	} else if (page == 'pause.html') {
		$("#include").ready(function() {
			showScreen(500);
			printStars();
		})
		.on('tap', '#main_menu_btn', {mode : 'main'}, exitPause)
		.on('tap', '#resume', {next : 'gameplay.html'}, setPage)
		.on('tap', '#levels', {mode : 'levels'}, exitPause)
		.on('tap', '#settings_big', {next : 'settings.html'}, setPage)
		.on('tap', '#more_games_big', showAds)
		.on('tap', '#main_menu_btn, #resume, #levels, #settings_big, #more_games_big', playButtonClick);
	} else if (page == 'level_failed.html') {
		$("#include").ready(function() { showScreen(500);})
		.on('tap', '#try_again', {lvl : playedLevel - 1}, startLevel);
	} else if (page == 'level_complete.html') {
		$("#include").ready(function() {
			showScreen(500);
			if(skin != 'blue') $("#frame").css("visibility", "hidden");
			printScore();
			spinStars();
			showAds('complete');
		}).on('tap', '#rate_it', {parent : $("#rate_it").parent()}, getFullGame)
		.on('tap', '#remind_me', {parent : $("#remind_me").parent()}, closePopup)
		.on('tap', '#no_thanks_small', doNotRate).on('tap', '#next', nextLevel)
		.on('tap', '#replay', {lvl : playedLevel - 1}, startLevel)
		.on('tap', '#levels_complete', {mode : levelMode}, selectLevel)
		.on('tap', '#more_games_medium', showAds)
		.on('tap', '#more_games_ads_close', closeFullScreenAd)
		.on('tap', '#next, #levels_complete, #more_games_medium', playButtonClick);
	} else if (page == 'levels_finished.html') {
		$("#include").ready(function() {
			showScreen(500);
			document.getElementById("congratulations").className = ( isPaid ? "all_finished" : "free_finished");
		}).on('tap', '#main_menu_btn', {next : 'main_menu.html'}, setPage)
		.on('tap', '#get_full_game_long', getGame)
		.on('tap', '#more_games_medium', showAds)
		.on('tap', '#main_menu_btn, #get_full_game_long, #more_games_medium', playButtonClick);
	}
	$("#include").on('mousedown touchstart', '*', tapDown)
	.on('mouseup touchend', '*', tapUp)
	.on('dragstart', 'img', function() { return false;}); //disable image dragging and show the whole content
}
/*Handle clicks*/
function tapDown(e) {
	var target = null;
	if('ontouchstart' in window) {
		if(e.originalEvent.targetTouches.length == 1) {
			var touch = e.originalEvent.targetTouches[0];
			target = touch.target;
		}
	}else {
		target = e.target;
	}
	if(target == document.getElementById("magnifier_container") || target == document.getElementById("magnifier")) return;
	//e.preventDefault();
	e.stopPropagation();
	clicked = {};
	clicked.object = target;
	clicked.left = $(clicked.object).offset().left;
	clicked.top = $(clicked.object).offset().top;
	clicked.right = (clicked.left + $(this).width());
	clicked.bottom = (clicked.top + $(this).height());
}
function tapUp(e) {
	if(clicked==null) return; //there is no clickable object
	e.preventDefault();
	e.stopPropagation();
	if('ontouchstart' in window) {
		if(e.originalEvent.changedTouches.length == 1) {
			var touch = e.originalEvent.changedTouches[0];
			if(((touch.pageX >= clicked.left && touch.pageX <= clicked.right) && (touch.pageY >= clicked.top && touch.pageY <= clicked.bottom))
			    || ((touch.target.parentNode == document.getElementById("magnifier_container") || touch.target.parentNode.className == "obj_div" || touch.target.parentNode.tagName.toLowerCase() == "td")
			     && touch.target == clicked.object)) {
				$(clicked.object).trigger('tap', [touch.pageX, touch.pageY]); //the click is in the old place of the button
			}
		}
	}else {
		if(((e.pageX >= clicked.left && e.pageX <= clicked.right) && (e.pageY >= clicked.top && e.pageY <= clicked.bottom))
		    || ((e.target.parentNode == document.getElementById("magnifier_container") || e.target.parentNode.className == "obj_div" || e.target.parentNode.tagName.toLowerCase() == "td") 
		    && e.target == clicked.object)) {
			$(clicked.object).trigger('tap', [e.pageX, e.pageY]); //the click is in the old place of the button
		}
	}
	clicked = null;
}
//play levels methods
function startLevel(e) {
	var levels = null;
	if (levelMode == 'word') {
		levels = wordLevels;
	} else if (levelMode == 'image') {
		levels = imageLevels;
	} else {
		levels = bonusLevels;
	}
	if (levels[e.data.lvl] >= 0) {
		soundPlayer.start(3);
		//play sound
		playedLevel = e.data.lvl + 1;
		setPage({
			data : {
				next : "gameplay.html"
			}
		});
	} else {
		soundPlayer.start(2);
		//locked sound
	}
}

function closeFullScreenAd() {
	$("#more_games_ads_close").on('tap', closeAds);
	$("#include").off('tap', '#next').on('tap', '#next', nextLevel);
	$("#full_screen_ad").hide();
	$("#loading_bar").hide();
}

function closeRewardScreen() {
	$("#more_games_ads_close").on('tap', closeAds);
	setPage({data : {next : 'main_menu.html'}});
}

function nextLevel() {
	//start next level
	// if (beforeBonus != 'bonus' && levelMode != 'bonus') {//we just have played normal level
		// levelMode = 'bonus';
		// startLevel({data : {lvl : playedLevel - 1}});
		//play bonus level after every normal level
	// } else if (beforeBonus != 'bonus' && levelMode == 'bonus') { //continue playing normal levels
		// levelMode = beforeBonus;
	if(levelMode == 'word' && wordLevels.length > playedLevel) {
		if(wordLevels[playedLevel] > -2) { //check is unlockable
			startLevel({data : {lvl : playedLevel}});
		}else { //all levels are finished
			setPage({data : {next : 'levels_finished.html'}});
		}
	}else if(levelMode == 'image' && imageLevels.length > playedLevel) {
		if (imageLevels[playedLevel] > -2) { //check is unlockable
			startLevel({data : {lvl : playedLevel}});
		} else { //all levels are finished
			setPage({data : {next : 'levels_finished.html'}});
		}
	}else if(levelMode == 'bonus' && bonusLevels.length > playedLevel) {
		if(bonusLevels[playedLevel] > -1) { //check is already unlocked
			startLevel({data : {lvl : playedLevel}});
		}else if(bonusLevels[playedLevel] == -1) { //locked level, go back to level select screen
			selectLevel({data : {mode : levelMode}});
		}else { //all levels are finished
			setPage({data : {next : 'levels_finished.html'}});
		}
	}else {
		setPage({data : {next : 'levels_finished.html'}});
		// selectLevel({data : {mode : levelMode}});
	}
}

function exitPause(e) {
	//clear data about found items
	leftPrevs = [];
	sbTimer.stop();
	sbProgressBar.stop();
	soundPlayer.stop(6);
	if(e.data.mode == 'levels') {
		// levelMode = beforeBonus;
		//here levelMode can be different than real user choice
		selectLevel({data : {mode : levelMode}});
	} else {
		setPage({data : {next : 'main_menu.html'}});
	}
}

var sbTimer = {
	time : 0,
	timer : null,
	isPaused : false,
	isStopped : true,
	isStarted : false,
	isFreezed : false,
	freezeTimeout : 0,
	freezedTime : 0,
	hintTime : 0,
	once : function() {
		if(typeof(sbTimer.timer) == 'undefined') sbTimer.stop();
		var min = Math.floor(sbTimer.time / 60);
		var sec = sbTimer.time % 60;
		sbTimer.timer.innerHTML = "" + Math.floor(min / 10) + min % 10 + ":" + Math.floor(sec / 10) + sec % 10;
		if(sbTimer.time > 0) {
			//play sound if needed
			if(sbTimer.time < 11 && sbTimer.time % 2 == 0) {
				soundPlayer.start(10); //play tik
			}else if(sbTimer.time < 11 && sbTimer.time % 2 != 0) {
				soundPlayer.start(11); //play tok
			}
			--sbTimer.time;
			//handle pause, hint and reveal activity
			if(objects.length < 1) finishLevel(); //all objects are found
			var revealed = 0;
			if(levelMode=='word') {
				revealed = document.getElementsByClassName("word_mode_text_ltrought").length; 
			}else {
				$(".tick").each(function() { revealed += $(this).is(":visible") ? 1 : 0;});
			}
			var len = 0;
			if(levelMode=='bonus') {
				$(leftPrevs).each(function(index) { if(typeof(leftPrevs[index])!='undefined') ++len;});
				len-=objects.length;
			}else {
				len = leftPrevs.length - objects.length;
			}
			var turnOn = objects.length > 5 ? (revealed==0) : (len == revealed);
			//toggle button
			var selectors = ["#hint", "#pause_up", ".power_up:odd"];
			for(var i=0; i<selectors.length; ++i) {
				if($(selectors[i]).hasClass('disabled_button') || 
					$(selectors[i]).hasClass('enable_pe')) selectors.splice(i, 1); //remove it from selectors
			}
			if(sbTimer.hintTime > 0) {
				--sbTimer.hintTime;
				selector = "#pause_up, .power_up:odd";
			}
			if(turnOn) { //enable pointer events
				$(selectors.join()).removeClass('disable_pe').addClass('enable_pe');
			}else { //disable pointer events
				$("#hint, #pause_up, .power_up:odd").removeClass('enable_pe').addClass('disable_pe');
			}
		}else {
			if(sbTimer.callback != null) {
				sbTimer.callback(); //the callback calls sbTimer.stop();
			}else {
				sbTimer.stop();
			}
		}
	},
	interval : null,
	start : function() {
		if(sbTimer.isStarted) return;
		var func = sbTimer.once;
		sbTimer.isPaused = false;
		sbTimer.isStopped = false;
		sbTimer.isFreezed = false;
		sbTimer.isStarted = true;
		sbTimer.interval = setInterval(func, 1000);
	},
	pause : function() {
		clearInterval(sbTimer.interval);
		sbTimer.isStopped = false;
		sbTimer.isStarted = false;
		sbTimer.isPaused = true;
	},
	stop : function() {
		clearInterval(sbTimer.interval);
		sbTimer.callback = null;
		sbTimer.isPaused = false;
		sbTimer.isStarted = false;
		sbTimer.isStopped = true;
		sbTimer.isFreezed = false;
		sbTimer.hintTime = 0;
	},
	callback : null
};
//progress bar
var sbProgressBar = {
	progress : 0,
	max : 0,
	progressBar : null,
	ratio : 1,
	multiplier : null,
	isPaused : false,
	isStopped : true,
	isStarted : false,
	interval : null,
	once : function(flag) {
		if ( typeof (sbProgressBar.progressBar) == 'undefined' || typeof (sbProgressBar.multiplier) == 'undefined')
			return;
		//handle multiplier
		if (sbProgressBar.isPaused && sbProgressBar.ratio < 2)
			return;
		//no need to animate progress after pause when multiplier is 1x
		if (sbProgressBar.ratio < 12 && !flag)
			sbProgressBar.ratio++;
		//after pause we don't need to increase the multiplier
		sbProgressBar.multiplier.innerHTML = sbProgressBar.ratio + "x";
		//handle progress bar
		$(sbProgressBar.progressBar).css("width", ( flag ? sbProgressBar.progress : sbProgressBar.max) + 'px');
		//set max
		$(sbProgressBar.progressBar).animate({
			width : 0
		}, ( flag ? sbProgressBar.progress / sbProgressBar.max : 1) * 20000, sbProgressBar.stop);
		//animate 'till 0
	},
	pause : function() {
		sbProgressBar.progress = $(sbProgressBar.progressBar).width();
		$(sbProgressBar.progressBar).stop(true);
		//stop animation
		sbProgressBar.isStarted = false;
		sbProgressBar.isPaused = true;
	},
	start : function() {
		$(sbProgressBar.progressBar).stop(true);
		//stop animation
		var flag = sbProgressBar.isPaused && sbProgressBar.progress != 0;
		//start progress after pause
		sbProgressBar.once(flag);
		//if progress bar has paused we have to use other value for progres
		sbProgressBar.isPaused = false;
		sbProgressBar.isStopped = false;
		sbProgressBar.isStarted = true;
	},
	stop : function() {
		sbProgressBar.ratio = 1;
		$(sbProgressBar.progressBar).stop(null, false, true);
		//stop animation
		sbProgressBar.multiplier.innerHTML = sbProgressBar.ratio + "x";
		sbProgressBar.isPaused = false;
		sbProgressBar.isStarted = false;
		sbProgressBar.isStopped = true;
	}
};
//sound player
var soundPlayer = {
	start : function(tune) {
		if(!sound && tune != 6)	return;	//the sound is off
		var audio = document.getElementById("audio" + tune);
		if(audio != null) {
			if(audio.paused) { //unpause
				audio.play();
				return;
			}else if(tune == 1) return;
		}
		switch(tune) {
			case 1:
				audio = new Audio("res/sounds_changeable/theme.ogg");
				break;
			case 2:
				audio = new Audio("res/sounds_constant/locked.ogg");
				break;
			case 3:
				audio = new Audio("res/sounds_constant/click.ogg");
				break;
			case 4:
				audio = new Audio("res/sounds_constant/button_effect2.ogg");
				break;
			case 5:
				audio = new Audio("res/sounds_constant/whoosh.ogg");
				break;
			case 6:
				if(playedLevel!=0) audio = new Audio("res/sounds_changeable/Scene " + playedLevel + " Audio.ogg");
				break;
			case 7:
				audio = new Audio("res/sounds_constant/fail.ogg");
				break;
			case 8:
				audio = new Audio("res/sounds_constant/found.ogg");
				break;
			case 9:
				audio = new Audio("res/sounds_constant/hint.ogg");
				break;
			case 10:
				audio = new Audio("res/sounds_constant/tik.ogg");
				break;
			case 11:
				audio = new Audio("res/sounds_constant/tok.ogg");
				break;
			case 12:
				audio = new Audio("res/sounds_constant/level_failed.ogg");
				break;
			case 13:
				audio = new Audio("res/sounds_constant/victory.ogg");
				break;
			default:
				console.log("Wrong audio has chosen!");
		}
		audio.setAttribute("id", "audio" + tune);
		$("#include").before(audio);
		if (tune == 1) {
			audio.loop = true; //repeat on
		}else if(tune == 6) {
			audio.addEventListener('ended', function() {
				soundPlayer.start(1); //resume theme sound
				$(audio).remove();
			});
		}else if(tune == 13) {
			audio.addEventListener('ended', function() {
				soundPlayer.start(1); //resume theme sound after score tick sound is finished
				$(audio).remove();
			});
		}else {
			audio.addEventListener('ended', function() {
				$(audio).remove();
			});
			//remove cloned nodes
		}
		audio.play();
		if(tune==6 && !narration) soundPlayer.mute(6, true); //check is narration off
	},
	pause : function(tune) {
		var audio = document.getElementById("audio" + tune);
		if (audio != null)
			audio.pause();
	},
	stop : function(tune) {
		var audio = document.getElementById("audio" + tune);
		if (audio != null) {
			$(audio).remove();
		}
	},
	mute : function(tune, flag) {
		var audio = document.getElementById("audio" + tune);
		if (audio != null) audio.muted = flag;
	}
};
//animations
function frame(animation, position, width, height, frameX, frameY) {
	if (frameX != 'undefined' && frameY != 'undefined') {
		animation.css({
			"background-position" : position,
			"width" : width,
			"height" : height,
			"margin-left" : frameX,
			"margin-top" : frameY
		});
	} else {
		animation.css({
			"background-position" : position,
			"width" : width,
			"height" : height
		});
	}
}

function getFrames(doc, tag, isFull) {
	var xhttp;
	if (window.XMLHttpRequest) {
		xhttp = new XMLHttpRequest();
		try {
			xhttp.open("GET", doc, false);
			xhttp.send();
			var arr = new Array();
			var xml = xhttp.responseXML;
			var el = xml.getElementsByTagName(tag);
			for (var i = 0; i < el.length; i++) {
				var map = {};
				map.x = (-1 * el.item(i).getAttributeNode('x').value) + 'px';
				map.y = (-1 * el.item(i).getAttributeNode('y').value) + 'px';
				map.width = (el.item(i).getAttributeNode('width').value) + 'px';
				map.height = (el.item(i).getAttributeNode('height').value) + 'px';
				if (isFull) {
					map.frameX = (-1 * el.item(i).getAttributeNode('frameX').value) + 'px';
					map.frameY = (-1 * el.item(i).getAttributeNode('frameY').value) + 'px';
				}
				arr[i] = map;
			}
			return arr;
		} catch (e) {
			console.log(e);
		}
	}
}
//hint animation
function animateHint(hint, obj) {
	var normalizeHint = function() { $(hint).attr("class", "hint_animation").parent().removeAttr('style');};
	$(hint).off().on('tap', function() {
		setTimeout(normalizeHint, 2000); //because of triggering the click event the class of hint is changed
		$(obj).trigger('tap'); //find the object
	}).addClass('h_blinking');
	setTimeout( normalizeHint, 8000);
}

//found animation
function animateFound(animation, holder) {
	$(animation).addClass('f_blinking');
	setTimeout(function() { $(holder).remove(); }, 1500);
}
//printer
function printPages() {
	var count = 0;
	var len = wordLevels.length;
	if (levelMode == 'word') {
		if (skin == 'blue') {
			count = Math.ceil((len % 2 == 0 ? len + 2 : len) / 14);
			//blue skin
		} else {
			count = Math.ceil((len % 2 == 0 ? len + 2 : len) / 10);
			//steampunk
		}
	} else if (levelMode == 'image') {
		if (skin == 'blue') {
			count = Math.ceil((len % 2 == 0 ? len + 2 : len) / 14);
			//blue skin
		} else {
			count = Math.ceil((len % 2 == 0 ? len + 2 : len) / 10);
			//steampunk
		}
	} else {
		if (skin == 'blue') {
			count = Math.ceil((len % 2 == 0 ? len + 2 : len) / 14);
			//blue skin
		} else {
			count = Math.ceil((len % 2 == 0 ? len + 2 : len) / 10);
			//steampunk
		}
	}
	if (skin == 'blue') {
		$("#pager").css("width", ((count + 2) * 5) + "%");
		//align page dots, 10%, 15%, 20% etc.
	} else {
		$("#pager").css("width", ((count + 2) * 5 - 1.5) + "%");
		//align page dots, 8%, 13%, 18% etc.
	}
	for (var i = 1; i <=(count > 0 ? count : 1); ++i) {
		printPage("#go_right", i);
	}
	$("#pager").show();
	pagesPos(count, skin);
}

function printPage(bef, n) {
	var div = document.createElement("div");
	var text = document.createElement("div");
	$(text).attr({
		"id" : "page_num",
		"class" : "text"
	});
	text.innerHTML = n;
	var page = document.createElement("img");
	$(page).attr({
		"src" : "res/assets/common/pager_dot.png",
		"class" : "page"
	});
	if (n != 1) {
		$(text).hide();
	}
	$(bef).before(div);
	$(div).prepend(page, text);
}

//handle pager size
function pagesPos(count, skin) {
	var margin = skin == 'blue' ? '-19.5%' : '-18%';
	switch(count) {
		case 1:
			margin;
			break;
		case 2:
			margin = (parseFloat(margin) + 4) + '%';
			break;
		default:
			margin = (parseFloat(margin) + 1 + 2 * count) + '%';
			break;
	}
	changeCSS("#page_num", "margin-left", margin);
}

function printStars() {
	var text = document.createElement("div");
	$(text).attr({
		"id" : "stmpunk",
		"class" : "text"
	});
	var wonStars = 0;
	var maxStars = 0;
	//get won stars
	for (var i = 0; i < wordLevels.length; i++) {
		if (wordLevels[i] > -2)
			maxStars += 3;
		//-1 can be unlocked, but -2 can not
		if (wordLevels[i] > 0)
			wonStars += wordLevels[i];
		if (imageLevels[i] > 0)
			wonStars += imageLevels[i];
		if (bonusLevels[i] > 0)
			wonStars += bonusLevels[i];
		if (wordLevels[i] < -1 && imageLevels[i] < -1 && bonusLevels[i] < -1)
			break;
		//all other levels are locked
	}
	text.innerHTML = wonStars + "/" + maxStars * 3;
	//max stars *3 because we have 3 modes with equal number of levels
	$("#stars_won").show().after(text);
}

function syncOptions() {
	$("#sound_on").attr("id", ( sound ? "sound_on" : "sound_off"));
	$("#narration_on").attr("id", ( narration ? "narration_on" : "narration_off"));
}

//print levels in slider
function printLevels() {
	var levels = [];
	if(levelMode == 'word') {
		levels = wordLevels;
	}else if (levelMode == 'image') {
		levels = imageLevels;
	}else {
		levels = bonusLevels;
	}
	//calc number of levels on row
	var maxLevels = Math.ceil((levels.length + 1) / 2);
	//make slider enought long
	if (skin == 'blue') {
		//183px for each level box blue skin or at least screen width
		$("#slider").css("width", (maxLevels * 183 > $("#wrapper").width() ? maxLevels * 183 : $("#wrapper").width()) + 'px');
	} else {
		//252px for each level box steampunk or at least screen width
		$("#slider").css("width", (maxLevels * 252 > $("#wrapper").width() ? maxLevels * 252 : $("#wrapper").width()) + 'px');
	}
	//print levels on slider
	for (var i = 0; i < levels.length; i++) {
		printLevelBox(i, levels[i], skin);
	}
	//print last box - "get all levels"/"comming soon"
	var last = document.createElement("div");
	$(last).attr("class", "level_box").on('tap', getAll);
	$("#slider").append(last);
	//last label
	var hiddenLabel = document.createElement("div");
	$(hiddenLabel).attr({
		"id" : "label",
		"class" : "text"
	}).css("visibility", "hidden");
	hiddenLabel.innerHTML = (levelMode != 'bonus') ? "level" : "bonus";
	//last preview
	var preview = document.createElement("div");
	preview.className = "level_preview";
	if (isPaid) {
		$(preview).css("background", "url('res/assets/common/coming_soon.png') no-repeat 50% 50%");
		//steampunk
	} else {
		$(preview).css("background", "url('res/assets/common/buy_full.png') no-repeat 50% 50%");
	}
	$(preview).css("background-size", "85%");
	//make orb
	if (skin == 'stmpunk') {
		//print orb
		var orb = document.createElement("div");
		orb.className = "level_orb";
		$(preview).append(orb);
	}
	//append all into the last box
	$(last).append(hiddenLabel, preview);
	$("#slider").show();
}

function printLevelBox(i, stars, skin) {
	//make level box
	var box = document.createElement("div");
	$(box).attr("class", "level_box").on('tap', {lvl : i}, tryStartLevel);
	$("#slider").append(box);
	//make label
	var label = document.createElement("div");
	$(label).attr({
		"class" : "text_regular",
		"id" : "label"
	});
	label.innerHTML = (levelMode == 'bonus' ? "bonus " : "Level ") + (i + 1);
	//make preview
	var prev = document.createElement("div");
	prev.className = "level_preview";
	if(stars >= 0) { //unlocked level
		$(prev).css("background", "url('res/levels/level_" + (i + 1) + "/preview.jpg') no-repeat 50% 50%");
	}else { //locked level
		$(prev).css("background-size", "85%");
	}
	if (skin == 'stmpunk') {
		//print orb
		var orb = document.createElement("div");
		orb.className = "level_orb";
		$(prev).append(orb);
	}
	//make stars
	var levelStars = [];
	for (var j = 0; j < 3; j++) {
		levelStars[j] = document.createElement("img");
		levelStars[j].className = "stars";
		if (stars > j) {
			levelStars[j].setAttribute("src", "res/assets/common/star_full.png");
		} else {
			levelStars[j].setAttribute("src", "res/assets/common/star_empty.png");
		}
	}
	//make bonus cup
	var cup = null;
	if (levelMode == 'bonus') {
		cup = document.createElement("div");
		cup.className = "bonus_cup";
	}
	//append all as level box
	$(box).append(label, prev, levelStars, cup);
}

function tryStartLevel(evn) {
	if(canSlide) startLevel(evn);
}

function printScore() {
	soundPlayer.start(13);
	//play sound
	var spans = document.getElementsByClassName("text_green");
	var spansVal = [];
	//level_bonus, time_bonus, score
	spansVal[0] = playedLevel * 200;
	spansVal[1] = sbTimer.time * 4;
	spansVal[2] = currentScore + spansVal[0] + spansVal[1];
	currentScore = 0;
	//save levelsScore into localStorage
	if (levelsScore[levelMode][playedLevel - 1] < spansVal[2]) {
		levelsScore[levelMode][playedLevel - 1] = spansVal[2];
		changeLS('levelsScore["' + levelMode + '"]', levelsScore[levelMode]);
		//write the whole array, no other way
		setTimeout(function() {
			$("#high_score").animate({
				opacity : 1
			}, "slow");
		}, 1000);
	}
	//play score sound
	for (var i = 0; i < spans.length; i++) {
		$(spans[i]).animate({
			borderSpacing : spansVal[i]
		}, {
			step : function(now, fx) {
				this.innerHTML = now.toFixed(0);
			},
			duration : 3500
		}, "linear");
	}
	//resume theme sound
}

function spinStars() {
	//calc stars
	var allTime = tsi['time'];
	var stars = 0;
	if (levelMode != 'bonus') {
		if (sbTimer.time > allTime/2) {
			$("#complete_label").attr("class", "wow_genius");
			stars = 3;
		} else if (sbTimer.time > allTime/4) {
			$("#complete_label").attr("class", "truly_brainy");
			stars = 2;
		} else {
			$("#complete_label").attr("class", "very_smart");
			stars = 1;
		}
	} else {
		if (sbTimer.time > allTime/2) {
			$("#complete_label").attr("class", "wow_genius");
			stars = 3;
		} else if (sbTimer.time > allTime/4) {
			$("#complete_label").attr("class", "truly_brainy");
			stars = 2;
		} else {
			$("#complete_label").attr("class", "very_smart");
			stars = 1;
		}
	}
	//save won stars if they are more than before. Save them into localStorage
	if (levelMode == 'word' && wordLevels[playedLevel - 1] < stars) {
		wordLevels[playedLevel - 1] = stars;
		changeLS('wordLevels', wordLevels);
	} else if (levelMode == 'image' && imageLevels[playedLevel - 1] < stars) {
		imageLevels[playedLevel - 1] = stars;
		changeLS('imageLevels', imageLevels);
	} else if (bonusLevels[playedLevel - 1] < stars) {
		bonusLevels[playedLevel - 1] = stars;
		changeLS('bonusLevels', bonusLevels);
	}
	//handle spinning
	$("#stars_holder").animate({
		marginTop : 0
	}, "medium", function() {
		if(skin == 'blue') soundPlayer.start(5);
		//play sound
		var spinDivs = document.getElementsByClassName("stars_received");
		var starsArr = document.getElementsByClassName("spining_star");
		for(var i = 0; i < stars; i++) {
			if(skin != 'blue') starsArr[i].src = starsArr[i].src.replace("common", "levelComplete");
			$(spinDivs[i]).show();
			$(starsArr[i]).animate({
				width : '100%',
				marginTop : 0,
				borderSpacing : 3600
			}, {
				step : function(now, fx) {
					$(this).css("transform", "rotate(" + now + "deg)");
				},
				duration : "slow"
			}, "linear");
		}
		if(stars == 3) {//add reward power up
			var earned = document.getElementById("earned").getElementsByTagName("span")[0];
			var reward = getRandomPowerUp();
			if(reward.name) { //we have a reward
				$("#earned").delay(500).fadeIn("slow");
				earned.innerHTML = reward.label;
				powerUps[reward.name]++;
				changeLS('powerUps["' + reward.name + '"]', powerUps[reward.name]);
			}
		}
	});
}

function getRandomPowerUp() {
	var random = Math.floor(Math.random() * 3);
	var pUp = {
		name: null,
		label: null
	};
	switch(random) {
		case 0:
			pUp.label = "Freeze Powerup!";
			pUp.name = "freeze";
			break;
		case 1:
			pUp.label = "Reveal Powerup!";
			pUp.name = "reveal";
			break;
		case 2:
			pUp.label = "Locate Powerup!";
			pUp.name = "locate";
			break;
		default:
			console.log("Random powerup:" + random + " out of range!");
	}
	return pUp;
}

//slider
var canSlide = true;
var current = 1;

//slider methods
function slideNext() {
	var pages = $("[id='page_num']");
	var left = parseFloat($("#slider").css("left"));
	var lines = getPageChangeLines();
	if (canSlide && current < lines.length && left > lines[lines.length - 1]) {
		canSlide = false;
		$("#slider").animate({left : lines[current] + 'px'}, "slow", function() {
			canSlide = true;
			if (current < pages.length) {
				$(pages[current - 1]).hide();
				$(pages[current]).show();
				++current;
			}
		});
	} else {
		$("#slider").animate({left : lines[lines.length - 1] + "px"}, "slow"); //go to last page
	}
}

function slidePrevious() {
	var pages = $("[id='page_num']");
	var left = parseFloat($("#slider").css("left"));
	var lines = getPageChangeLines();
	if (canSlide && current > 1 && left < 0) {
		canSlide = false;
		var distance = lines[current - 2] != lines[0] ? lines[current - 2] : 0;
		//check if we go to the first page
		$("#slider").animate({left : distance + "px"}, "slow", function() {
			canSlide = true;
			if (current > 1) {
				$(pages[current - 1]).hide();
				--current;
				$(pages[current - 1]).show();
			}
		});
	} else {
		$("#slider").animate({left : "0px"}, "slow"); //go to first page
	}
}

//handle page change
function getPageChangeLines() {
	var pages = document.getElementsByClassName("page").length;
	//get center lines
	var sl = $("#slider").width();
	var scr = $("#wrapper").width();
	var lines = [];
	for (var i = 0; i < pages; i++) {
		if (sl > scr) {
			lines[i] = Math.floor(-1 * (i + 1) * (sl - scr) / pages);
		} else {
			lines[i] = scr;	//screen width
		}
	}
	return lines;
}

function handlePageChange(lines, pos) {
	var pages = $("[id='page_num']");
	if (pos < lines[current - 1] && current < lines.length) {
		$(pages[current - 1]).hide();
		$(pages[current]).show();
		current++;
	} else if (current > 1) {
		if (pos > lines[current - 2]) {
			$(pages[current - 1]).hide();
			current--;
			$(pages[current - 1]).show();
		}
	}
}

function handleSlide() {
	var lines = getPageChangeLines();
	//vars for animating on mouse up/touch end
	var startTime = 0;
	var direction = 'n'; //neutral direction
	var prevPoint = null;
	var startP = 0; //start point
	var endP = 0; //end point
	//check for direction change to handle right the distance
	var prepareSlideEnd = function(currPoint) {
		if(prevPoint == null) { //first time call of this function
			prevPoint = currPoint;
			return;
		}
		var currDir = direction; //current direction
		if(currPoint > prevPoint) {
			direction = 'r'; //right
		}else if(currPoint < prevPoint) {
			direction = 'l'; //left
		}else {
			direction = 'n'; //neutral
		}
		if(currDir != direction) {
			startP = currPoint; //start point is new
			startTime = Date.now();
		}
		endP = currPoint; //last event position
		prevPoint = currPoint;
	};
	//handle events
	if('ontouchstart' in window) {
		var slider = document.getElementById("slider");
		var touch = null;
		var startPoint = null;
		var left = null;
		//handlers
		var touchMove = function(e) {
			if(e.targetTouches.length == 1) {
				touch = e.targetTouches[0];
				var distance = (startPoint - touch.pageX);
				prepareSlideEnd(touch.pageX);
				//move slider
				$("#slider").stop(true).css({left : (left - distance) + 'px'});
			}
		};
		var touchStart = function(e) {
			if(e.targetTouches.length == 1) {
				startTime = Date.now();
				touch = e.targetTouches[0];
				startPoint = touch.pageX;
				left = parseFloat($("#slider").css("left"));
				slider.addEventListener('touchmove', touchMove, false);
			}
		};
		var touchEnd = function(e) {
			slider.removeEventListener('touchmove', touchMove);
			var speed = (((startP - endP)/(Date.now() - startTime))*100).toFixed(2);
			if(startP != endP) e.stopPropagation(); //prevent click when sliding
			slidePage(speed, lines);
			direction = 'n'; //neutrall direction
			startP = 0;
			endP = 0;
		};
		//add listeners
		slider.addEventListener('touchstart', touchStart, false);
		slider.addEventListener('touchend', touchEnd, false);
	}else {
		$("#slider").on('mousedown', function(e) {
			startTime = Date.now();
			var startPoint = e.pageX;
			var left = parseFloat($("#slider").css("left"));
			$("#wrapper").on('mousemove', function(evn) {
				var distance = (startPoint - evn.pageX);
				prepareSlideEnd(evn.pageX);
				//move slider
				$("#slider").stop(true).css({left : (left - distance) + 'px'});
			});
		}).on('mouseup mouseleave', function(e) {
			$("#wrapper").off("mousemove");
			var speed = (((startP - endP)/(Date.now() - startTime))*100).toFixed(2);
			if(startP != endP) e.stopPropagation(); //prevent click when sliding
			slidePage(speed, lines);
			direction = 'n'; //neutrall direction
			startP = 0;
			endP = 0;
		});
	}
}

function slidePage(speed, lines) {
	var curr = parseFloat($("#slider").css("left"));
	var min = $("#wrapper").width() - $("#slider").width(); //max is 0
	if(Math.abs(speed) <= 75) { //min speed required
		returnToNormal(lines, curr, min);
		return;
	}
	$("#slider").stop(true).animate({
		left: curr - speed*(Math.abs(speed)/50) //till 20 times faster, depends of the swipe speed
	},
	{
		duration: 400,
		step: function(now) {
			if(now < min || now > 0) $(this).stop(true); //stop the animation
			returnToNormal(lines, now, min);
		}
	});
}
function returnToNormal(lines, curr, min) {
	if (curr < min) {
		$("#slider").stop(true, false).animate({left : min + 'px'}, "medium");
	} else if (curr > 0) {
		$("#slider").stop(true, false).animate({ left : '0px'}, "medium");
	}
	//handle page change
	handlePageChange(lines, curr);
	//lock start level when sliding
	setTimeout(function() {canSlide = true;}, 500);
}

//gameplay
var tsi = {};
var penalty = 0;
var objects = [];

function loadLevel() {
	$(".hint_animations_place").before('<img id="level_content" src="res/levels/level_' + playedLevel + '/background.jpg"/>');
	$("#level_title").text((levelMode != 'bonus' ? 'Level ' : 'Bonus ') + playedLevel);
	tsi = getTimeSoundIntro();
	loadSideBar();
	loadPowerUps();
	soundPlayer.pause(1);
	//pause theme sound
	if(sbTimer.isPaused && levelMode != 'bonus') {
		playLevel();
	}else if (levelMode == 'bonus') {
		playLevel();
		soundPlayer.start(1); //resume theme sound
	}else {
		writeNarration(0);
	}
}

function handlePenalties(x, y, obj) {
	//if user clicks on locate dialog or magnifier icon it should not be a penalty
	if(obj == document.getElementById("magnifier_icon") || obj.className == "hint_animation h_blinking") return;
	var content = {
		x : parseInt($("#level_content").css("left")),
		y : parseInt($("#level_content").css("top"))
	};
	if(x >= content.x * scl && y >= content.y * scl) {
		var prev = null;
		if(obj.className == "object_img") obj = obj.parentNode;
		if(levelMode != 'bonus') {
			prev = getPreview(obj);
		} else {
			prev = getLetterPreview(obj);
		}
		if(prev == null) {
			++penalty;
			if (penalty - 4 == 0) {
				if (sbTimer.time > 9) {
					sbTimer.time -= 1;
				} else {
					sbTimer.time = 0;
				}
				penalty -= 4;
				soundPlayer.start(7); //play sound
				//show -10 label
				var div = document.createElement("div");
				$(div).attr({
					"id" : "penalty",
					"class" : "text_regular"
				});
				div.innerHTML = -1;
				$(div).css({
					"top" : y / scl + 'px',
					"left" : x / scl + 'px'
				});
				$("#items_container").after(div);
				$(div).fadeOut(1000, function() {
					$(this).remove();
				});
			}
		} else {
			penalty = 0;
		}
	}else {
		penalty = 0;
	}
}

function loadSideBar() {
	sbTimer.timer = document.getElementById("timer");
	sbProgressBar.progressBar = document.getElementById("progress_bar");
	sbProgressBar.multiplier = document.getElementById("multiplier");
	sbProgressBar.max = $("#white_rect").width() - 5;
	if (sbTimer.isStopped) {//the timer has never been started
		objects = getLevelObjects()[(levelMode != 'bonus' ? 'objects' : 'letters')];
		sbTimer.time = tsi['time'];
		sbTimer.callback = levelMode != 'bonus' ? levelFailed : finishLevel;
		sbTimer.once();
	} else {
		sbTimer.time;
		sbTimer.once();
	}
	setObjects();
}

function loadPowerUps() {
	//check here for localStorage and if there is no value set 1 to all power-ups
	var powerUpsObj = document.getElementsByClassName("power_up");
	//place the rest of powerups
	$(powerUpsObj[1]).css("top", skin=='blue' ? 465 + 'px' : 482 + 'px');
	$(powerUpsObj[2]).css("top", skin=='blue' ? 525 + 'px' : 544 + 'px');
	//sync count
	powerUpsObj[0].childNodes[0].innerHTML += powerUps.freeze;
	powerUpsObj[1].childNodes[0].innerHTML += powerUps.reveal;
	powerUpsObj[2].childNodes[0].innerHTML += powerUps.locate;
	if (powerUps.freeze == 0)
		disableBtn(powerUpsObj[0], 0, null);
	if (powerUps.reveal == 0)
		disableBtn(powerUpsObj[1], 0, null);
	if (powerUps.locate == 0)
		disableBtn(powerUpsObj[2], 0, null);
}

//setting objects methods
function setObjects() {
	var tds = document.getElementsByTagName("td");
	if (levelMode != 'bonus' && document.getElementsByTagName("td").length < 6) {
		makeTable();
	} else if (document.getElementsByTagName("td").length < 6) {
		makeBonusTable();
	}
	//set previews
	for (var i = 0; i < leftPrevs.length; i++) {
		if (levelMode != 'bonus') {
			$(tds[i]).append(leftPrevs[i]);
		} else {//show ticks on bonus mode
			if (leftPrevs[i] != null)
				showLetter(leftPrevs[i].getAttribute("name"), leftPrevs[i].innerHTML);
		}
	}
	//set objects
	for (var i = 0; i < objects.length; i++) {
		var map = getObjAttributes(i);
		setObject(map['id'], map['imageSrc'], map['previewSrc'], map['literal'], map['x'], map['y'], map['width'], map['height'], map['childIndex']);
	}
	//fill word holder
	if (levelMode == 'bonus') {
		var word = document.getElementById("bonus_word_holder");
		var letters = [];
		for (var i = 0; i < tds.length; i++) {
			if (tds[i].childNodes.length < 2) {
				if(tds[i].className != "bonus_word_holder") {
					if((skin!='blue' && $(tds[i]).css("visibility")!='hidden') || skin=='blue') $(tds[i]).hide();
				}
			} else {
				var id = tds[i].childNodes[1].getAttribute("name").split("_");
				//letter and number
				letters[id[1] - 1] = (skin == 'stmpunk' ? id[0].toUpperCase() : id[0]);
				if (document.getElementById(leftPrevs[i].getAttribute("name")) == null)
					$(leftPrevs[i]).prev().show();
			}
		}
		//build word
		for (var i = 0; i < letters.length; i++)
			if (letters[i] != null)
				word.innerHTML += letters[i];
	} else if (objects.length < 7 && levelMode == 'image') {
		for (var i = 0; i < leftPrevs.length; i++) {
			if (getObjectByPreview(leftPrevs[i]) == null)
				$(tds[i].childNodes[0]).show();	//show tick
		}
	}
	//place all elements in magnifier
	var content = document.getElementById("items_container").cloneNode(true);
	content.id = "magnifier_container";
	content.style.backgroundImage = "url(" + $("#level_content").attr("src") + ")";
	$("#mg_glass").append(content);
	//fix objects size
	$("#magnifier_container > .obj_div").each(function() {
		var img = document.getElementById(this.id);
		$(this).css({
			"width" : $(this).width() + 'px',
			"height" : $(this).height() + 'px',
			"top" : parseFloat($(this).css("top")) + 'px',
			"left" : parseFloat($(this).css("left") + 273) + 'px'
		}).on('tap', {obj : img}, found);
	});
}

function getObjAttributes(i) {
	var attrMap = {};
	attrMap['id'] = objects[i].getAttributeNode("id").value;
	attrMap['imageSrc'] = objects[i].getAttributeNode("imageSrc").value;
	attrMap['previewSrc'] = objects[i].getAttributeNode("previewSrc").value;
	attrMap['literal'] = objects[i].getAttributeNode("literal").value;
	attrMap['x'] = (1 * objects[i].getAttributeNode("x").value) + "px";
	attrMap['y'] = (1 * objects[i].getAttributeNode("y").value) + "px";
	attrMap['width'] = objects[i].getAttributeNode("width").value + "px";
	attrMap['height'] = objects[i].getAttributeNode("height").value + "px";
	attrMap['childIndex'] = objects[i].getAttributeNode("childIndex").value;
	return attrMap;
}

function setObject(id, imageSrc, previewSrc, literal, x, y, width, height, childIndex) {
	//create object if not exist
	if(document.getElementById(id) == null) {
		var iwidth = Math.floor(parseFloat(width) * 1.07); //scale images here instead in the xml
		var iheight = Math.floor(parseFloat(height) * 1.07);
		//prepare holder
		var holder = document.createElement("div");
		$(holder).on('tap', {obj: holder}, found).css({
				"width": (iwidth < 60 ? 60 : iwidth) + 'px',
				"height": (iheight < 60 ? 60 : iheight) + 'px',
				"top" : parseFloat(y) * 1.07 + 'px',
				"left" : (parseFloat(x) * 1.07 + 597) + 'px' //for steampunk
			}).attr({"id" : id, "class": "obj_div"});
		//prepare image
		var img = document.createElement("img");
		$(img).css({"width" : iwidth + 'px', "height" : iheight + 'px'})
		.attr({"class" : "object_img", "src" : imageSrc});
		//add image to holder
		$(holder).append(img);
		$("#items_container").prepend(holder);
	}
	//create preview in the side bar
	if (levelMode == 'image') {
		showPreview(childIndex, previewSrc, imageSrc, width, height);
	} else if (levelMode == 'word') {
		showWord(childIndex, literal);
	} else {
		showLetter(id, literal);
	}
}

//remove objects
function removeObject(obj) {
	if(objects.length < 1)	return;
	var id = obj.id;
	for(var i = 0; i < objects.length; i++) {
		if(objects[i].getAttributeNode("id").value == id) {
			$(obj).remove();
			$("#magnifier_container > #" + id).remove();
			$(objects[i]).remove();
			return;
		}
	}
}
//handle previews
function showPreview(index, src, altSrc, w, h) {
	var tds = document.getElementsByTagName("td");
	var img = document.createElement("img");
	$(img).attr({
		"src" : src,
		"id" : index
	});
	w = parseInt(w);
	h = parseInt(h);
	if (70 * h / w > 70) {//h > 70 when w = 70, used to set size of previews
		w = (w / h) * 70;
		h = 70;
	} else {
		h = 70 * h / w;
		w = 70;
	}
	$(img).attr({
		"width" : w + 'px',
		"height" : h + 'px'
	}).css("display", "none");
	for (var i = 0; i < tds.length; i++) {
		if (tds[i].childNodes.length < 2) {
			$(tds[i]).append(img);
			$(img).load(function() {
				$(img).show();
			}).error(function() {
				img.src = altSrc;
			});
			leftPrevs[i] = img; //save into previews
			break;
		}
		//fix ticks position
		if (skin == 'stmpunk') {
			$(tds[i].firstChild).css("top", (12 + Math.floor(i / 2) + Math.floor(i / 2) * 100) + 'px');
			//14px - 121px - 228px
			if (i % 2 != 0)
				$(tds[i].firstChild).css("margin-left", "-6px");
		} else {
			$(tds[i].firstChild).css("top", (5 + Math.floor(i / 2) * 100) + 'px');
			//5px - 105px - 205px
		}
	}
}

function showWord(index, word) {
	var tds = document.getElementsByTagName("td");
	//get all 6 tds
	var div = document.createElement("div");
	$(div).attr({
		"class" : "word_mode_text",
		"id" : index
	});
	div.innerHTML = word;
	for (var i = 0; i < tds.length; i++) {
		if (tds[i].childNodes.length < 2) {
			$(tds[i]).append(div);
			leftPrevs[i] = div;	//save into previews
			break;
		}
	}
}

function showLetter(id, letter) {
	var tds = document.getElementsByTagName("td");
	//get all tds
	var div = document.createElement("div");
	$(div).attr({
		"class" : "text",
		"id" : "letter",
		"name" : id
	});
	id = parseInt(id.split("_")[1]);
	div.innerHTML = (skin == 'stmpunk' ? letter.toUpperCase() : letter);
	var num = null;
	var mleft = null;
	if (skin == 'stmpunk') {
		if (id < 5) {
			num = (id - 1) * 3;
			$(div).css("left", "12px");
			mleft = "16px";
		} else if (id > 4 && id < 9) {
			num = (id - 5) * 3 + 1;
			mleft = "6px";
		} else {
			num = (id - 9) * 3 + 2;
			$(div).css("right", "12px");
			mleft = "-6px";
		}
	} else {
		switch(id) {
			case 1:	num = 0; break;
			case 2:	num = 2; break;
			case 3:	num = 4; break;
			case 4:	num = 6; break;
			case 5:	num = 1; break;
			case 6:	num = 3; break;
			case 7:	num = 5; break;
			case 8:	num = 7; break;
		}
	}
	if(tds[num].childNodes.length < 2) {
		$(tds[num]).css("visibility", "visible"); //show the td
		$(tds[num]).append(div);
		leftPrevs[num] = div;
		if(skin == 'stmpunk') {
			$(tds[num].firstChild).css("margin-left", mleft);
		}
	}
}

//make tables (previews table)
function makeTable() {
	var trs = document.getElementsByTagName("tr");
	if (levelMode == 'image') {
		document.getElementsByTagName("table")[0].className = "items_holder";
		for (var i = 0; i < 3; i++) {//make 3 new td, now the tds are 6 as they should be
			var td = document.createElement("td");
			$(trs[i]).append(td);
			$(td).append('<div class="tick"></div>');
		}
	} else if (levelMode == 'word') {
		var table = document.getElementsByTagName("table")[0];
		table.className = "words_holder";
		for (var i = 0; i < 3; i++) {//make 3 new rows with tds
			var tr = document.createElement("tr");
			var td = document.createElement("td");
			$(trs[i]).after(tr);
			$(tr).append(td);
			$(td).append('<div class="tick"></div>');
		}
	}
}

function makeBonusTable() {
	var trs = document.getElementsByTagName("tr");
	var table = document.getElementsByTagName("table")[0];
	table.className = "letters_holder";
	//ad 4th td
	var tr = document.createElement("tr");
	$(trs[trs.length - 1]).after(tr);
	var td = document.createElement("td");
	$(tr).append(td);
	$(td).append('<div class="tick"></div>').css("visibility", "hidden");
	//in bonus mode we can have up to 4 rows and the objects fills by row
	if (objects.length >= 4 || leftPrevs.length >= 4) $(td).css("visibility", "visible");
		
		for (var i = 0; i < trs.length; i++) {
			td = document.createElement("td");
			$(trs[i]).append(td);
			$(td).append('<div class="tick"></div>');
			if(skin == 'stmpunk') { //make one more column
				$(td).css("visibility", "hidden");
				td = document.createElement("td");
				$(td).css("visibility", "hidden");
				$(trs[i]).append(td);
				$(td).append('<div class="tick"></div>');
			}else if(skin=='blue' && objects.length > 4){
				changeCSS("table.letters_holder", "left", "90px");
			}
		}
	
	//add field for whole word
	var div = null;
	if (skin == 'stmpunk') { //make word as td
		div = document.createElement("td");
		$(div).attr({
			"class" : "bonus_word_holder",
			"colspan" : "3"
		});
		tr = document.createElement("tr");
		//make new row for it
		$(trs[trs.length - 1]).after(tr);
		$(tr).append(div);
	} else {
		div = document.createElement("div");
		div.className = "bonus_word_holder";
		$(table).after(div);
	}
	var text = document.createElement("div");
	$(text).attr({
		"id" : "bonus_word_holder",
		"class" : "text_regular"
	});
	$(div).append(text);
	text.innerHTML = "";
}

//handle narration
function writeNarration(paragraph) {
	$("#include").css("opacity", 1);
	var dialogue = document.getElementById("dialogue_content");
	var start = document.getElementById("start");
	var back = document.getElementById("back_arrow");
	var close = document.getElementById("dialogue_close");
	var text = $(tsi['intro'][paragraph]).text();
	if (text.split(".").length <= 2) {
		text = "</br>" + text;
	} else {
		var arr = text.split(".");
		text = "";
		if (arr.length > 2) {
			for (var i = 0; i < arr.length; i++) {
				if (i == Math.floor(arr.length / 2)) {
					if(i>0) {
						if(arr[i-1].indexOf("Dr")<0) text += "<br/></br>";
					}
				}
				text += arr[i] + (i < arr.length - 1 ? "." : "");
			}
		}
	}
	dialogue.innerHTML = text;
	$(close).off().on('tap', playLevel);
	if (tsi['intro'].length == 1) {
		$(back).hide();
		$(start).attr("class", "dialogue_start").off().on('tap', playLevel);
	} else {
		if(paragraph == 0) {
			$(back).hide();
		}else {
			$(back).show();
		}
		$(back).off().on('tap', function() {
			changeIntro(false, paragraph);
		});
		if(tsi['intro'].length - 1 > paragraph) { //we are not on the last page
			$(start).attr("class", "dialogue_arrow").off().on('tap', function() {
				changeIntro(true, paragraph);
			});
		}else { //we are on the last page
			$(start).attr("class", "dialogue_start").off().on('tap', playLevel);
		}
	}
	//show the screen
	setTimeout(function() {
		$("#dialogue").animate({opacity: 1}, "slow");
		$("#dark_screen, #loading_bar").hide();
	}, 3000);
}

function changeIntro(flag, paragraph) {
	if (flag) {
		++paragraph;
	} else {
		if (paragraph > 0)
			--paragraph;
	}
	writeNarration(paragraph);
}

//play, pause, exit, etc.
function playLevel() {
	var doPlay = function(flag) {
		$("#dialogue_screen").css("visibility", "hidden");
		if(flag) $("#dark_screen, #loading_bar").show();
		$("#gameplay_content").on('tap', function(e, ex, ey) { //handle click
			handlePenalties(ex, ey, e.target);
		});
		$("#include").css("opacity", 1);
		setTimeout(function() {
			//start timer after the screen is visible
			setTimeout(function() { //countinue freezing timer if it had been freezed
				if(levelMode!='bonus') soundPlayer.start(6); //start or unpause narration
				sbTimer.start();
				$("#freeze_rect").hide();
				if (sbProgressBar.isPaused)
					sbProgressBar.start();
			}, (sbTimer.isFreezed ? sbTimer.freezeTimeout : 0));
			//make the screen visible
			$("#gameplay_content").animate({opacity: 1}, "slow");
			$("#dark_screen, #loading_bar").hide();
		}, 2000);
		if(sbTimer.isFreezed) { //show freezing rect and show progress bar
			$("#freeze_rect").show();
			$("#progress_bar").css("width", sbProgressBar.progress + 'px');
		}
		if(sbTimer.hintTime!=0) disableBtn("#hint", sbTimer.hintTime, null); //disable hint if it needs
		document.getElementById("score").innerHTML = currentScore;
	};
	if(levelMode == 'bonus' || sbTimer.isPaused) {
		$("#dark_screen, #loading_bar").show();
		//check are the images ready
		var imgReady = 1;
		var imgs = $(".object_img");
		//all images
		var checkReady = function() {
			if (imgReady == 0) {
				//everything is ready
				doPlay(false);
			}
		};
		for (var i = 0; i < imgs.length; ++i) {
			++imgReady;
			imgs[i].onload = function() {
				--imgReady;
				checkReady();
			};
		}
		--imgReady;
		checkReady();
	}else {
		doPlay(true);
	}
}

function pause() {
	$("#gameplay_content").off(); //clear events
	if (sbTimer.isFreezed) {//if the timer is freezed get remaining freeze time
		var before = sbTimer.freezedTime;
		var now = Date.now();
		sbTimer.freezeTimeout -= now - before;
	}
	sbTimer.pause();
	//pause the timer
	sbProgressBar.pause();
	//pause the progress bar
	soundPlayer.start(1);
	//resume theme sound
	soundPlayer.pause(6);
	//pause narration
	setPage({data : {next : "pause.html"}});
}

function levelFailed() {
	$("#gameplay_content").off();
	//clear interval
	currentScore = 0;
	sbTimer.stop();
	sbProgressBar.stop();
	soundPlayer.stop(6);
	//stop narration
	//clear unused global variables
	leftPrevs = [];
	//next screen
	soundPlayer.start(12);
	//play sound
	setPage({data : {next : "level_failed.html"}});
}

function finishLevel() {
	$("#gameplay_content").off();
	sbTimer.stop();
	sbProgressBar.stop();
	soundPlayer.stop(6);
	//stop narration
	var score = parseInt(document.getElementById("score").innerHTML);
	//increment levelsPlayed used for rate it popup and fullscreen ads!!!
	levelsPlayed++;
	//unlock next level and save in local storage
	if(levelMode == 'word' && wordLevels.length > playedLevel) {
		if(wordLevels[playedLevel] == -1) {
			wordLevels[playedLevel] = 0; //unlock next level
			changeLS('wordLevels', wordLevels);
		}
	}else if(levelMode == 'image' && imageLevels.length > playedLevel) {
		if(imageLevels[playedLevel] == -1) {
			imageLevels[playedLevel] = 0; //unlock next level
			changeLS('imageLevels', imageLevels);
		}
	}
	//unlock bonus level
	if(bonusLevels[playedLevel - 1] == -1 && levelMode != 'bonus') {
		bonusLevels[playedLevel - 1] = 0;
		changeLS('bonusLevels', bonusLevels);
	}
	//clear unused global variables
	leftPrevs = [];
	//next screen
	setPage({data:{ next: "level_complete.html"	}});
}

//hint, found, power-ups
function hint(btn, time, obj, n) {
	disableBtn(btn, time, null);
	//if the normal hint is used, then the multiplier goes down with 3
	if(n==0 && sbProgressBar.ratio > 3) {
		sbProgressBar.ratio -= 3;
		sbProgressBar.once(true);
	} else if (n == 0 && sbProgressBar.ratio <= 3) {
		sbProgressBar.stop();
	}
	soundPlayer.start(9); //play sound
	if(obj == null) obj = getRandomObject();
	var holder = document.getElementById("h" + n);
	var animation = holder.firstChild;
	syncCenters(obj, holder);
	animateHint(animation, obj.parentNode);
	//reduce the multiplier with 3
	if(sbProgressBar.ratio > 3) sbProgressBar.ratio -= 3;
}

function found(evn) {
	var objHolder = evn.data.obj; //image holder
	var obj = objHolder.firstChild; //image
	var prev = null;
	if(levelMode != 'bonus') { //get preview
		prev = getPreview(objHolder);
	}else {
		prev = getLetterPreview(objHolder);
	}
	if(prev != null) {
		penalty = 0; //clear penalties
		soundPlayer.start(8); //play sound
		//make animation
		var holder = document.createElement("div");
		var animation = document.createElement("div");
		animation.className = "found_animation";
		$(holder).append(animation);
		$("#items_container").after(holder);
		//handle found
		syncCenters(obj, holder);
		animateFound(animation, holder);
		//show preview and fade away
		var src = obj.src;
		var newSrc = getArrayObjectByObject(objHolder).getAttributeNode("previewSrc").value;
		obj.setAttribute("src", newSrc);
		obj.removeAttribute("style"); //remove width and height of the image
		obj.onerror = function() { //there is no preview for this object
			obj.src = src;
		};
		$(obj).fadeOut(1000);
		//add score
		var score = document.getElementById("score");
		var multiplier = document.getElementById("multiplier");
		score.innerHTML = parseInt(score.innerHTML) + 100 * parseInt(multiplier.innerHTML);
		currentScore = parseInt(score.innerHTML);
		//add score to the global variable
		if(sbTimer.isFreezed) {
			//show max progress bar
			$("#progress_bar").css("width", sbProgressBar.max + 'px');
			sbProgressBar.progress = sbProgressBar.max;
			//increase ratio
			if(sbProgressBar.ratio < 9)
				sbProgressBar.ratio++;
			sbProgressBar.multiplier.innerHTML = sbProgressBar.ratio + "x";
		}else {
			sbProgressBar.start();
		}
		//show tick or line-through text word
		var td = null;
		td = prev.parentNode;
		if(levelMode != 'word') {
			var tick = td.firstChild;
			$(tick).show();
		}else {
			prev.className = "word_mode_text_ltrought";
			if(skin == 'stmpunk') {
				$(prev).css("width", (prev.innerHTML.length * 11.5 + 10) + 'px');
				//10.5px/letter
			}else {
				$(prev).css("width", (prev.innerHTML.length * 12 + 10) + 'px');
				//12px/letter
			}
		}
		//remove object, set new and hide tick
		$("#pause_up").removeClass('enable_pe').addClass('disable_pe'); //disable pause
		setTimeout(function() {
			if (objects.length > (levelMode == 'bonus' ? (skin!='blue' ? 12 : 8) : 6)) { //remove preview
				removePreview(prev); //remove preview from prevs array
				$(tick).hide();
			}
			removeObject(objHolder); //remove object
			if(objects.length >= (levelMode == 'bonus' ? (skin!='blue' ? 12 : 8) : 6)) {
				var map = getObjAttributes(5);
				setObject(map['id'], map['imageSrc'], map['previewSrc'], map['literal'], map['x'], map['y'], map['width'], map['height'], map['childIndex']);
			}
		}, 1000);
		//hide magnifier if it is shown
		toggleMagnifier(false);
	}
}

function removePreview(prev) {
	for (var i = 0; i < leftPrevs.length; i++) {
		if(prev == leftPrevs[i]) {
			leftPrevs[i] = null;
			$(prev).remove();
			break;
		}
	}
}

//handle magnifier
function toggleMagnifier(auto) {
	var mgIcon = document.getElementById("magnifier_icon");
	if(auto === 'undefined')
		auto = true;
	if(mgIcon.className == "magnifier_closed" && auto) {
		$("#magnifier, #mg_glass").css("visibility", "visible");
		mgIcon.className = "magnifier_opened";
		handleMagnifier(true); //activate magnifier
	}else {
		$("#magnifier, #mg_glass").css("visibility", "hidden");
		mgIcon.className = "magnifier_closed";
		handleMagnifier(false);	//deactivate magnifier
	}
}

function handleMagnifier(active) {
	if (active) {
		//handle glass move
		var mgn = document.getElementById("magnifier");
		var glass = document.getElementById("mg_glass");
		if('ontouchstart' in window) {
			var touchMoving = function(e) {
				if (e.targetTouches.length == 1) {
					var touch = e.targetTouches[0];
					if (touch.pageX >= (1280 - $("#level_content").width()) * scl && touch.pageX <= 1280 * scl && touch.pageY >= 0 && touch.pageY <= 800 * scl) {
						//move magnifier and glass
						$("#magnifier").css({
							"top" : touch.pageY / scl - $(glass).height() / 2,
							"left" : touch.pageX / scl - $(glass).width() / 2
						});
						$("#mg_glass").css({
							"top" : touch.pageY / scl - $(glass).height() / 2 + 22,
							"left" : touch.pageX / scl - $(glass).width() / 2 + 22
						});
						//move background in glass
						$("#magnifier_container").css({
							"top" : -2 * touch.pageY / scl + 800 - $("#mg_glass").height() / 2, //height: 800
							"right" : 2 * touch.pageX / scl - ($("#magnifier_container").width() + 2 * $("#side_bar").width() + 3 * parseFloat($("#side_bar").css("left"))) //width: 1006 + 2*sidebar_width: 3*slider_left
						});
					}
				}
			};
			var touchBeggin = function(evn) {
				if (evn.targetTouches.length == 1) {
					window.addEventListener('touchmove', touchMoving, false);
				}
			};
			window.addEventListener('touchstart', touchBeggin, false);
			window.addEventListener('touchend', function() {
				window.removeEventListener('touchmove', touchMoving);
			});
		} else {
			$(window).mousedown(function() {
				$(window).mousemove(function(e) {
					//active action place: sidebar, right, top, bottom
					if (e.pageX >= (1280 - $("#level_content").width()) * scl && e.pageX <= 1280 * scl && e.pageY >= 0 && e.pageY <= 800 * scl) {
						//move magnifier and glass
						$("#magnifier").css({
							"top" : e.pageY / scl - $(glass).height() / 2,
							"left" : e.pageX / scl - $(glass).width() / 2
						});
						$("#mg_glass").css({
							"top" : e.pageY / scl - $(glass).height() / 2 + 22,
							"left" : e.pageX / scl - $(glass).width() / 2 + 22
						});
						//move background in glass
						$("#magnifier_container").css({
							"top" : -2 * e.pageY / scl + 800 - $("#mg_glass").height() / 2, //height: 800
							"right" : 2 * e.pageX / scl - ($("#magnifier_container").width() + 2 * $("#side_bar").width() + 3 * parseFloat($("#side_bar").css("left"))) //width: 1006 + 2*sidebar_width: 3*slider_left
						});
					}
				});
			}).mouseup(function() {
				$(window).unbind("mousemove");
			});
		}
	} else {
		$(window).unbind();
	}
}

//power ups
function powerUp(type, time) {
	if (type == 'freeze') {
		var btn = document.getElementsByClassName("power_up")[0];
		reducePowerUp(0, btn);
		disableBtn(btn, time, "#freeze_rect");
	} else if (type == 'reveal') {
		var btn = document.getElementsByClassName("power_up")[1];
		hint(btn, (reducePowerUp(1, btn) ? time : 0), null, 1);
	} else {
		//copy the table content
		var table = document.getElementsByTagName("table")[0].cloneNode(true);
		//add content and show popup
		$("#locate_popup").prepend(table).css("visibility", "visible");
		if(levelMode=='bonus') table.id = "bonus_lp";
		//change table css
		if(skin == 'blue') {
			if(levelMode == 'word') {
				$(".word_mode_text").css({
					"border" : "3px solid #41ED02",
					"border-radius" : "5px"
				});
			}else if(levelMode == 'image') {
				$("table * td").css("border-color", "#41ED02");
				
			}else {
				$("table.letters_holder * td").css("border-color", "#41ED02");
				$("#bonus_word_holder").css("border-color", "#41ED02");
			}
		}
		//add onclick function
		var tds = $("#locate_popup > table").find("td");
		for(var i = 0; i < tds.length; i++) {
			//set onclick on previews
			if(tds[i].hasChildNodes()) {
				if(levelMode != 'bonus') {
					$(tds[i].childNodes[1]).on('tap', {id : tds[i].childNodes[1].id, time : time}, locate);
				} else {
					if(tds[i].childNodes.length > 1 && $(tds[i].childNodes[0]).css("display") == 'none') {
						$(tds[i].childNodes[1]).on('tap', {letter : tds[i].childNodes[1].getAttribute("name"),time : time}, locateLetter);
					}
				}
			}
		}
	}
}

function locate(e) {
	var btn = document.getElementsByClassName("power_up")[2];
	var obj = document.getElementById(e.data.id);
	obj = getObjectByPreview(obj);
	hint(btn, (reducePowerUp(2, btn) ? e.data.time : 0), obj != null ? obj.firstChild : obj, 2);
	closeLocate();
}

function locateLetter(e) {
	var word = document.getElementById("bonus_word_holder").innerHTML;
	var btn = document.getElementsByClassName("power_up")[2];
	//get object directly
	var obj = document.getElementById(e.data.letter).firstChild;
	hint(btn, (reducePowerUp(2, btn) ? e.data.time : 0), obj, 2);
	closeLocate();
}

function closeLocate() {
	//remove onclick, class and locate dialogue
	if(skin == 'blue') {
		if(levelMode == 'word') {
			$(".word_mode_text").css("border", "none");
		}else if(levelMode == 'image') {
			$("table.items_holder * td").css("border-color", "transparent");
		}else {
			$("table.letters_holder * td").css("border-color", "transparent");
			$("#bonus_word_holder").css("border-color", "transparent");
		}
	}
	$("#locate_popup").removeAttr('style'); //hide the locate popup
	$("#locate_popup > table").remove(); //remove the table
	sbTimer.start(); //unpause the timer
	var tds = document.getElementsByTagName("td");
	for (var i = 0; i < tds.length; i++) {
		$(tds[i]).off('tap');
	}
}

function reducePowerUp(i, btn) {
	var powerUp = document.getElementsByClassName("power_up");
	var text = powerUp[i].childNodes[0].innerHTML;
	if (text[text.length - 1] > 0) {
		text = text.replace(text[text.length - 1], (text[text.length - 1] - 1));
		powerUp[i].childNodes[0].innerHTML = text;
		if (i == 0) {
			powerUps.freeze = parseInt(text[text.length - 1]);
			changeLS('powerUps["freeze"]', powerUps.freeze);
		} else if (i == 1) {
			powerUps.reveal = parseInt(text[text.length - 1]);
			changeLS('powerUps["reveal"]', powerUps.reveal);
		} else {
			powerUps.locate = parseInt(text[text.length - 1]);
			changeLS('powerUps["locate"]', powerUps.locate);
		}
		if (text[text.length - 1] == 0)
			return false;
	} else {
		return false;
	}
	return true;
}
//common used
function syncCenters(obj, holder) {
	var x = parseFloat($(obj).css("left"));
	var	y = parseFloat($(obj).css("top"));
	if(x == 0) {
		x = parseFloat($(obj.parentNode).css("left"));
		y = parseFloat($(obj.parentNode).css("top"));
	}
	//get coords
	var object = {
		width : $(obj).width(),
		height : $(obj).height(),
		left : x,
		top : y,
		right : function() {
			return object.left + object.width;
		},
		bottom : function() {
			return object.top + object.height;
		}
	};
	//get animation size
	var anim = {
		width : $(holder).children().width(),
		height : $(holder).children().height()
	};
	//get middle point
	var mid = {
		left : (object.left + object.right()) / 2,
		top : (object.top + object.bottom()) / 2
	};
	//sync their centers
	$(holder).css({
		'height' : anim.height,
		'width' : anim.width,
		'position' : 'absolute',
		'left' : mid.left - anim.width / 2,
		'top' : mid.top - anim.height / 2
	});
	var scale = 0;
	if (object.height < object.width) {
		scale = Math.min(object.width, anim.width) / Math.max(object.width, anim.width);
	} else {
		scale = Math.min(object.height, anim.height) / Math.max(object.height, anim.height);
	}
	scale++;
	$(holder).children().css("transform", "scale(" + scale + ")");
}

function getRandomObject() {
	//get previews
	var tds = document.getElementsByTagName("td");
	var objs = [];
	var n = 0;
	for (var i = 0; i < tds.length; i++) {
		if ($(tds[i]).css("display") != "none" && $(tds[i]).css("visibility") != "hidden") {
			var obj = null;
			if (levelMode == 'bonus' && $(tds[i].childNodes[0]).css("display") == 'none') {
				obj = getLetterByPreview(tds[i].childNodes[1]);
			} else {
				obj = getObjectByPreview(tds[i].childNodes[1]);
			}
			if (obj != null) {
				objs[n] = obj.firstChild;
				n++;
			}
		}
	}
	return objs[Math.floor(Math.random() * objs.length)];
}
function disableBtn(btn, time, obj) {
	$(btn).addClass('disabled_button');
	if (obj != null) {//freeze timer
		sbTimer.isFreezed = true;
		sbTimer.freezeTimeout = time * 1000;
		sbTimer.freezedTime = Date.now();
		sbProgressBar.pause();
		sbTimer.pause();
		$(obj).show();
	}
	if(time > 0) {
		setTimeout(function() {
			if (obj != null && sbTimer.isFreezed) {//unfreeze timer
				sbTimer.isFreezed = false;
				sbProgressBar.start();
				sbTimer.start();
				$(obj).hide();
			}
			$(btn).removeClass('disabled_button');
		}, time * 1000);
	}
}

function getPreview(obj) {
	for (var i = 0; i < objects.length; i++) {
		if (objects[i].getAttributeNode("id").value == obj.id) {
			var prev = document.getElementById(objects[i].getAttributeNode("childIndex").value);
			if(prev != null) return prev;
		}
	}
	return null;
}

function getLetterPreview(obj) {
	var tds = document.getElementsByTagName("td");
	var prev = null;
	for (var i = 0; i < tds.length; i++) {
		if (tds[i].hasChildNodes()) {
			if (tds[i].childNodes.length > 1) {
				if (tds[i].childNodes[1].getAttribute("name") == obj.id && $(tds[i]).css("display") != "none") {
					prev = tds[i].childNodes[1];
					break;
				}
			}
		}
	}
	return prev;
}

function getObjectByPreview(prev) {
	for (var i = 0; i < objects.length; i++) {
		if (objects[i].getAttributeNode("childIndex").value == $(prev).attr("id")) {
			var obj = document.getElementById(objects[i].getAttributeNode("id").value);
			if (obj != null)
				return obj;
		}
	}
	return null;
}

function getLetterByPreview(obj) {
	var obj = document.getElementById(obj.getAttribute("name"));
	return obj != null ? obj : null;
}

function getArrayObjectByObject(obj) {
	for (var i = 0; i < objects.length; i++) {
		if (objects[i].getAttributeNode("id").value == obj.id) {
			//check if the sent object is exist into objects array
			//if it exist try to get preview, and if the preview exist return the object from the array
			var prev = (levelMode=='bonus' ? 
						document.getElementsByName(objects[i].getAttributeNode("id").value) :
						document.getElementById(objects[i].getAttributeNode("childIndex").value));
			if(prev != null) return objects[i];
		}
	}
	return null;
}
//get from xml methods
function getLevelObjects() {
	var xhttp;
	if (window.XMLHttpRequest) {
		xhttp = new XMLHttpRequest();
		try {
			xhttp.open("GET", "res/level_xmls/level_" + playedLevel + ".xml", false);
			xhttp.send();
			var xml = xhttp.responseXML;
			var map = {};
			var regular = xml.getElementsByTagName("regular")[0];
			var bonus = xml.getElementsByTagName("bonus")[0];
			map['objects'] = regular.getElementsByTagName("object");
			map['letters'] = bonus.getElementsByTagName("object");
			return map;
		} catch (e) {
			console.log("Problem with opening the xml! " + e);
		}
	}
}

function getTimeSoundIntro() {
	var xhttp;
	if (window.XMLHttpRequest) {
		xhttp = new XMLHttpRequest();
		try {
			xhttp.open("GET", "res/level_xmls/level_" + playedLevel + ".xml", false);
			xhttp.send();
			var map = {};
			var xml = xhttp.responseXML;
			var regular = xml.getElementsByTagName("regular").item(0);
			var bonus = xml.getElementsByTagName("bonus").item(0);
			var intro = xml.getElementsByTagName("intro").item(0);
			if (levelMode == 'bonus') {
				map['time'] = bonus.getAttributeNode("time").value;
			} else {
				map['time'] = regular.getAttributeNode("time").value;
			}
			map['sound'] = regular.getAttributeNode("sound").value;
			map['intro'] = intro.getElementsByTagName("n");
			return map;
		} catch (e) {
			console.log("Problem with opening the xml! " + e);
		}
	}
}