exports.init = function(globals) {

	var win = Ti.UI.createWindow({
		orientationModes : [
	        Titanium.UI.LANDSCAPE_LEFT,
	        Titanium.UI.LANDSCAPE_RIGHT 
	    ]
	});
	
	var obj = getViewObj(win, globals);
	
	win.addEventListener('android:back', obj.goBack);
	win.addEventListener('postlayout', obj.onPostLayout);
	win.addEventListener('close', obj.onClose);
	win.addEventListener('focus', obj.onFocus);
	win.addEventListener('blur', obj.onBlur);
	
	win.setPuzzle = function(data){
		obj.setPuzzle(data);
	};
	win.cleanPuzzle = function(){
		obj.cleanPuzzle();
	};
	
	obj.buildView();
	return win;
};

function getViewObj(win, globals){
	var winSound = null;
	if (Ti.Platform.osname != "mobileweb") {
		winSound = Ti.Media.createSound({url: 'audio/win.mp3'});
	} else {
		winSound = soundMgr.createSound('audio/win.mp3');
	}
	var touchStartSound = null;
	if (Ti.Platform.osname != "mobileweb") {
		touchStartSound = Ti.Media.createSound({url: 'audio/button5.mp3'});
	} else {
		touchStartSound = soundMgr.createSound('audio/button5.mp3');
	}
	var winPuzzle = {
		view: {},
		scene: {},
		popup: {},
		updateBox: {},
		nextBox: {},
		randomVec: [],
		nCurrentPart: 0,
		winSound: winSound,
		audioLoop: {},
		pieceSound: {},
		voice: {},
		touchStartSound: touchStartSound, 
		target: 0,
		goalCounter: 0,
		maxPartIndex: 1,
		initialPosition: {x:180,y:120},
		currentConfig: {},
		puzzleLeft: globals.platformWidth-450*globals.screenRatio-10*globals.screenRatio,
		puzzleTop: 10*globals.screenRatio,
		puzzleId: 0,
		started: false,
		finished: false,
		puzzlePartViews: [],
				
		buildView: function(){
			
			// view definition
			this.view = Ti.UI.createView({});
			this.buildBackground();
			this.buildScene();
			this.buildNavigation();
			this.buildPopup();
			win.add(this.view);
			
			// audio
			if (Ti.Platform.osname == "mobileweb") {
				
				this.audioLoop = soundMgr.createLoop('audio/game.mp3');
				this.pieceSound = {
					tracks: [
						soundMgr.createSound('audio/piece-on/1.mp3'),
						soundMgr.createSound('audio/piece-on/2.mp3'),
						soundMgr.createSound('audio/piece-on/3.mp3'),
						soundMgr.createSound('audio/piece-on/4.mp3'),
						soundMgr.createSound('audio/piece-on/5.mp3'),
						soundMgr.createSound('audio/piece-on/6.mp3'),
						soundMgr.createSound('audio/piece-on/7.mp3'),
						soundMgr.createSound('audio/piece-on/8.mp3')
					],
					num: 0,
					play: function(){
						this.tracks[this.num].play();
						this.num++;
						if(this.num > this.tracks.length - 1){
							this.num = 0;
						}
					}
				};
				
			} else {
				
				this.audioLoop = Ti.Media.createSound({url: 'audio/game.mp3', volume: 0.5});
				this.pieceSound = {
					tracks: [
						Ti.Media.createSound({url: 'audio/piece-on/1.mp3'}),
						Ti.Media.createSound({url: 'audio/piece-on/2.mp3'}),
						Ti.Media.createSound({url: 'audio/piece-on/3.mp3'}),
						Ti.Media.createSound({url: 'audio/piece-on/4.mp3'}),
						Ti.Media.createSound({url: 'audio/piece-on/5.mp3'}),
						Ti.Media.createSound({url: 'audio/piece-on/6.mp3'}),
						Ti.Media.createSound({url: 'audio/piece-on/7.mp3'}),
						Ti.Media.createSound({url: 'audio/piece-on/8.mp3'})
					],
					num: 0,
					play: function(){
						this.tracks[this.num].play();
						this.num++;
						if(this.num > this.tracks.length - 1){
							this.num = 0;
						}
					}
				};
			}
			
		},
		
		goBack: function(){
			Ti.App.fireEvent('jumpTo', {target: globals.WIN_ADVMAP, source: win, startGamePlay: false});
		},
		
		onPostLayout: function(){
			if(!winPuzzle.started){
				winPuzzle.started = true;
				/*winPuzzle.showStartPanel(function() {
					var inf = globals.infantium;
					if (inf && inf.enabled) {
						globals.infantium.startTime();
					}
					winPuzzle.showNextPart();
				});*/
			}
		},
		
		onClose: function() {
			winPuzzle.cleanPuzzle();
			winPuzzle.started = false;
		},
		
		onFocus: function() {
			if(globals.playsound && !winPuzzle.audioLoop.isPlaying()){
				if(winPuzzle.started){
					//winPuzzle.audioLoop.setLooping(true);
					winPuzzle.audioLoop.play();
				}else{
					winPuzzle.hasToPlay = true;
					setTimeout(function(){
						if(globals.playsound && !winPuzzle.audioLoop.isPlaying()){
							if(winPuzzle.hasToPlay){
								//winPuzzle.audioLoop.setLooping(true);
								winPuzzle.audioLoop.play();
							}
						}
					}, 1000);
				}
			}
		},
		
		onBlur: function() {
			winPuzzle.hasToPlay = false;
			if(globals.playsound && winPuzzle.audioLoop.isPlaying()){
				//winPuzzle.audioLoop.setLooping(false);
				winPuzzle.audioLoop.pause();
			}
		},
		
		buildBackground: function(){
			winPuzzle.view.add(Ti.UI.createImageView({
				image: '/images/common/puzzle-bg.jpg',
				width: Math.floor(1.3*800*globals.screenRatio),
				height: Math.floor(1.3*480*globals.screenRatio)
			}));
		},
		
		buildScene: function(){
			
			// scene definition
			var scene = Ti.UI.createView({
				width:'100%',
				height:'100%'
			});
			scene.add(Ti.UI.createLabel({
				text:'',
				color:'#fff',
				font: {fontSize: 20*globals.screenRatio, fontFamily: globals.fontFamily, fontWeight: 'bold'},
				textAlign:'center',
				backgroundImage: '/images/common/wood-150.png',
				width: 150*globals.screenRatio,
				height: 45*globals.screenRatio,
				top: 20*globals.screenRatio,
				left: 80*globals.screenRatio,
				zIndex: 100
			}));
			
			// image area
			var imageArea = Ti.UI.createView({});
			scene.add(imageArea);
			scene.imageArea = imageArea;
			
			// play area
			var playArea = Ti.UI.createView({});
			scene.add(playArea);
			scene.playArea = playArea;

			// add scene
			winPuzzle.scene = scene;
			winPuzzle.view.add(scene);
		},
		
		buildNavigation: function(){

			// back button
			var backButton = Ti.UI.createImageView({
				image: '/images/common/navigation/back.png',
				top: 5*globals.screenRatio,
				left: 5*globals.screenRatio,
				width: 72*globals.screenRatio,
				height: 72*globals.screenRatio
			});
			backButton.addEventListener('touchstart',function(){
				if(globals.playsound){
					globals.audioButton.play();
				}
				winPuzzle.goBack();
			});
			winPuzzle.view.add(backButton);
			
			// update button
			var updateBox = Ti.UI.createView({
				width: 240*globals.screenRatio,
				height: 80*globals.screenRatio,
				bottom: 0,
				left: 0,
				visible: false
			});
			var updateLabel = Ti.UI.createLabel({
				text: (globals.firefox) ? 'Repeat' : L('repeat'),
				font: {fontSize: 22*globals.screenRatio, fontWeight: 'bold'},
				backgroundColor: '#0660be',
				borderRadius: 10*globals.screenRatio,
				borderWidth: 2*globals.screenRatio,
				color: '#fff',
				textAlign: 'center',
				height: 40*globals.screenRatio,
				width: 170*globals.screenRatio,
				bottom: 15*globals.screenRatio,
				left: 50*globals.screenRatio
			});
			updateBox.add(updateLabel);
			var updateButton = Ti.UI.createImageView({
				image:'/images/common/navigation/update.png',
				bottom: 5*globals.screenRatio,
				left: 5*globals.screenRatio,
				width: 72*globals.screenRatio,
				height: 72*globals.screenRatio
			});
			updateBox.add(updateButton);
			updateBox.addEventListener('touchstart',function(){
				if(globals.playsound){
					globals.audioButton.play();
				}
				winPuzzle.updateBox.hide();
				winPuzzle.nextBox.hide();
				winPuzzle.resetGame();
				var inf = globals.infantium;
				if (inf && inf.enabled) {
					globals.infantium.startTime();
				}
			});
			winPuzzle.view.add(updateBox);
			winPuzzle.updateBox = updateBox;
			
			// next button
			var nextBox = Ti.UI.createView({
				width: 240*globals.screenRatio,
				height: 80*globals.screenRatio,
				bottom: 0,
				right: 0,
				visible: false
			});
			var nextLabel = Ti.UI.createLabel({
				text: (globals.firefox) ? 'Next' : L('next'),
				font: {fontSize: 22*globals.screenRatio, fontWeight: 'bold'},
				backgroundColor: '#24be06',
				borderRadius: 10*globals.screenRatio,
				borderWidth: 2*globals.screenRatio,
				color: '#fff',
				textAlign: 'center',
				height: 40*globals.screenRatio,
				width: 170*globals.screenRatio,
				bottom: 15*globals.screenRatio,
				right: 50*globals.screenRatio
			});
			nextBox.add(nextLabel);
			var nextButton = Ti.UI.createImageView({
				image: '/images/common/navigation/next.png',
				bottom: 5*globals.screenRatio,
				right: 5*globals.screenRatio,
				width: 72*globals.screenRatio,
				height: 72*globals.screenRatio
			});
			nextBox.add(nextButton);
			nextBox.addEventListener('touchstart',function(){
				if(globals.playsound){
					globals.audioButton.play();
				}
				winPuzzle.goBack();
			});
			winPuzzle.view.add(nextBox);
			winPuzzle.nextBox = nextBox;
		},
		
		buildPopup: function() {
			var popup = require('ui/Popup').Popup(globals);
			winPuzzle.popup = popup;
			winPuzzle.view.add(popup);
			winPuzzle.showStartPanel(function() {
				var inf = globals.infantium;
				if (inf && inf.enabled) {
					globals.infantium.startTime();
				}
				winPuzzle.showNextPart();
			});
		},
		
		buildBehavior: function(){
			var scene = winPuzzle.scene;
			var playArea = scene.playArea;
			//var touchArea = scene.touchArea;
			var inf = globals.infantium;
			if (inf && inf.enabled) {
				touchArea.addEventListener('singletap', function(e) {	
					/*if (winPuzzle.finished){
						globals.infantium.addNoElementTap({
							x: Math.round(e.x), 
							y: Math.round(e.y)
						});
					} else {*/
					if (!winPuzzle.finished){
						var children=playArea.children;
						var nChildren=children.length;
						var firstPart={};
						var maxZIndex=0;
						for(var i=0; i<nChildren; i++){
							var partView=children[i];
							var widthHalf=partView.width/2;
							var heightHalf=partView.height/2;
							if ( (e.x > partView.center.x - widthHalf) && (e.x < partView.center.x + widthHalf) ){
								if ( (e.y > partView.center.y - heightHalf) && (e.y < partView.center.y + heightHalf) ){
									if(partView.zIndex > maxZIndex){
										maxZIndex = partView.zIndex;
										firstPart = partView;
									}
								}
							}
						}
						if(firstPart.zIndex){
							globals.infantium.addElementTap(firstPart.id);
						} else {
							globals.infantium.addNoElementTap({
								x: Math.round(e.x), 
								y: Math.round(e.y)
							});
						}
					}
				});
			}
			touchArea.addEventListener('touchstart',function(e){
				
				if(winPuzzle.finished){
					if(globals.playsound){
						var character = winPuzzle.scene.imageArea.children[0];
						if(e.x >= character.left && e.x <= character.left + character.width){
							if(e.y >= character.top && e.y <= character.top + character.height){
								winPuzzle.playSound();
							}
						}
					}
				}else{	
					var nIndex = winPuzzle.currentPartIndex;
					var partView = playArea.children[nIndex];
					var widthHalf = partView.width/2;
					var heightHalf = partView.height/2;
					console.log(JSON.stringify(partView.center));
					if ( (e.x > partView.center.x - widthHalf) && (e.x < partView.center.x + widthHalf) &&
						(e.y > partView.center.y - heightHalf) && (e.y < partView.center.y + heightHalf) ) {
						partView.selected = true;
						partView.dragStarted = false;
						if(globals.playsound){
							winPuzzle.touchStartSound.play();
						}
					}
				}
			});
			touchArea.addEventListener('touchmove',function(e){
				
				var nIndex = winPuzzle.currentPartIndex;
				var p = playArea.children[nIndex];
				
				if (p.selected) {
					p.center={
						x: Math.round(e.x),
						y: Math.round(e.y)
					};
					if (!p.dragStarted) {
						var inf = globals.infantium;
						if (inf && inf.enabled) {
							globals.infantium.startDragging({
								id: p.id,
								x1: p.center.x,
								y1: p.center.y
							});
						}
						p.dragStarted = true;
					}
				}
			});
			touchArea.addEventListener('touchend',function(e){
				
				var nIndex = winPuzzle.currentPartIndex;
				var p = playArea.children[nIndex];
				
				if (p.selected) {
					if (p.dragStarted) {
						var success = winPuzzle.checkGoal(p);
						var inf = globals.infantium;
						if (inf && inf.enabled) {
							var output = success ? 'success' : 'error';
							globals.infantium.endDragging({
								x2: Math.round(p.center.x),
								y2: Math.round(p.center.y)
							}, output);
						}
						p.dragStarted = false;
					}
					p.selected = false;
				}
			});
		},
		
		setPuzzle: function(data){
			var inf = globals.infantium;
			if (inf && inf.enabled) {
				globals.infantium.resetCurrentGame();
			}
			this.puzzleId = data.puzzleId;
			var scene = winPuzzle.scene;
			var imageArea = scene.imageArea;
			var playArea = scene.playArea;
			imageArea.add(Ti.UI.createImageView({	// child[0] - puzzle on
				image: '/images/common/puzzles/'+this.puzzleId+'/'+this.puzzleId+'.png',
				top: 10*globals.screenRatio,
				left: globals.platformWidth-460*globals.screenRatio,
				width: 450*globals.screenRatio,
				height: 450*globals.screenRatio
			}));
			imageArea.add(Ti.UI.createImageView({	// child[1] - puzzle off
				image: '/images/common/puzzle-off/'+this.puzzleId+'.png',
				//backgroundColor: '#eee',
				//opacity: 0.8,
				borderRadius: 43*globals.screenRatio,
				top: 10*globals.screenRatio,
				left: globals.platformWidth-460*globals.screenRatio,
				width: 450*globals.screenRatio,
				height: 450*globals.screenRatio
			}));
			currentConfig = require('/config/puzzles/'+this.puzzleId).init();
			scene.children[0].text = L(this.puzzleId);
			
			// create parts
			var parts = currentConfig.parts;
			winPuzzle.goalCounter = parts.length;
			var baseImgUrl = '/images/common/puzzles/'+this.puzzleId+'/';
			var evaluate = [];
			for(var i=0; i<parts.length; i++){
				var part = parts[i];
				var id = 'part-' + (i+1) + '-' + winPuzzle.puzzleId;
				evaluate.push(id);
				part.goal.x = Math.round(part.goal.x*globals.screenRatio);
				part.goal.y = Math.round(part.goal.y*globals.screenRatio);
				var partView = winPuzzle.getPartView(part, id);
				playArea.add(partView);
								
				if (inf && inf.enabled) {
					winPuzzle.setInfElements(id, partView.center.x, partView.center.y, partView.width, partView.height, part.goal.x, part.goal.y, i);
				}
			}
			if (inf && inf.enabled) {
				globals.infantium.setEvaluate(evaluate);
			}
			winPuzzle.randomizeParts();
			winPuzzle.pieceSound.num = 0;
			//winPuzzle.showNextPart();
		},
		
		getPartView: function(part, id) {
			
			var baseImgUrl = '/images/common/puzzles/'+this.puzzleId+'/';
			var part = Ti.UI.createImageView({
				image: baseImgUrl + part.image,
				width: Math.round(part.width * globals.screenRatio),
				height: Math.round(part.height * globals.screenRatio),
				left: winPuzzle.initialPosition.x * globals.screenRatio,
				top: winPuzzle.initialPosition.y * globals.screenRatio,
				canMove: true,
				visible: false,
				goal: part.goal,
				id: id,
				//zIndex: 0
			});
			/*part.addEventListener('touchstart',function(e){
				console.log('touch start');
				if (!this.canMove) return;
				
				this.localPoint = { x: e.x, y: e.y };
				if (globals.firefox) {
					this.fireEvent('touchmove', e);
				}
				
				
				/*if(winPuzzle.finished){
					if(globals.playsound){
						var character = winPuzzle.scene.imageArea.children[0];
						if(e.x >= character.left && e.x <= character.left + character.width){
							if(e.y >= character.top && e.y <= character.top + character.height){
								winPuzzle.playSound();
							}
						}
					}
				}else{	
					var nIndex = winPuzzle.currentPartIndex;
					var partView = playArea.children[nIndex];
					var widthHalf = partView.width/2;
					var heightHalf = partView.height/2;
					if ( (e.x > partView.center.x - widthHalf) && (e.x < partView.center.x + widthHalf) &&
						(e.y > partView.center.y - heightHalf) && (e.y < partView.center.y + heightHalf) ) {
						partView.selected = true;
						partView.dragStarted = false;
						if(globals.playsound){
							winPuzzle.touchStartSound.play();
						}
					}
				}*/
			//});
			part.addEventListener('touchmove',function(e){
				
				if (!this.canMove) return;
				
				if (!this.moving) {  // touch start
					this.localPoint = { x: e.x, y: e.y };
					this.moving = true;
				} else {  // touch move
					var nIndex = winPuzzle.currentPartIndex;
					var playArea = winPuzzle.scene.playArea;
					var p = playArea.children[nIndex];
					var globalPoint = e.source.convertPointToView({x : e.x, y : e.y }, playArea);
					
					p.left = globalPoint.x - p.localPoint.x;
					p.top = globalPoint.y - p.localPoint.y;
				}
				
					
				
				/*
				var nIndex = winPuzzle.currentPartIndex;
				var p = playArea.children[nIndex];
				
				if (p.selected) {
					p.center={
						x: Math.round(e.x),
						y: Math.round(e.y)
					};
					if (!p.dragStarted) {
						var inf = globals.infantium;
						if (inf && inf.enabled) {
							globals.infantium.startDragging({
								id: p.id,
								x1: p.center.x,
								y1: p.center.y
							});
						}
						p.dragStarted = true;
					}
				}*/
			});
			part.addEventListener('touchend',function(e){
				
				if (!this.canMove) return;
				
				this.moving = false;
				
				var success = winPuzzle.checkGoal(this);
				
				/*
				var nIndex = winPuzzle.currentPartIndex;
				var p = playArea.children[nIndex];
				
				if (p.selected) {
					if (p.dragStarted) {
						var success = winPuzzle.checkGoal(p);
						var inf = globals.infantium;
						if (inf && inf.enabled) {
							var output = success ? 'success' : 'error';
							globals.infantium.endDragging({
								x2: Math.round(p.center.x),
								y2: Math.round(p.center.y)
							}, output);
						}
						p.dragStarted = false;
					}
					p.selected = false;
				}*/
			});
			return part;
		},
		
		cleanPuzzle: function(){
			var scene = winPuzzle.scene;
			var title = scene.children[0];
			var imageArea = scene.imageArea;
			var playArea = scene.playArea;
			var puzzleImage = imageArea.children[0];
			var imageFilter = imageArea.children[1];
			if (puzzleImage) {
				imageArea.remove(puzzleImage);
				puzzleImage = null;
			}
			if (imageFilter) {
				imageArea.remove(imageFilter);
				imageFilter = null;
			}
			currentConfig = null;
			title.text = '';
			winPuzzle.cleanPlayArea();
			winPuzzle.pieceSound.num = 0;

			// clean voices
			var tracks = winPuzzle.voice.tracks;
			if(tracks){
				for(var i=0; i<tracks.length; i++){
					var track = tracks[i];
					if(track){
						//track.release();
						tracks[i] = null;
					}
				}
			}
			
			//remove view
			win.remove(winPuzzle.view);
			
			//set finished
			winPuzzle.finished = false;
		},
		
		checkGoal: function(part){
			
			if (!part.canMove) return;
			
			var goal = part.goal;
			var margin = 20*globals.screenRatio;
			var success = false;
			
			var center = {
				x: part.left + 0.5*part.width,
				y: part.top + 0.5*part.height
			};
			if(center.x > winPuzzle.puzzleLeft + goal.x - margin && center.x < winPuzzle.puzzleLeft + goal.x + margin){
				if(center.y > winPuzzle.puzzleTop + goal.y - margin && center.y < winPuzzle.puzzleTop + goal.y + margin){
					part.canMove = false;
					//part.move = false;
					winPuzzle.animatePart(part);
					success = true;
				}
			}
			var inf = globals.infantium;
			if (inf && inf.enabled) {
				if (success) {
					globals.infantium.gameplay.successes++;
				} else {
					globals.infantium.gameplay.failures++;
				}
			}
			return success;
		},
		
		animatePart: function(part){
			
			part.left = winPuzzle.puzzleLeft + part.goal.x - 0.5*part.width;
			part.top = winPuzzle.puzzleTop + part.goal.y - 0.5*part.height;
			
			if(globals.playsound){
				winPuzzle.pieceSound.play();
			}
			
			winPuzzle.checkFinish();
			
			/*
			part.center={
				x: winPuzzle.puzzleLeft + part.goal.x,
				y: winPuzzle.puzzleTop + part.goal.y
			};
			if(globals.playsound){
				winPuzzle.pieceSound.play();
			}
			part.animate({
				width: part.width*1.3,
				height: part.height*1.3,
				duration: 250,
				autoreverse: true
			}, function(){
				winPuzzle.checkFinish();
			});
			*/
		},
		
		checkFinish: function(){
			if(winPuzzle.goalCounter<2){
				winPuzzle.finishGame();
			} else {
				winPuzzle.showNextPart();
				winPuzzle.goalCounter-=1;
			}
		},
		
		finishGame: function(){
			var scene = winPuzzle.scene;
			var imageArea = scene.imageArea;
			var playArea = scene.playArea;
			var puzzleOff = imageArea.children[1];
			
			if(globals.playsound){
				winPuzzle.winSound.play();
			}
			
			puzzleOff.hide();	
			playArea.animate({
				opacity: 0,
				duration: 1000
			}, function(){
				// check level
				var currentLevel = Ti.App.Properties.getInt('currentLevel');
				if(!currentLevel){
					currentLevel = 1;
				}
				if(currentConfig.level == currentLevel){					
					currentLevel++;
					Ti.App.Properties.setInt('currentLevel', currentLevel);
					var inf = globals.infantium;
					if (inf && inf.enabled) {
						var levels = Ti.App.Properties.getObject('player-levels');
						if (levels) {
							var uuid = inf.currentPlayer.player_uuid;
							levels[uuid] = currentLevel;
							Ti.App.Properties.setObject('player-levels', levels);
						}
					}
				}
				
				// show end panel
				winPuzzle.showEndPanel();
				
				// load sounds
				if(globals.playsound){
					var id = winPuzzle.puzzleId;
					if (Ti.Platform.osname != "mobileweb") {
						winPuzzle.voice = {
							tracks: [
								Ti.Media.createSound({url: 'audio/voices/'+id+'1.mp3'}),
								Ti.Media.createSound({url: 'audio/voices/'+id+'2.mp3'}),
								Ti.Media.createSound({url: 'audio/voices/'+id+'3.mp3'})
							],
							num: 0
						};
					} else {
						winPuzzle.voice = {
							tracks: [
								soundMgr.createSound('audio/voices/'+id+'1.mp3'),
								soundMgr.createSound('audio/voices/'+id+'2.mp3'),
								soundMgr.createSound('audio/voices/'+id+'3.mp3')
							],
							num: 0
						};
					}
					winPuzzle.voice.tracks[0].play();
				}
				
				// set finished
				winPuzzle.finished = true;
				var inf = globals.infantium;
				if (inf && inf.enabled) {
					globals.infantium.sendData();
				}
			});
		},
		
		showStartPanel: function(callback) {
			var layout = Ti.UI.createView({
				width: 400*globals.screenRatio,
				height: 220*globals.screenRatio
			});
			layout.add(Ti.UI.createLabel({
				text: (globals.firefox) ? 'Puzzles' : L('puzzles'),
				height: 40*globals.screenRatio,
				top: 30*globals.screenRatio,
				textAlign: 'center',
				font: {fontSize: 40*globals.screenRatio, fontFamily: globals.fontFamily, fontWeight: 'bold'},
				color: '#fff'
			}));
			layout.add(Ti.UI.createLabel({
				text: (globals.firefox) ? 'Arrange the pieces to complete the picture.' : L('puzzles_help'),
				width: '90%',
				height: 80*globals.screenRatio,
				top: 90*globals.screenRatio,
				textAlign: 'center',
				font: {fontSize: 22*globals.screenRatio},
				color: '#333'
			}));
			winPuzzle.popup.setLayout(layout);
			winPuzzle.popup.open({autoClose: true, exitOnTouch: true, callback: callback});
		},
		
		showEndPanel: function() {
			var layout = Ti.UI.createView({
				top: 30*globals.screenRatio,
				width: 400*globals.screenRatio,
				height: 220*globals.screenRatio
			});
			layout.add(Ti.UI.createLabel({
				text: (globals.firefox) ? 'Excellent!' : L('end_practice'),
				height: 40*globals.screenRatio,
				top: 30*globals.screenRatio,
				textAlign: 'center',
				font: {fontSize: 40*globals.screenRatio, fontFamily: globals.fontFamily, fontWeight: 'bold'},
				color: '#fff'
			}));

			winPuzzle.popup.setLayout(layout);
			winPuzzle.popup.open({autoClose: true, exitOnTouch: true});
			winPuzzle.updateBox.show();
			winPuzzle.nextBox.show();
		},
		
		resetGame: function(){
			var inf = globals.infantium;
			if (inf && inf.enabled) {
				globals.infantium.resetCurrentGame();
			}
			var scene = winPuzzle.scene;
			var imageArea = scene.imageArea;
			var puzzleOff = imageArea.children[1];
			puzzleOff.show();
			
			var inf = globals.infantium;
			var evaluate = [];
			
			scene.playArea.animate({
				opacity:1,
				duration:1
			});
			
			var partViews = scene.playArea.children;
			for(var i=0; i<partViews.length; i++){
				var part = partViews[i];
				part.canMove = true;
				
				part.left = winPuzzle.initialPosition.x*globals.screenRatio;
				part.top =  winPuzzle.initialPosition.y*globals.screenRatio;
				
				/*part.center = {
					x: Math.round(winPuzzle.initialPosition.x*globals.screenRatio),
					y: Math.round((winPuzzle.initialPosition.y+150)*globals.screenRatio)
				};*/
				if (inf && inf.enabled) {
					var id = 'part-' + (i+1) + '-' + winPuzzle.puzzleId;
					evaluate.push(id);
					winPuzzle.setInfElements(
						id, 
						part.center.x, 
						part.center.y, 
						part.width, 
						part.height, 
						part.goal.x, 
						part.goal.y, 
						i
					);
				}
				part.visible = false;
			}
			winPuzzle.goalCounter = partViews.length;
			
			winPuzzle.randomizeParts();
			winPuzzle.showNextPart();
			
			winPuzzle.finished = false;
			winPuzzle.pieceSound.num = 0;	
			
			if (inf && inf.enabled) {
				globals.infantium.setEvaluate(evaluate);
			}
		},
		
		//+ Jonas Raoni Soares Silva
		//@ http://jsfromhell.com/array/shuffle [v1.0]
		shuffle: function(o) {
			for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
			return o;
		},
		
		randomizeParts: function(){
			var s = [];
			var nParts = winPuzzle.scene.playArea.children.length;
			for (var i=0; i<nParts; i++) {
				s.push(i+1);
			}
			winPuzzle.randomVec = winPuzzle.shuffle(s);
			winPuzzle.nCurrentPart = 0;
		},
		
		cleanPlayArea: function() {
			if (!globals.firefox) {
				winPuzzle.scene.playArea.removeAllChildren();
			}
		},
		
		showNextPart: function() {
			
			var scene = winPuzzle.scene;
			var playArea = scene.playArea;
			var partViews = playArea.children;
			var nCurrent = winPuzzle.nCurrentPart;
			var nextIndex = winPuzzle.randomVec[nCurrent] - 1;
			var nextPart = partViews[nextIndex];
			
			winPuzzle.nCurrentPart++;
			winPuzzle.currentPartIndex = nextIndex;
			
			for(var i=partViews.length-1; i>=0; i--){
				playArea.children[i].zIndex = 0;
			}
			nextPart.zIndex = 1;
			nextPart.visible = true;
		},
		
		playSound: function(){
			var voice = winPuzzle.voice;
			if(voice.tracks[voice.num]){
				voice.tracks[voice.num].play();
			}
			voice.num = (voice.num > 1) ? 0 : voice.num + 1;
		},
		
		// infantium
		getInfSubcategory: function(id, n) {
			var v = null;
			if (id == 'dog') v = ['top', 'bottom_left', 'bottom_right'];
			else if (id == 'farmgirl') v = ['top', 'top_left', 'bottom', 'top_right'];
			else if (id == 'farmboy') v = ['center', 'top_left', 'bottom_left', 'bottom_right', 'top_right'];
			else if (id == 'cat') v = ['top_right', 'top_left', 'bottom_left', 'center', 'bottom_right', 'right'];
			else if (id == 'sheep') v = ['top_left', 'center', 'top_right', 'bottom_left', 'center', 'right', 'bottom_right'];
			else if (id == 'scarecrow') v = ['top_left', 'top', 'top_right', 'center', 'center', 'bottom_left', 'left', 'bottom_right'];
			else if (id == 'skunk') v = ['top_left', 'top', 'center', 'right', 'bottom_right', 'bottom', 'left', 'center', 'bottom_left'];
			else if (id == 'squirrel') v = ['top_left', 'top', 'center', 'top_right', 'left', 'center', 'center', 'bottom_left', 'bottom', 'bottom_right'];
			
			else if (id == 'owl') v = ['top_left', 'center', 'top_right', 'right', 'left', 'center', 'right', 'left', 'center', 'bottom_left', 'bottom_right'];
			else if (id == 'crow') v = ['top_left', 'top_right', 'right', 'left', 'center', 'center', 'center', 'right', 'bottom_left', 'bottom', 'bottom', 'bottom_right'];
			else if (id == 'mouse') v = ['top_left', 'top', 'top', 'top_right', 'left', 'center', 'center', 'center', 'right', 'bottom_left', 'bottom', 'center', 'bottom_right'];
			else if (id == 'rabbit') v = ['top_left', 'top', 'top_right', 'left', 'center', 'center', 'center', 'center', 'center', 'right', 'bottom_left', 'bottom', 'bottom_right'];
			else if (id == 'hedgehog') v = ['top_left', 'top', 'center', 'top_right', 'right', 'left', 'center', 'center', 'right', 'left', 'center', 'bottom_right', 'bottom_left', 'bottom'];
			else if (id == 'goat') v = ['top_left', 'top', 'top', 'top_right', 'left', 'center', 'center', 'center', 'right', 'bottom_left', 'center', 'bottom_right', 'bottom', 'bottom'];
			else if (id == 'hen') v = ['left', 'top_left', 'top', 'top_right', 'left', 'center', 'center', 'right', 'bottom_left', 'center', 'center', 'bottom', 'center', 'bottom_right'];
			else if (id == 'turkey') v = ['top_left', 'top', 'top_right', 'right', 'left', 'center', 'right', 'left', 'center', 'center', 'right', 'bottom_left', 'center', 'bottom', 'bottom_right'];
			else if (id == 'pig') v = ['top_left', 'top', 'top', 'top_right', 'left', 'center', 'center', 'center', 'right', 'bottom_left', 'center', 'bottom', 'bottom', 'bottom', 'bottom_right'];
			else if (id == 'goose') v = ['top_left', 'top', 'top_right', 'left', 'center', 'center', 'right', 'left', 'center', 'right', 'left', 'center', 'bottom_left', 'bottom', 'bottom_right'];
			else if (id == 'cow') v = ['top_left', 'top', 'top', 'top_right', 'left', 'center', 'center', 'right', 'left', 'center', 'center', 'right', 'bottom_left', 'bottom', 'bottom', 'bottom_right'];
			else if (id == 'horse') v = ['top_left', 'top', 'top', 'top_right', 'left', 'center', 'center', 'right', 'left', 'center', 'center', 'right', 'bottom_left', 'bottom', 'bottom', 'bottom_right'];
			else if (id == 'wolf') v = ['top_left', 'top', 'top', 'top_right', 'left', 'center', 'center', 'right', 'left', 'center', 'center', 'right', 'bottom_left', 'bottom', 'bottom', 'bottom_right'];
			
			return v ? v[n] : null;
		},
		
		setInfElements: function(id, x, y, w, h, gx, gy, n) {
			var subcategory = winPuzzle.getInfSubcategory(winPuzzle.puzzleId, n);
			var inf = globals.infantium;
			var color = winPuzzle.getPartColor(winPuzzle.puzzleId, n);
			globals.infantium.addElement({	// visible part
				id: id,
				size: {w: w, h: h},
				category: 'puzzle',
				subcategory: subcategory,
				xpos: x,
				ypos: y,
				color: color
			});
			globals.infantium.addElement({	// target
				id: id + '-target',
				size: {w: w, h: h},
				category: 'puzzle',
				subcategory: subcategory,
				xpos: gx,
				ypos: gy
			});
			globals.infantium.addTarget({
				element: id,
				goal: id + '-target'
			});
		},
		
		getPartColor: function(partId, n) {
			var v = null;
			if (partId == 'dog') {
				v = ['257, 219, 254', '129, 109, 90', '232, 232, 232'];
			} else if (partId == 'farmgirl') {
				v = ['239, 64, 64', '162, 221, 251', '129, 109, 90', '190, 229, 232'];
			} else if (partId == 'farmboy') {
				v = ['238, 180, 124', '158, 220, 254', '129, 109, 90', '255, 214, 104', '177, 225, 241'];
			} else if (partId == 'cat') {
				v = ['86, 100, 72', '193, 169, 122', '193, 169, 122', '193, 169, 122', '214, 161, 126', '193, 169, 122'];
			} else if (partId == 'sheep') {
				v = ['156, 219, 255', '255, 255, 255', '178, 225, 241', '103, 150, 68', '189, 189, 189', '241, 185, 185', '103, 150, 68'];
			} else if (partId == 'scarecrow') {
				v = ['157, 219, 254', '156, 219, 255', '173, 224, 243', '255, 144, 0', '107, 150, 68', '107, 150, 68', '107, 150, 68', '107, 150, 68'];
			} else if (partId == 'skunk') {
				v = ['48, 69, 31', '113, 83, 20', '255, 255, 255', '48, 69, 31', '103, 150, 68', '51, 77, 112', '103, 150, 68', '51, 77, 112', '103, 150, 68'];
			} else if (partId == 'squirrel') {
				v = ['162, 221, 251', '74, 101, 53', '168, 121, 79', '73, 101, 53', '73, 101, 53', '185, 229, 232', '204, 159, 123', '73, 101, 53', '155, 121, 94', '113, 83, 20'];
			} else if (partId == 'owl') {
				v = ['128, 88, 52', '89, 60, 43', '156, 219, 254', '69, 102, 48', '255, 255, 255', '193, 159, 139', '97, 133, 69', '73, 101, 53', '229, 157, 30', '72, 100, 52', '69, 102, 48'];
			} else if (partId == 'crow') {
				v = ['166, 223, 247', '166, 223, 247', '166, 223, 247', '166, 223, 247', '32, 63, 81', '255, 255, 255', '7, 45, 67', '255, 255, 255', '166, 223, 247', '166, 223, 247', '135, 118, 85', '128, 89, 62'];
			} else if (partId == 'mouse') {
				v = ['166, 223, 247', '166, 223, 247', '166, 223, 247', '56, 84, 34', '166, 223, 247', '166, 223, 247', '137, 137, 137', '137, 137, 137', '115, 83, 20', '115, 83, 20', '115, 83, 20', '137, 137, 137', '115, 83, 20'];
			} else if (partId == 'rabbit') {
				v = ['213, 182, 182', '52, 80, 30', '226, 226, 226', '226, 226, 226', '139, 126, 108', '73, 92, 59', '221, 221, 221', '139, 126, 108', '139, 126, 108', '95, 141, 62', '95, 141, 62', '95, 141, 62', '95, 141, 62'];
			} else if (partId == 'hedgehog') {
				v = ['74, 91, 48', '67, 96, 45', '74, 91, 48', '74, 101, 52', '74, 91, 48', '103, 150, 68', '125, 125, 125', '125, 125, 125', '103, 150, 68', '103, 150, 68', '202, 164, 164', '103, 150, 68', '103, 150, 68', '103, 150, 68'];
			} else if (partId == 'goat') {
				v = ['166, 223, 247', '166, 223, 247', '166, 223, 247', '166, 223, 247', '50, 74, 30', '127, 106, 68', '157, 142, 121', '196, 180, 157', '59, 81, 42', '224, 224, 224', '196, 180, 157', '103, 150, 68', '103, 150, 68', '103, 150, 68'];
			} else if (partId == 'hen') {
				v = ['166, 223, 247', '166, 223, 247', '166, 223, 247', '255, 0, 0', '106, 146, 71', '170, 122, 47', '230, 180, 101', '166, 223, 247', '105, 150, 68', '136, 91, 21', '95, 64, 15', '76, 100, 55', '95, 64, 15', '104, 150, 68'];
			} else if (partId == 'turkey') {
				v = ['166, 223, 247', '166, 223, 247', '166, 223, 247', '166, 223, 247', '166, 223, 247', '255, 190, 52', '255, 216, 0', '102, 150, 68', '57, 43, 20', '103, 150, 68', '103, 150, 68', '103, 150, 68', '57, 43, 20', '76, 100, 55', '103, 150, 68'];
			} else if (partId == 'pig') {
				v = ['156, 219, 255', '251, 203, 203', '251, 203, 203', '160, 220, 252', '160, 220, 252', '241, 185, 185', '241, 185, 185', '241, 185, 185', '241, 185, 185', '96, 127, 69', '104, 90, 76', '99, 132, 69', '241, 185, 185', '241, 185, 185', '129, 109, 90'];
			} else if (partId == 'goose') {
				v = ['166, 223, 247', '207, 128, 36', '166, 223, 247', '166, 223, 247', '255, 255, 255', '166, 223, 247', '73, 100, 52', '106, 150, 68', '166, 223, 247', '103, 150, 68', '103, 150, 68', '103, 150, 68', '103, 150, 68', '76, 100, 55', '103, 150, 68'];
			} else if (partId == 'cow') {
				v = ['156, 219, 255', '156, 219, 255', '255, 255, 255', '157, 219, 254', '165, 222, 249', '159, 220, 253', '38, 21, 4', '180, 226, 239', '241, 185, 185', '241, 185, 185', '174, 168, 168', '38, 21, 4', '106, 150, 68', '104, 143, 68', '104, 143, 68', '104, 143, 68'];
			} else if (partId == 'horse') {
				v = ['156, 219, 255', '156, 219, 255', '156, 219, 255', '156, 219, 255', '157, 97, 39', '157, 97, 39', '163, 221, 250', '172, 224, 244', '174, 108, 44', '157, 97, 39', '157, 97, 39', '248, 162, 77', '103, 150, 68', '157, 97, 39', '103, 150, 68', '103, 150, 68'];
			} else if (partId == 'wolf') {
				v = ['67, 105, 39', '88, 52, 16', '111, 138, 162', '53, 82, 30', '111, 138, 162', '105, 61, 18', '111, 138, 162', '143, 170, 194', '171, 142, 84', '111, 138, 162', '111, 138, 162', '168, 139, 81', '81, 120, 47', '111, 138, 162', '171, 142, 84', '171, 142, 84'];
			}
			return v ? v[n] : null;
		}
	};
	return winPuzzle;
}
