MetaGame = Class.create({
	initialize: function(technoId, technology) {
		this.technoId = technoId;
		this.technology = technology;
        this.update();
	},
    update: function() {
        
        var technoId = this.technoId;
        var technology = this.technology;
        
        log.debug('GetGameInfoAllTechno call. Techno id: ' + technoId + ' Technology: ' + technology);
        this.gameInfo = GetGameInfoAllTechno(technoId, technology);
        this.priority = parseInt(this.gameInfo.strDownloadPriority);
        for(i in this.gameInfo) {
            log.debug('->' + i + '=' + this.gameInfo[i]);
        }
        this.title = this.gameInfo.strProductName;
        this.titleWoSpace = this.title.replace(/\s+/gi, '-');
        this.download = { downloadedKBytes: 0, totalKBytesToPlay: 0, totalKBytes: 0, timeToPlay: 0, timeToFull: 0, speedKBSec: 0 };
        this.setDownloadProgressInKBytes(
                this.gameInfo.strDownloadedKB, 
                this.gameInfo.strInitialDownloadSizeKB,
                this.gameInfo.strFullDownloadSizeKB,
                this.gameInfo.strInitialDownloadTimeLeftSec,
                this.gameInfo.strFullDownloadTimeLeftSec
        );
        this.progress = {
                startSize: 0,
                startTime: 0,
                clearTime: 60 * 1000
        }
    },
	exentUpdate: function() {
		this.gameInfo = GetGameInfoAllTechno(this.technoId, this.technology);
		this.setDownloadProgressInKBytes(
				this.gameInfo.strDownloadedKB, 
				this.gameInfo.strInitialDownloadSizeKB,
				this.gameInfo.strFullDownloadSizeKB,
				this.gameInfo.strInitialDownloadTimeLeftSec,
				this.gameInfo.strFullDownloadTimeLeftSec
		);
	},
	gametapUpdate: function() {
        var progress = getProgressInfoGame(this.technoId);
		var speed = parseInt(progress.SpeedKBSec);
		log.debug('gametap progress. DownloadedBytesStr: ' + progress.DownloadedBytesStr + ' TotalBytesToPlayStr: ' + progress.TotalBytesToPlayStr + 
		' TotalBytesStr: ' + progress.TotalBytesStr + ' EstTimeRemainingToPlaySec:' + progress.EstTimeRemainingToPlaySec + 
		' EstTimeRemainingFullDLSec: ' + progress.EstTimeRemainingFullDLSec + ' speed: ' + speed);
		speed = (speed < 0) ? 0 : speed;
        this.setDownloadProgressInBytes(
                progress.DownloadedBytesStr,
                progress.TotalBytesToPlayStr,
                progress.TotalBytesStr,
                progress.EstTimeRemainingToPlaySec,
                progress.EstTimeRemainingFullDLSec,
				speed
        );
	},
    isFullyCached: function() {
        return parseInt(this.gameInfo.strFullyCached);
    },
    isActive: function() {
        return parseInt(this.gameInfo.strActive);
    },
    isReady: function() {
        return parseInt(this.gameInfo.strReadyToUse);
    },
    isRunning: function() {
        return parseInt(this.gameInfo.strGameRunning);
    },
    isDownloadNow: function() {
        return (this.isActive() && !this.isRunning());
    },
	getStatus: function() {
		if (this.isFullyCached()) {
			return i18n('addGameInfo1');
		} else if (this.isReady()) {
			return i18n('addGameInfo2');
		} else if (this.isDownloadNow()) {
			return i18n('addGameInfo3');
		} 
		return i18n('addGameInfo4');
	},
	downloadedPercent: function() {
        return percentAvancement(this.download.downloadedKBytes, this.download.totalKBytes);
    },
    getFullSize: function() {
        return this.getDynamicSize(this.download.totalKBytes);
    },    
    getDownloadedSize: function() {
    	return this.getDynamicSize(this.download.downloadedKBytes);
    }, 
    minDownloadedPercent: function() {
        return percentAvancement(this.download.totalKBytesToPlay, this.download.totalKBytes);
    },
    setDownloadProgressInKBytes: function(downloadedKBytes, totalKBytesToPlay, totalKBytes, timeToPlay, timeToFull, speedKBSec) {
    	downloadedKBytes = parseInt(downloadedKBytes); 	totalKBytesToPlay = parseInt(totalKBytesToPlay);
    	totalKBytes = parseInt(totalKBytes); 			timeToPlay = parseInt(timeToPlay);
    	timeToFull = parseInt(timeToFull);				speedKBSec = parseFloat(speedKBSec);
    	if (!isNaN(downloadedKBytes))  	this.download.downloadedKBytes = downloadedKBytes;
    	if (!isNaN(totalKBytesToPlay))  this.download.totalKBytesToPlay = totalKBytesToPlay;
    	if (!isNaN(totalKBytes)) this.download.totalKBytes = totalKBytes;
    	if (!isNaN(timeToPlay))  this.download.timeToPlay = timeToPlay;
    	if (!isNaN(timeToFull))  this.download.timeToFull = timeToFull;
    	if (!isNaN(speedKBSec))  this.download.speedKBSec = speedKBSec;
    },
    setDownloadProgressInBytes: function(downloadedBytes, totalBytesToPlay, totalBytes, timeToPlay, timeToFull, speedKBSec) {
    	downloadedKBytes = parseInt(downloadedBytes) / 1024; 	
    	totalKBytesToPlay = parseInt(totalBytesToPlay) / 1024;
    	totalKBytes = parseInt(totalBytes) / 1024;    	
    	this.setDownloadProgressInKBytes(downloadedKBytes, totalKBytesToPlay, totalKBytes, timeToPlay, timeToFull, speedKBSec);
    },
    setBandwidthExent: function() {
    	if (this.progress.startSize == 0 || (new Date() - this.progress.startTime) > this.clearTime) {
    		this.progress.startSize = this.download.downloadedKBytes;
    		this.progress.startTime = new Date();
    	}
        var progressBandwidth = Math.round(
        		(this.download.downloadedKBytes - this.progress.startSize) / (new Date() - this.progress.startTime) * 1000
        );
//        progressBandwidth = parseFloat(progressBandwidth);
        if (isNaN(progressBandwidth)) progressBandwidth = 0;
        this.download.speedKBSec = (progressBandwidth < 0) ? 0 : progressBandwidth;
    },
    getBandwidth: function() {
    	if (this.technology == enumGameTechno.EXENT_TECHNO) this.setBandwidthExent();
        return this.download.speedKBSec + '&nbsp;' + i18n('downloadSpeedLabel'); 
    },
    getProcessTime: function() {
        var seconds = parseInt(
        		this.download.downloadedKBytes > this.download.totalKBytesToPlay ? 
        				this.download.timeToFull : this.download.timeToPlay);
        var minutes = Math.floor(seconds / 60);
        var hours   = Math.floor(seconds / 3600);
        if (isNaN(seconds) || isNaN(minutes) || isNaN(hours)) { return false; }
        if (seconds < 60) {
            return '00:00:' + formatNumber(seconds);
        } 
        if (minutes < 60) {
            return '00:' + formatNumber(minutes) + ':' + formatNumber(seconds - minutes * 60);
        }
        minutes = minutes - (hours * 60);
        seconds = seconds - minutes * 60 - hours * 3600;
        return formatNumber(hours) + ':' + formatNumber(minutes) + ':' + formatNumber(seconds);
    },
    getProcessTimeleft: function() {
    	var result = this.getProcessTime();
    	if (!result) { return i18n('ElapsedTime'); }
        return result + '&nbsp;' + i18n('ElapsedTime_result');
    },
    getDynamicSize: function(sizeKb) {
    	if (sizeKb > 1048576) {
    		return (Math.round(sizeKb/104857))/10 + ' ' + i18n('sizeGbLabel');
    	} 
		if (sizeKb > 1024) {
			return (Math.round(sizeKb/102))/10 + ' ' + i18n('sizeMbLabel');
		} 
    	return Math.round(sizeKb) + ' ' + i18n('sizeKbLabel');
    }
});

function sortByTitle(a, b) {
    return (a.title > b.title);
}

function sortByPriority(a, b) {
    return (a.priority - b.priority);
}

MyGames = Class.create({
    initialize: function() {

		this.downloaded = new Hash();
		this.inDownload = new Hash();
		this.notInDownload = new Hash();
		this.hashCookie = new Array();

		this.constant = {
				langPrefix: getLocale().path,
				userGames: 'usergames',
				inProgress: 'gameInProgress',
				readyGames: 'fullDownloadGamesList',
				readyBrowserGames: 'fullDownloadBrowserGamesList'
		};
		
		this.myEffects = {
				move: 1,
				moveFast: 0.3,
				moveSlow: 1,
				create: 0.2,
				remove: 0.6,
                noPlayer: 0.8
		};

		this.exentUpdater = null;
		this.gameInProcessTechnoId = null;
		if (isOk) {
			if (DEFINE.get('TYPE') == 'META') {
	            if (isTheGoodVersionInstalledMultiTechno(DEFINE.get('PLAYER_EXENT_VERSION'), DEFINE.get('PLAYER_YUMMY_VERSION'))) {
	                this.playerAvailable();    
	            } else {
	                this.playerUpdate();                
	            }
			} else {
				this.playerAvailable();
			}
		} else {
			this.playerNotAvailable();
		}
    },
    playerNotAvailable: function() {
        var url = new UrlConstructor('profile/download_player');
        url.addVar('isIE', (Prototype.Browser.IE) ? 1 : 0);
        new Ajax.Request(url.construct(), {
            onSuccess: function(transport) {
                var uGames = $(this.constant.userGames);
                uGames.setStyle({display: 'none'});
                uGames.update(transport.responseText);
                new Effect.BlindDown(uGames, {duration: this.myEffects.noPlayer });
            }.bind(this)
        });
    },
    playerUpdate: function() {
        var url = new UrlConstructor('profile/update_player');
        new Ajax.Request(url.construct(), {
            onSuccess: function(transport) {
                var uGames = $(this.constant.userGames);
                uGames.setStyle({display: 'none'});
                uGames.update(transport.responseText);
                new Effect.BlindDown(uGames, {duration: this.myEffects.noPlayer });
            }.bind(this)
        });
    },
    getGameList: function(xml) {
    	var list = new Hash();
    	var xmlDoc = getXmlDoc(xml);
      	result = xmlDoc.getElementsByTagName('ContentDescriptor');
		for (var i = 0 ; i < result.length ; i++) {
		 	el = result.item(i);
		 	list.set(el.getAttribute('Id'), el.getAttribute('codeTechno'));
		}      	
    	return list;
    },
    getAllGames: function() {
    	try {
    		log.debug('In download: ' + writeInDownloadListGamesAllTechno());
            this.getGameList(writeInDownloadListGamesAllTechno()).each(function(g) {
				this.inDownload.set(g.key, new MetaGame(g.key, g.value));
            }.bind(this));
	    	log.debug('Downloaded: ' + writeFullyDownloadedListGamesAllTechno());
	    	this.getGameList(writeFullyDownloadedListGamesAllTechno()).each(function(g) {
	    		if (this.inDownload.get(g.key)) return; 
	    		this.downloaded.set(g.key, new MetaGame(g.key, g.value));
	    	}.bind(this));
	    	log.debug('Not in download: ' + writeNotInDownloadListGamesAllTechno());
	    	this.getGameList(writeNotInDownloadListGamesAllTechno()).each(function(g) {
	    		if (this.downloaded.get(g.key)) return; 
	    		this.notInDownload.set(g.key, new MetaGame(g.key, g.value));
	    	}.bind(this));
	    	
	    	if (typeof(writeFullyDownloadedListGamesEmulatorAllTechno) != 'undefined') {
		    	log.debug('Browser games: ' + writeFullyDownloadedListGamesEmulatorAllTechno());
		    	this.browser = new Hash();
		    	this.getGameList(writeFullyDownloadedListGamesEmulatorAllTechno()).each(function(g) {
		    		this.browser.set(g.key, new MetaGame(g.key, g.value));
		    	}.bind(this));
	    	}
    	} catch(e) {
    		log.err(e);
    	}
    },
	playerAvailable : function() {
        ww.show();
    	this.getAllGames();
    	var url = new UrlConstructor('profile/get_games_info');
    	var merged = new Hash(); 
    	merged = this.downloaded.merge(this.inDownload).merge(this.notInDownload);
    	if (this.browser) merged = merged.merge(this.browser); 
		new Ajax.Request(url.construct(), {
			method: 'post',
			parameters: 'games=' + merged.keys().toJSON(),
			onSuccess: function(transport) {
				var obj = transport.responseText.evalJSON();
				$(this.constant.userGames).update(obj.content);
				if (typeof(obj.games) != 'undefined') this.extendMetaGame(obj.games);
                ww.hide();
				this.render();
			}.bind(this)
		});
	},
	extendMetaGame: function(games) {
        var queueSort = new Array();
		this.downloaded.keys().each(function(technoId) {
			if (typeof(games[technoId]) == 'object')
				Object.extend(this.downloaded.get(technoId), games[technoId]);
			else
				this.downloaded.unset(technoId);
		}.bind(this));
		this.inDownload.keys().each(function(technoId) { 
			if (typeof(games[technoId]) == 'object') {
                var metaGame = this.inDownload.get(technoId);
				Object.extend(this.inDownload.get(technoId), games[technoId]);
                log.debug('meta game indownload. techno id: ' + metaGame.technoId + ' technology: ' + metaGame.technology + ' priority: ' + metaGame.priority);
                queueSort.push(metaGame);
                /*
				var inGameCookie = this.inDownload.get(technoId);
				if(inGameCookie){
					this.hashCookie.push(inGameCookie);
				}
				*/
			} else {
                this.inDownload.unset(technoId);
            }
		}.bind(this));
		this.notInDownload.keys().each(function(technoId) { 
			if (typeof(games[technoId]) == 'object')
				Object.extend(this.notInDownload.get(technoId), games[technoId]);
			else
				this.notInDownload.unset(technoId);
		}.bind(this));
		if (this.browser) {
			this.browser.keys().each(function(technoId) { 
				if (typeof(games[technoId]) == 'object') 
					Object.extend(this.browser.get(technoId), games[technoId]);
				else
					this.browser.unset(technoId);
			}.bind(this));
		}
        
        if (__meta) {
            try {
                var tmp = new Array();
                queueSort.sort(sortByPriority);
                queueSort.each(function(item){
                    tmp.push(item.technoId + '/' + item.technology);
                });
                var queueCookie = tmp.join(',');
                log.debug('set queue cookie. value: ' + queueCookie);
                set_cookie(queueCookie);                
                var queueCookie = get_cookie();
                log.debug('get queue cookie. value: ' + queueCookie);
                var matchCookie = queueCookie.match(/(\d+\/\w+)/gi);
                if (matchCookie && matchCookie.size()) {
                    var inDownload = this.inDownload.clone();
                    this.inDownload = new Hash();
                    matchCookie.each(function(item){
                        log.debug('cookie queue item. item: ' + item);
                        var res = item.split('/');
                        var technoId = res[0];
                        var technology = res[1];
                        var cloneGame = inDownload.get(technoId);
                        if (cloneGame) {
                            this.inDownload.set(technoId, cloneGame);
                            log.debug('set indownload game. technoId: ' + technoId + ' technology: ' + technology);    
                        } else {
                            log.debug('can\'t find indownload game presented in cookie. technoId: ' + technoId + ' technology: ' + technology);
                        }
                    }.bind(this));
                }
            } catch(e) {
                log.err(e);
            }
        } 
        
        /*        
		// build the list of game downloaded cookie		
		this.hashCookie = orderListGamesByParameters(this.hashCookie);
		var cookiePriorityQueueDownload="";
		for (var x=0;x<this.hashCookie.length;x++){
			alert("i : "+this.hashCookie[x].technoId + " / "+this.hashCookie[x].gameInfo.strDownloadPriority)
			
			cookiePriorityQueueDownload += this.hashCookie[x].technoId+"/"+this.hashCookie[x].technology+",";
		}
		alert(cookiePriorityQueueDownload)
		set_cookie (cookiePriorityQueueDownload)
		*/
	},
	showInProgress: function() {
		if (this.inDownload.size() || this.notInDownload.size()) {
			$(this.constant.inProgress).removeClassName('displayNone');
		}
	},
    addGradient: function(technoId, metaGame) {
		return new Element('img', {
			id: 'bg-' + technoId,
			'class': 'gradientBG gradientGame',
			'src': DEFINE.get('MY_GAMES_GRADIENT')
		});
    },
    addFavorite: function(technoId, metaGame) {
    	return new Element('div', {
    		'class': 'favourite' + (metaGame.favorite ? '' : ' favourite_inactive') 
    	}).insert(
    		new Element('a', {
    			'class': 'tooltip righttip',
    			'title': i18n('addFavorite1'),
    			'href': '#add_to_favorites'
    		}).insert( new Element('span').insert(i18n('addFavorite1')) ).observe('click', this.toggleFavorite.bind(this))
    	);
    },
    addGameInfo: function(technoId, metaGame, options) {
    	var gameInfo = new Element('div', {'class': 'gameInfo'});
    	gameInfo.insert(new Element('a', {href: metaGame.gameUrl}).insert(
			new Element('img', {
				'class': 'tooltip tipright gameImage', 
				src: metaGame.boxshotUrl,
				title: metaGame.getStatus(),
				alt: metaGame.getStatus()
			})
    	));
    	gameInfo.insert(
    		new Element('a', {'class': 'manual', href: 'javascript:showManual(' + metaGame.gameId + ');'}).update(i18n('addGameInfo6'))
    	);
    	gameInfo.insert(new Element('p', {'class': 'gameTitle'}).insert(
    			new Element('a', {href: metaGame.gameUrl}).update(metaGame.title)
    	));
    	if (options && options.showProgressBar) {
    		gameInfo.insert(new Element('div', {'class': 'progressBarBG'}));
    		gameInfo.insert(new Element('p', {'class': 'numberPercent', id: 'percent-' + technoId}).update(metaGame.downloadedPercent() + '%'));
    	}
    	gameInfo.insert(new Element('p', {'class': 'infoText', id: 'processInfo-' + technoId}).update(metaGame.getDownloadedSize() + ' / ' + metaGame.getFullSize()));
    	return gameInfo;
    },
    addDownloadingButtons: function(technoId, metaGame) {
    	return new Element('div', {'class': 'downloadingButtons'});
    },
    addDownloadedButtons: function(technoId, metaGame) {
    	return new Element('div', {'class': 'downloadedButtons'});
    },
    addDownloadOnOff: function(technoId, metaGame) {
    	return new Element('div', {'class': 'downloadOnOff'});
    },
    addDownloadPriority: function(technoId, metaGame) {
    	return new Element('div', {'class': 'downloadPriority'}).insert(new Element('div', {'class': 'buttonContainer'}));
    },
    addDownloadingRemove: function(technoId, metaGame) {
        return new Element('div', {'class': 'downloadingRemove'}).insert(
        	new Element('a', {'class': 'buttonRemoveSmall', href: '#remove'}).observe('click', this.removeGame.bind(this))
        ); 
    },
    addListStatusAll: function() {
		var btStartStop = $('buttonPauseStart');
		btStartStop.insert(new Element('a', {'class': 'buttonPlayAll'}).update('Start').observe('click', this.startDownloadList.bind(this)));
    },
	refreshPriority: function(p) {
        if (!p) return;
		var info = this.getInfo(p);
		var container = info.element.down('div.downloadPriority').down().update();
		if (!this.inDownload.get(info.technoId)) return;
		if (info.order != 0) {
			container.insert(new Element('a', {'class': 'buttonUp', href: '#increase'}).observe('click', this.moveGameUp.bind(this)));
		}
		if (++info.order != this.inDownload.size()) {
			container.insert(new Element('a', {'class': 'buttonDown', href: '#decrease'}).observe('click', this.moveGameDown.bind(this)));
		}
	},
	refreshGameInfo: function(p, forceReady) {
		var info = this.getInfo(p);
		var progress = info.element.down('div.progressBarBG');
		if (progress) {
			progress.update();
		} else {
			return false;
		}
		if (info.metaGame.isFullyCached() || forceReady) {
			progress.insert(new Element('div', {
				id: 'progressBar-' + info.technoId, 
				'class': 'progressBarFill progressComplete'
			}));
		} else {
			progress.insert(new Element('div', {
				id: 'progressBar-' + info.technoId, 
				'class': 'progressBarFill' + (info.metaGame.isReady() ? ' progressReady' : ' progressIncomplete')
			}).setStyle({
				width: info.metaGame.downloadedPercent() + '%'
			}));
			progress.insert(new Element('div', {'class': 'progressBarMark'}).setStyle({
					marginLeft: info.metaGame.minDownloadedPercent() + '%'
				}).insert(new Element('a', {'class': 'progressBarInfo tooltip righttip', title: i18n('addGameInfo5')}).setStyle({
						cursor: 'default'
					}))
			);
		}
	},
	refreshDownloadingButtons: function(p, options) {
		var info = this.getInfo(p);
		var metaGame = info.metaGame;
        metaGame.update();
		var buttons = info.element.down('div.downloadingButtons').update();
		
	    var btPlay = new Element('div', {'class': 'buttonPlay buttonWidth1'});
	    var aPlay = new Element('a', {href: '#launch'});
	    aPlay.insert(new Element('span', {'class': 'buttonD_left'}));
	    aPlay.insert(new Element('span', {'class': 'buttonD_center buttonWidth1Center'}).insert(
	    	new Element('strong').update(i18n('addDownloadingButtons3'))
	    )); 
	    aPlay.insert(new Element('span', {'class': 'buttonD_right'}));
	    btPlay.insert(aPlay);
	    buttons.insert(btPlay);

	    if (metaGame.commandLines.size() > 1) {
	    	if (options && options.showOptions) {
		    	var btOptions = new Element('div', {
		    		'class': 'buttonOption buttonOptions buttonWidth1 mygames downloading',
		    		id: 'options-' + metaGame.technoId
		    	})
		    	aOptions = new Element('a', {href: '#options' + (!metaGame.isReady() ? '_inaccessibly' : '_accessibly')});
		    	aOptions.insert(new Element('span', {'class': 'buttonD_left'}));
		    	aOptions.insert(new Element('span', {'class': 'buttonD_center buttonWidth1Center'}).insert(
				    	new Element('strong').update(i18n('addDownloadingButtonsOptions'))
				    )); 
		    	aOptions.insert(new Element('span', {'class': 'buttonD_right'}));
		    	btOptions.insert(aOptions);
		    	buttons.insert(btOptions);
	    	}
	    } else {
	    	btPlay.addClassName('buttonCentred');
	    }

	    if (metaGame.isReady()) {
	    	aPlay.observe('click', this.launch.bind(this));
	    } else {
	    	btPlay.addClassName('buttonInactive');
	    	if (btOptions) btOptions.addClassName('buttonInactive');
	    }
	    
	    if (metaGame.isMultiPlayer) {
	    	btPlay.addClassName('btMultiPlayer');
	    	if (btOptions) btOptions.addClassName('btMultiPlayerOptions');	    	
	        buttons.insert(new Element('a', {
	        		'class': 'buttonMultiplayer getMultiplayerKey',
	        		href: '#multi_player_key_' + metaGame.gameId
	        	}).update(i18n('addDownloadingButtons1'))
	        );
	        if (options && options.showMultiplayerInfo) {
		        buttons.insert(new Element('a', {
		        		'class': 'multiplayerInfo tooltip righttip',
		        		title: i18n('addDownloadingButtons2')
		        	}).setStyle({cursor: 'default'})
		        );
	        }
	    }
	},
	refreshDownloadedButtons: function(p, options) {
		var info = this.getInfo(p);
		var metaGame = info.metaGame;
		var buttons = info.element.down('div.downloadedButtons').update();
		
		var btPlay = new Element('a', {'class': 'buttonPlay'}).observe('click', this.launch.bind(this));
		buttons.insert(btPlay);
	    if (metaGame.commandLines.size() > 1) {
	    	if (options && options.showOptions) {
		    	var btOptions = new Element('div', {
		    		'class': 'buttonOptions mygames btOptionsClass',
		    		id: 'options-' + metaGame.technoId
		    	}).insert(new Element('a', {href: '#options'}).insert(new Element('span')));
		    	buttons.insert(btOptions);
	    	}
	    }
	    var btRemove = new Element('a', {'class': 'buttonRemove', href: '#remove'}).update(i18n('addDownloadedButtons3'));
	    btRemove.observe('click', this.removeGame.bind(this));
	    buttons.insert(btRemove);
	    
	    if (metaGame.isMultiPlayer) {
	    	btPlay.addClassName('btMultiPlayer');
	    	if (btOptions) btOptions.addClassName('btMultiPlayer');	    	
	        buttons.insert(new Element('a', {
	        		'class': 'buttonMultiplayer getMultiplayerKey',
	        		href: '#multi_player_key_' + metaGame.gameId
	        	}).update(i18n('addDownloadedButtons1'))
	        );
	        if (options && options.showMultiplayerInfo) {
		        buttons.insert(new Element('a', {
		        		'class': 'multiplayerInfo tooltip righttip',
		        		title: i18n('addDownloadedButtons2')
		        	}).setStyle({cursor: 'default'})
		        );
	        }
	    }
	},
	refreshDownloadedBrowserButtons: function(p, options) {
		var info = this.getInfo(p);
		var metaGame = info.metaGame;
		var buttons = info.element.down('div.downloadedButtons').update();
		
		var btPlay = new Element('a', {'class': 'buttonPlay'}).observe('click', this.launch.bind(this));
		buttons.insert(btPlay);
		var btRemove = new Element('a', {'class': 'buttonRemove', href: '#remove'}).update(i18n('addDownloadedButtons3'));
		btRemove.observe('click', this.removeGame.bind(this));
		buttons.insert(btRemove);
	},
	refreshDownloadOnOff: function(p) {
		var info = this.getInfo(p);
		var buttons = info.element.down('div.downloadOnOff');
		var btOnOff = new Element('div', {'class': 'buttonContainer'});
		if (this.inDownload.get(info.technoId)) {
			btOnOff.insert(new Element('a', {'class': 'buttonOn'}));
			btOnOff.insert(new Element('a', {'class': 'buttonOff buttonOff_inactive'}).observe('click', this.removeFromList.bind(this)))
		} else {
			btOnOff.insert(new Element('a', {'class': 'buttonOn buttonOn_inactive'}).observe('click', this.addToList.bind(this)))
			btOnOff.insert(new Element('a', {'class': 'buttonOff'}));
		}
		buttons.update(btOnOff);
	},
    refreshListStatusAll: function(isDownloadActive) {
    	log.debug("start refreshListStatusAll")
    	log.debug("this.isDownloadActive : "+this.isDownloadActive)
    	log.debug("isDownloadActive : "+isDownloadActive)
		var btStartStop = $('buttonPauseStart');
		if (!btStartStop || this.isDownloadActive == isDownloadActive) return;
		this.isDownloadActive = isDownloadActive;
		btStartStop.update();
		if (isDownloadActive) {
			var a = new Element('a', {'class': 'buttonStopAll'}).update('Stop');
			a.observe('click', this.stopDownloadList.bind(this));
		} else {
			var a = new Element('a', {'class': 'buttonPlayAll'}).update('Start');
			a.observe('click', this.startDownloadList.bind(this))
		}
		a.setStyle({cursor: 'pointer'});
		btStartStop.insert(a);
	    log.debug("end refreshListStatusAll");
    },
    refreshBg: function(technoId, state) {
    	log.debug("refreshBg : "+technoId+" / "+state)
    	var bg = $('bg-' + technoId);
    	var skin = $('skin');
    	if (!bg || !skin) return;
    	var imgUrl = DEFINE.get('MY_GAMES_GRADIENT');
    	if (state == enumGameState.DOWNLOADING) {
    		imgUrl = DEFINE.get('MY_GAMES_GRADIENT_HILIGHT');
    	}
    	if (bg.src != imgUrl) bg.src = imgUrl;
    },
    addOptions: function(metaGame) {
    	if (metaGame.commandLines.size() < 1) return;
    	var optContainer = new Element('div', {id: 'expand-' + metaGame.technoId, 'class': 'optionExpand'}).setStyle({'display': 'none'});
    	var wrapper = new Element('div');
    	var ulContainer = new Element('ul', {'class': 'optionList'});
    	metaGame.commandLines.each(function(cmdLine) {
    		var li = new Element('li').insert(new Element('a', {'class': 'optionSet', href: '#option_' + cmdLine.snumber}).update(cmdLine.name));
    		ulContainer.insert(li);
    	});
    	wrapper.insert(ulContainer);
    	optContainer.insert(wrapper);
    	if (this.downloaded.get(metaGame.technoId)) {
    		$('optionExpandContainerA').insert(optContainer);
    	} else {
    		$('optionExpandContainer').insert(optContainer);
    	}
    },
	render: function() {
    	try {
		this.showInProgress();
		
        this.inDownload.keys().each(function(technoId, iter) {
            var metaGame = this.inDownload.get(technoId);
            if (metaGame.isDownloadNow()) {
                log.debug('game inprocess. technoId: ' + technoId);
                this.gameInProcessTechnoId = technoId; 
            }
            var li = new Element('li', {id: 'dsort' + iter, 'class': 't-' + technoId});
            var wrapper = new Element('div');
            wrapper.insert(this.addGradient(technoId, metaGame));
            wrapper.insert(this.addFavorite(technoId, metaGame));
            wrapper.insert(this.addGameInfo(technoId, metaGame, {
                showProgressBar: 1,
                showMultiplayerInfo: parseInt(DEFINE.get('MY_GAMES_DOWNLOADED_SHOW_MULTIPLAYER_INFO'))
            }));
            wrapper.insert(this.addDownloadingButtons(technoId, metaGame));
            wrapper.insert(this.addDownloadOnOff(technoId, metaGame));
            wrapper.insert(this.addDownloadPriority(technoId, metaGame));
            wrapper.insert(this.addDownloadingRemove(technoId, metaGame));
            li.insert(wrapper);
            //li.hide();
            $(this.constant.inProgress).insert(li);
            this.refreshPriority(li);
            this.refreshGameInfo(li);
            this.refreshDownloadingButtons(li, {
                showProgressBar: 1,
                showMultiplayerInfo: parseInt(DEFINE.get('MY_GAMES_DOWNLOADED_SHOW_MULTIPLAYER_INFO'))
            });
            this.refreshDownloadOnOff(li);
            if (parseInt(DEFINE.get('MY_GAMES_OPTIONS'))) {
                this.addOptions(metaGame);
            }
            //Effect.BlindDown(li, {queue: 'end', duration: this.myEffects.create });
        }.bind(this));

        var inDownloadSize = this.inDownload.size();
        this.notInDownload.keys().each(function(technoId, iter) {
            var metaGame = this.notInDownload.get(technoId);
            var li = new Element('li', {id: 'dsort' + (inDownloadSize + iter), 'class': 't-' + technoId});
            var wrapper = new Element('div');
            wrapper.insert(this.addGradient(technoId, metaGame));
            wrapper.insert(this.addFavorite(technoId, metaGame));
            wrapper.insert(this.addGameInfo(technoId, metaGame, {
                showProgressBar: 1,
                showMultiplayerInfo: parseInt(DEFINE.get('MY_GAMES_DOWNLOADED_SHOW_MULTIPLAYER_INFO'))
            }));
            wrapper.insert(this.addDownloadingButtons(technoId, metaGame));
            wrapper.insert(this.addDownloadOnOff(technoId, metaGame));
            wrapper.insert(this.addDownloadPriority(technoId, metaGame));
            wrapper.insert(this.addDownloadingRemove(technoId, metaGame));
            li.insert(wrapper);
            //li.hide();
            $(this.constant.inProgress).insert(li);
            this.refreshGameInfo(li);
            this.refreshDownloadingButtons(li, {
                showProgressBar: 1,
                showMultiplayerInfo: parseInt(DEFINE.get('MY_GAMES_DOWNLOADED_SHOW_MULTIPLAYER_INFO'))
            });
            this.refreshDownloadOnOff(li);          
            this.refreshPriority(li);
            if (parseInt(DEFINE.get('MY_GAMES_OPTIONS'))) {
                this.addOptions(metaGame);
            }
            //Effect.BlindDown(li, {queue: 'end', duration: this.myEffects.create });
        }.bind(this));
		
		var ul = new Element('ul', {id: 'downloadGamesId', 'class': 'downloadGames'});
		$(this.constant.readyGames).insert(ul);
		
		this.downloaded.keys().each(function(technoId, iter) {
			var metaGame = this.downloaded.get(technoId);
			var li = new Element('li', {id: 'csort' + iter, 'class': 't-' + technoId});
			var wrapper = new Element('div');
			wrapper.insert(this.addGradient(technoId, metaGame));
			wrapper.insert(this.addFavorite(technoId, metaGame));
			wrapper.insert(this.addGameInfo(technoId, metaGame, {
				showProgressBar: parseInt(DEFINE.get('MY_GAMES_DOWNLOADED_SHOW_PROGRESSBAR')),
				showMultiplayerInfo: parseInt(DEFINE.get('MY_GAMES_DOWNLOADED_SHOW_MULTIPLAYER_INFO'))
			}));
			wrapper.insert(this.addDownloadedButtons(technoId, metaGame));
			li.insert(wrapper);
			//li.hide();
			ul.insert(li);
			this.refreshGameInfo(li, true);
			this.refreshDownloadedButtons(li, {
				showMultiplayerInfo: parseInt(DEFINE.get('MY_GAMES_DOWNLOADED_SHOW_MULTIPLAYER_INFO')),
				showOptions: parseInt(DEFINE.get('MY_GAMES_OPTIONS'))
			});
			if (parseInt(DEFINE.get('MY_GAMES_OPTIONS'))) {
				this.addOptions(metaGame);
			}
			//Effect.BlindDown(li, {queue: 'end', duration: this.myEffects.create });
		}.bind(this));
		
        if (this.browser) {
            var ul = new Element('ul', {id: 'downloadBrowserGamesId', 'class': 'downloadGames'});
            $(this.constant.readyBrowserGames).insert(ul);
    
            this.browser.keys().each(function(technoId, iter) {
                var metaGame = this.browser.get(technoId);
                var li = new Element('li', {id: 'cbsort' + iter, 'class': 't-' + technoId});
                var wrapper = new Element('div');
                wrapper.insert(this.addGradient(technoId, metaGame));
                wrapper.insert(this.addFavorite(technoId, metaGame));
                wrapper.insert(this.addGameInfo(technoId, metaGame, {
                    showProgressBar: parseInt(DEFINE.get('MY_GAMES_DOWNLOADED_SHOW_PROGRESSBAR')),
                    showMultiplayerInfo: parseInt(DEFINE.get('MY_GAMES_DOWNLOADED_SHOW_MULTIPLAYER_INFO'))
                }));
                wrapper.insert(this.addDownloadedButtons(technoId, metaGame));
                li.insert(wrapper);
                //li.hide();
                ul.insert(li);
                this.refreshGameInfo(li, true);
                this.refreshDownloadedBrowserButtons(li);
                //Effect.BlindDown(li, {queue: 'end', duration: this.myEffects.create });
            }.bind(this));
        }
		
		this.addListStatusAll();
		
		if (this.gameInProcessTechnoId) {
			this.gameDownloadingStartCB(this.gameInProcessTechnoId);
			this.refreshListStatusAll(true);
		}
		if (typeof(MultiPlayerKey) == 'function') new MultiPlayerKey();
		if (typeof(MFTooltip) == 'function') new MFTooltip();
		if (typeof(Options) == 'function') new Options();

    	} catch(e) {
    		log.err(e); 
    	}
	},
	getGameById: function(technoId) {
		if (this.inDownload.get(technoId)) { return this.inDownload.get(technoId); }
		if (this.downloaded.get(technoId)) { return this.downloaded.get(technoId); }		
		if (this.notInDownload.get(technoId)) { return this.notInDownload.get(technoId); }
        if (this.browser) {
            if (this.browser.get(technoId)) {
                return this.browser.get(technoId);
            }
        }
		return false;
	},
	getInfo: function(p) {
		var baseLi = p;
		if (!Object.isElement(p)) { baseLi = Event.element(p).up('li'); }
		var technoId = baseLi.className.match(/t-(\d+)/)[1];
		var game = this.getGameById(technoId);
		var order = null;
		try {
			order = parseInt(baseLi.id.match(/.+(\d+)/)[1]);
		} catch(e) { }
		return {
			element: baseLi,
			technoId: technoId,
			technology: game.technology,
			metaGame: game,
			order: order
		}
	},
	launch: function(p) {
		var info = this.getInfo(p);
		if (!info.metaGame.isBrowser) {
            if (typeof(gameManager) == 'object') {
                gameManager.launch(info.technoId, info.metaGame.technology, 1);
            } else {
                var gm = new GameManager();
                gm.launch(info.technoId, info.metaGame.technology, 1);   
            }
		} else {
			log.debug('redirect to game page');
	        window.location = info.metaGame.gameUrl + '?autostart=1';
		}
	},
	rebuildOrderDown: function(current) {
		var count = this.inDownload.size() + this.notInDownload.size();
		current.element.id = 'tmp';
		for(var i = (current.order + 1); i < count; i++) {
			var n = $('dsort' + i);
			n.id = 'dsort' + --this.getInfo(n).order;
			this.refreshPriority(n);
		}
		current.element.id = 'dsort' + (count - 1);
		this.refreshPriority(current.element);
	},
	rebuildOrderUp: function(current) {
//		var count = this.inDownload.size() + this.notInDownload.size();
		current.element.id = 'tmp';
		for (var i = current.order; i >= 1; i--) {
			var n = $('dsort' + (i - 1));
			n.id = 'dsort' + ++this.getInfo(n).order;
		}
		current.element.id = 'dsort0';
		this.inDownload.keys().each(function(technoId) { 
			this.refreshPriority($$('li.t-' + technoId).first());
		}.bind(this));
	},
	startDownloadList: function() {
                log.debug('start download list');
                // check dl rights and populate session
                var technoId = this.inDownload.keys().first();
                var firstGame = this.getGameById(technoId);
                var checkGameUrl = new UrlConstructor('profile/game_checker');
                checkGameUrl.addVar('process', 'download');
                checkGameUrl.addVar('technoId', technoId);
                checkGameUrl.addVar('technology', firstGame.technology);
                checkGameUrl.addVar('commandLine', firstGame.commandLines);
                new Ajax.Request(checkGameUrl.construct(), {
                        method: 'get',
                        //if check ok, then continue download
                        onComplete: function() {
                            var url = new UrlSeoConstructor('ADD_TO_DOWNLOAD_LIST');
                            log.debug('Check up complete. Call buttonStartDownloadListAllTechno params: '+ url.construct());
                            this.downloadClick = technoId;
                            buttonStartDownloadListAllTechno(url.construct());
                        }.bind(this)
                });
	},
	stopDownloadList: function() {
		buttonPauseDownloadListAllTechno();
	},
	removeFromList: function(p) {
		var info = this.getInfo(p);
		removeToDownloadListAllTechno(info.technoId, info.technology);
		log.debug('remove from download list. techno id: ' + info.technoId + ' technology: ' + info.technology);
		if (info.technology == enumGameTechno.YUMMY_TECHNO) this.removeFromListCB(info.technoId); 
	},
	removeFromListCB: function(technoId) {
		this.notInDownload.set(technoId, this.inDownload.unset(technoId));
		var current = this.getInfo($$('li.t-' + technoId).first());
		var count = this.inDownload.size() + this.notInDownload.size();
        setTimeout(function() { this.startDownloadList(); }.bind(this), 5000);
		var rowHeight = parseInt(DEFINE.get('MY_GAMES_QUEUE_OFFSET'));
		new Effect.Opacity(current.element, {queue: 'end', from: 1.0, to: 0, duration: this.myEffects.moveFast,
			afterFinish: function() { this.refreshDownloadOnOff(current.element); }.bind(this)
		});
		for (var i = current.order; i < count; i++) {
			new Effect.Move($('dsort' + i), { queue: 'end', y: - rowHeight, transition: Effect.Transitions.sinoidal, duration: this.myEffects.moveFast});
		}
		new Effect.Move(current.element, {queue: 'end', y: rowHeight * (count - current.order), transition: Effect.Transitions.full});
		new Effect.Opacity(current.element, {queue: 'end', from: 0, to: 1.0, duration: this.myEffects.moveFast,
			afterFinish: function() { this.rebuildOrderDown(current); }.bind(this)
		});
	},
	addToList: function(p) {
		var gm = new GameManager();
		var info = this.getInfo(p);
		gm.addToDownloadList(info.technoId, info.technology, 1, info.metaGame.title);
		if (info.technology == enumGameTechno.YUMMY_TECHNO) this.addToListCB(info.technoId);
	},
	addToListCB: function(technoId) {
		this.inDownload.set(technoId, this.notInDownload.unset(technoId));
		var current = this.getInfo($$('li.t-' + technoId).first());
		var rowHeight = parseInt(DEFINE.get('MY_GAMES_QUEUE_OFFSET'));
		new Effect.Opacity(current.element, {queue: 'end', from: 1.0, to: 0, duration: this.myEffects.moveFast,
			afterFinish: function() { this.refreshDownloadOnOff(current.element); }.bind(this)
		});
		for (var i = current.order; i >= 1; i--) {
			new Effect.Move($('dsort' + (i - 1)), { queue: 'end', y: rowHeight, transition: Effect.Transitions.sinoidal, duration: this.myEffects.moveFast});
		}
		new Effect.Move(current.element, {queue: 'end', y: -rowHeight * parseInt(current.order), transition: Effect.Transitions.full});
		new Effect.Opacity(current.element, {queue: 'end', from: 0, to: 1.0, duration: this.myEffects.moveFast,
			afterFinish: function() { this.rebuildOrderUp(current); }.bind(this)
		});
	},
	removeGame: function(p) {
		var current = this.getInfo(p);
		if (current.metaGame.isActive()) {
			alert(i18n('deleteFromDownloadList1'));
		    return;
		}
		try {
			if (confirm(i18n('deleteFromDownloadList2'))) {
				if (current.technology == enumGameTechno.GAMETAP_TECHNO) {
                    deleteGameAllTechno(current.technoId, false, current.technology);
                    if (current.technology == enumGameTechno.YUMMY_TECHNO) this.removeGameCB(current.technoId, false);
				} else {
                    if (confirm(i18n('deleteFromDownloadList3'))) {
                        if (this.notInDownload.get(current.technoId)) return;
                        deleteGameAllTechno(current.technoId, true, current.technology);
                        if (current.technology == enumGameTechno.YUMMY_TECHNO) this.removeGameCB(current.technoId, true);
                    } else { 
                        deleteGameAllTechno(current.technoId, false, current.technology);
                        if (current.technology == enumGameTechno.YUMMY_TECHNO) this.removeGameCB(current.technoId, false);
                    }
				}
			}
		} catch(e) {
			log.err('Delete failed');
		}
	},
	moveFromDownloadedToNotInDownload: function(technoId) {
        log.debug('moveFromDownloadedToNotInDownload technoId: ' + technoId);
		this.notInDownload.set(technoId, this.downloaded.unset(technoId));
		var current = this.getInfo($$('li.t-' + technoId).first());
		Effect.BlindUp(current.element, {queue: 'end', duration: this.myEffects.remove,
			afterFinish: function() {
				current.element.remove();
				this.renderNotInDownloadGameCB(technoId);
				this.optionsToInDownload(technoId);
 			}.bind(this)
		})
	},
	renderNotInDownloadGameCB: function(technoId) {
		var ul = $('downloadGamesId');
		var metaGame = this.notInDownload.get(technoId);
		if (!metaGame) return;
		var li = new Element('li', {id: 'dsort' + (this.inDownload.size() + this.notInDownload.size() - 1), 'class': 't-' + technoId});
		var wrapper = new Element('div');
		wrapper.insert(this.addGradient(technoId, metaGame));
		wrapper.insert(this.addFavorite(technoId, metaGame));
            wrapper.insert(this.addGameInfo(technoId, metaGame, {
                showProgressBar: 1,
                showMultiplayerInfo: parseInt(DEFINE.get('MY_GAMES_DOWNLOADED_SHOW_MULTIPLAYER_INFO'))
            }));
		wrapper.insert(this.addDownloadingButtons(technoId, metaGame));
		wrapper.insert(this.addDownloadOnOff(technoId, metaGame));
		wrapper.insert(this.addDownloadPriority(technoId, metaGame));
		wrapper.insert(this.addDownloadingRemove(technoId, metaGame));
		li.insert(wrapper);
		li.hide();
		$(this.constant.inProgress).insert(li);
		setTimeout(function() {
			this.refreshGameInfo(li);
            this.refreshDownloadingButtons(li, {
                showProgressBar: 1,
                showMultiplayerInfo: parseInt(DEFINE.get('MY_GAMES_DOWNLOADED_SHOW_MULTIPLAYER_INFO'))
            });
			this.refreshDownloadOnOff(li);			
			this.refreshPriority(li);
		}.bind(this), 5000);
		Effect.BlindDown(li, {queue: 'end', duration: this.myEffects.create });
	},
	removeGameCB: function(technoId, saveInfo) {
		var current = this.getInfo($$('li.t-' + technoId).first());
		if (saveInfo) {
			if (this.inDownload.get(current.technoId)) {
				this.removeFromListCB(technoId);
			} else {
				this.moveFromDownloadedToNotInDownload(technoId);
			}
		} else {
			Effect.BlindUp(current.element, {queue: 'end', duration: this.myEffects.remove,
				afterFinish: function() {
                    if (this.downloaded.get(current.technoId)) { this.downloaded.unset(current.technoId); return true; }
					if (this.inDownload.get(current.technoId)) { this.inDownload.unset(current.technoId); }
					if (this.notInDownload.get(current.technoId)) { this.notInDownload.unset(current.technoId); }
					var count = this.inDownload.size() + this.notInDownload.size();
					for (var i = current.order; i < (count); i++) {
						var n = $('dsort' + (i + 1));
						n.id = 'dsort' + --this.getInfo(n).order;					
					}
					current.element.remove();
					this.refreshPriority($('dsort0'));
					this.refreshPriority($('dsort' + (this.inDownload.size() - 1)));
				}.bind(this)
			});
		}
	},
	moveGameUp: function(event) {
		var current = this.getInfo(event);
		var offset = parseInt(DEFINE.get('MY_GAMES_QUEUE_OFFSET'));
		var oldFirstGameDownloadList = get_first_game_in_downloadlist();
		//increase_game_in_downloadlist(new String(current.technoId));
		increaseDownloadPriorityAllTechno(current.technoId, current.technology);
		var newFirstGameDownloadList = get_first_game_in_downloadlist();
		var previous = this.getInfo($('dsort' + (current.order - 1))); 
		current.element.id = 'dsort' + --current.order;
		previous.element.id = 'dsort' + ++previous.order;
		this.refreshPriority(current.element);
		this.refreshPriority(previous.element);
		new Effect.Move(current.element, { y: - offset, transition: Effect.Transitions.spring, duration: this.myEffects.move });
		new Effect.Parallel([
		    new Effect.Move(previous.element, { y: offset, transition: Effect.Transitions.sinoidal, sync: true}),
		    new Effect.Pulsate(previous.element, { pulses: 1, sync: true})
	    	], { duration: this.myEffects.move });
	    	log.debug("oldFirstGameDownloadList : "+oldFirstGameDownloadList+" - newFirstGameDownloadList : "+newFirstGameDownloadList)
	    	if(oldFirstGameDownloadList[0] != newFirstGameDownloadList[0]){
	    		buttonPauseDownloadListAllTechno();
	    		//var url = new UrlSeoConstructor('ADD_TO_DOWNLOAD_LIST');
	    		setTimeout(function() {var url = new UrlSeoConstructor('ADD_TO_DOWNLOAD_LIST'); buttonStartDownloadListAllTechno(url.construct()); }.bind(this), 2000);
			//buttonStartDownloadListAllTechno(url.construct());
	    	}
	},
	moveGameDown: function(event) {
		var current = this.getInfo(event);
		var offset = parseInt(DEFINE.get('MY_GAMES_QUEUE_OFFSET'));
		//decrease_game_in_downloadlist(new String(current.technoId));
		var oldFirstGameDownloadList = get_first_game_in_downloadlist();
		decreaseDownloadPriorityAllTechno(current.technoId, current.technology);
		var newFirstGameDownloadList = get_first_game_in_downloadlist();
		var next = this.getInfo($('dsort' + (current.order + 1)));
		current.element.id = 'dsort' + ++current.order;
		next.element.id = 'dsort' + --next.order;
		this.refreshPriority(current.element);
		this.refreshPriority(next.element);
		new Effect.Move(next.element, { y: - offset, transition: Effect.Transitions.spring, duration: this.myEffects.move });
		new Effect.Parallel([
		    new Effect.Move(current.element, { y: offset, transition: Effect.Transitions.sinoidal, sync: true}),
		    new Effect.Pulsate(current.element, { pulses: 1, sync: true})
	    	], { duration: this.myEffects.move });
	    	log.debug("oldFirstGameDownloadList : "+oldFirstGameDownloadList+" - newFirstGameDownloadList : "+newFirstGameDownloadList)
	    	if(oldFirstGameDownloadList[0] != newFirstGameDownloadList[0]){
	    		buttonPauseDownloadListAllTechno();
	    		//var url = new UrlSeoConstructor('ADD_TO_DOWNLOAD_LIST');
	    		setTimeout(function() { var url = new UrlSeoConstructor('ADD_TO_DOWNLOAD_LIST'); buttonStartDownloadListAllTechno(url.construct()); }.bind(this), 2000);
			//buttonStartDownloadListAllTechno(url.construct());
	    	}
	},
	renderDownloadedGameCB: function(technoId) {
		log.debug('render downloaded game. technoId: ' + technoId);
		try {
			var ul = $('downloadGamesId');
			var metaGame = this.downloaded.get(technoId);
			if (!metaGame) 
				return;
			metaGame.exentUpdate();
			var li = new Element('li', {
				'class': 't-' + technoId
			});
			var wrapper = new Element('div');
			wrapper.insert(this.addGradient(technoId, metaGame));
			wrapper.insert(this.addFavorite(technoId, metaGame));
            wrapper.insert(this.addGameInfo(technoId, metaGame, {
                showProgressBar: parseInt(DEFINE.get('MY_GAMES_DOWNLOADED_SHOW_PROGRESSBAR')),
                showMultiplayerInfo: parseInt(DEFINE.get('MY_GAMES_DOWNLOADED_SHOW_MULTIPLAYER_INFO'))
            }));
			wrapper.insert(this.addDownloadedButtons(technoId, metaGame));
			li.insert(wrapper);
			li.hide();
			ul.insert(li);
			this.refreshGameInfo(li, true);
			this.refreshDownloadedButtons(li, {
                showMultiplayerInfo: parseInt(DEFINE.get('MY_GAMES_DOWNLOADED_SHOW_MULTIPLAYER_INFO')),
                showOptions: parseInt(DEFINE.get('MY_GAMES_OPTIONS'))
            });
			Effect.BlindDown(li, {
				queue: 'end',
				duration: this.myEffects.create
			});
		} catch(e) {
			log.err('problem with render downloaded game. msg: ' + e.message);
		}
	},
	moveGameToCompletedCB: function(technoId) {
		var current = this.getInfo($$('li.t-' + technoId).first());
		if (this.downloaded.get(technoId)) return;
		var rowHeight = parseInt(DEFINE.get('MY_GAMES_QUEUE_OFFSET'));
        new Effect.Parallel([
            new Effect.Move(current.element, { y: - rowHeight * (parseInt(current.order) + 1), transition: Effect.Transitions.sinoidal, sync: true}),
            new Effect.Opacity(current.element, {from: 1.0, to: 0, sync: true})
        ], { 
            duration: this.myEffects.moveSlow,
            afterFinish: function() {
                this.downloaded.set(technoId, this.inDownload.unset(technoId));
                var count = this.inDownload.size() + this.notInDownload.size();
                for (var i = current.order; i < (count); i++) {
                    var n = $('dsort' + i);
					//log.debug('i = ' + i + 'n = ' + n);
                    n.id = 'dsort' + --this.getInfo(n).order;                    
                }
                current.element.remove();
                this.refreshPriority($('dsort0'));
                this.refreshPriority($('dsort' + (this.inDownload.size() - 1)));
                setTimeout(function() {
                    this.renderDownloadedGameCB(technoId);
                    this.refreshListStatusAll(false);
					if (parseInt(DEFINE.get('MY_GAMES_OPTIONS'))) {
						this.optionsToDownloaded(technoId);
						new Options();
					}
                    this.startNextGameInList();
                }.bind(this), 2000);
            }.bind(this)
        });
	},
    startNextGameInList: function() {
    	log.debug("startNextGameInList")
        if (!this.inDownload.size()) return false;
        var technoId = this.inDownload.keys().first();
        var metaGame = this.inDownload.get(technoId);
        log.debug('start next game in list. technoId: ' + technoId);
		if (metaGame.technology == enumGameTechno.GAMETAP_TECHNO) {
			log.debug('set active next game in list. technoId: ' + technoId);
			try {
				this.exentUpdater.stop();
				this.exentUpdater = null;
			} catch(e) {
				log.err('try stop periodical executer. msg: ' + e.message);
			}
		    this.gameDownloadingStartCB(technoId);	
		} else {
			var url = new UrlSeoConstructor('ADD_TO_DOWNLOAD_LIST');
			buttonStartDownloadListAllTechno(url.construct());
		}
		
		/*if (metaGame.technology == enumGameTechno.YUMMY_TECHNO) {
	        var gm = new GameManager();
	        gm.addToDownloadList(metaGame.technoId, metaGame.technology, 1, metaGame.title);    
		}else if(metaGame.technology == enumGameTechno.EXENT_TECHNO){
			var url = new UrlSeoConstructor('ADD_TO_DOWNLOAD_LIST');
			buttonStartDownloadListAllTechno(url.construct());	
		}*/
    },
	optionsToDownloaded: function(technoId) {
		try {
			if (!$('optionExpandContainerA')) return ;
			$('optionExpandContainerA').insert($('expand-' + technoId).remove());
		} catch(e) { log.err('Move options container to "downloaded" failed. ' + e.message); }
	},
	optionsToInDownload: function(technoId) {
		try {
			if (!$('optionExpandContainer')) return ;
			$('optionExpandContainer').insert($('expand-' + technoId).remove());
		} catch(e) { log.err('Move options container to "in download" failed. ' + e.message); }
	},
	updateGameInfo: function(technoId) {
		var game = this.getGameById(technoId);
		var processInfo = $('processInfo-' + technoId);
		var progressBar = $('progressBar-' + technoId);
		var percent = $('percent-' + technoId);
		if (!processInfo || !progressBar || !percent) { return false; }
    	processInfo.update(
    			game.getDownloadedSize() + '&nbsp;/&nbsp;' + game.getFullSize() + ' ' + 
    			'(' + game.getBandwidth() + ') ' +
    			game.getProcessTimeleft()
    	);
        progressBar.setStyle({width: game.downloadedPercent() + '%'});
        percent.update(game.downloadedPercent() + '%');
	},
	updateReadyToPlayCB: function(technoId) {
        var progressBar = $('progressBar-' + technoId);
        if (progressBar.hasClassName('progressIncomplete')) {
            progressBar.removeClassName('progressIncomplete').addClassName('progressReady');
            this.refreshDownloadingButtons($$('li.t-' + technoId).first());
        }
	},
	updateProgressCB: function(technoId, downloadedBytes, totalBytesToPlay, totalBytes, timeToPlay, timeToFull, speedKBSec) {
        if (this.downloaded.get(technoId)) return;
		var game = this.getGameById(technoId);
		game.setDownloadProgressInBytes(downloadedBytes, totalBytesToPlay, totalBytes, timeToPlay, timeToFull, speedKBSec);
		this.refreshListStatusAll(true);
		this.refreshBg(technoId, enumGameState.DOWNLOADING);
		this.updateGameInfo(technoId);
	},
	gameDownloadingStartCB: function(technoId) {
		log.debug("start UI download game : "+technoId)
		this.refreshBg(technoId, enumGameState.DOWNLOADING);
		this.refreshListStatusAll(true);
		var game = this.getGameById(technoId);
		if (game.technology == enumGameTechno.YUMMY_TECHNO) return;
		if (this.exentUpdater) return;
		new PeriodicalExecuter(function(pe) {
            try {
				this.exentUpdater = pe;
				if (game.technology == enumGameTechno.GAMETAP_TECHNO) {
					game.gametapUpdate();
				} else {
                    game.exentUpdate();					
				}
			    this.updateGameInfo(technoId);
            } catch(e) {
				log.err(e);
			}
		}.bind(this), 2); 
	},
	gameDownloadingStopCB: function(technoId) {
		log.debug("stop UI download game : "+technoId)
		this.refreshBg(technoId, enumGameState.DOWNLOAD_STOP);
		this.refreshListStatusAll(false);
		var game = this.getGameById(technoId);
		var processInfo = $('processInfo-' + technoId);
		if (processInfo) {
	    	processInfo.update(game.getDownloadedSize() + '&nbsp;/&nbsp;' + game.getFullSize());
		}
		if (this.exentUpdater) {
			try {
				this.exentUpdater.stop();
				this.exentUpdater = null;
			} catch(e) { log.err('Stop exent update failed'); }
		}
	},
    toggleFavorite: function(event) {
        var current = this.getInfo(event);
        var url = new UrlConstructor('profile/toggle_favorite');
        url.addVar('technoId', current.technoId);
        new Ajax.Request(url.construct(), {
            method: 'get',
            onSuccess: function(transport) {
                var obj = transport.responseText.evalJSON();
                var el = current.element.down('div.favourite');
                if (obj.status == 1) el.addClassName('favourite_inactive');
                else if (obj.status == 2) el.removeClassName('favourite_inactive');
            }
        });
    }
});

GameManager = Class.create({
	initialize: function() {
		this.addClass = 'a.addToDownloadList';
		this.launchClass = 'a.launchGame';
		this.browserClass = 'a.launchBrowserGame';
		this.context = $('context').getValue();
		this.inprocess = {
			technoId: null,
			technology: null,
			browser: false
		};
		this.myEffects = {
			showButtons: 0.4
		};
		this.actionClick = false;
        this.downloadClick = false;
		this.redirectionInProcess = false;
        this.blockYummyDownloadNotification = false;
		if(typeof(Engine) == 'object') {
			log.debug('yummy engine detect. init yummy engine');
			this.initYummyEngineEvents();
		} else {
			log.debug('yummy not detected. init yummy engine was skipped');
		}
        
        if (DEFINE.get('TYPE') == 'GT') {
            this.buttonLoading = new ButtonLoading();
            if (!parseInt(MvcSkel.getVar('isAuth'))) {
                log.debug('show download button. user not logged');
                this.buttonLoading.hide();
                $$('.downloadAction').each(function(el) {
                    this.showElement(el);
                }.bind(this));
            }
            if (browserGame) {
                this.buttonLoading.hide();
                $$('.launchBrowserGame').each(function(el) {
                    this.showElement(el);
                }.bind(this));  
            }
        } else {
            this.initGamePageButtons();
        }
                
		$$(this.addClass).each(function(el) {
			if (!el.hasClassName('addToDownloadList') && !el.hasClassName('launchGame')) return;
			el.observe('click', this.despatcher.bind(this));
		}.bind(this));
		$$(this.launchClass).each(function(el) {
			if (!el.hasClassName('addToDownloadList') && !el.hasClassName('launchGame')) return;
			el.observe('click', this.despatcher.bind(this));
		}.bind(this));
		$$(this.browserClass).each(function(el) {
			el.observe('click', this.despatcher.bind(this));
		}.bind(this));
		if (browserGame) {
			this.initAutorun();
		}
	},
	initYummyEngineEvents: function() {
		try {
			Engine.SetOnPreCacheComplete(this.onPreCacheComplete.bind(this));
			Engine.SetOnCacheComplete(this.onCacheComplete.bind(this));
			Engine.SetOnInstallComplete(this.onInstallComplete.bind(this));
			Engine.SetOnDownloadProgressRawNumbers(this.onDownloadProgressRawNumbers.bind(this));
			Engine.SetOnGameEnded(this.onGameEnded.bind(this));
			Engine.SetOnGameSessionExpired(this.onGameSessionExpired.bind(this));
			Engine.SetOnGameSessionViolation(this.onGameSessionViolation.bind(this));
			Engine.SetOnGameStarted(this.onGameStarted.bind(this));
			Engine.SetOnStateChange(this.onStateChange.bind(this));
			Engine.SetOnGamePatching(this.onGamePatching.bind(this));
//			Engine.SetOnCustomSessionExpireNotice(this.onCustomSessionExpireNotice.bind(this));
//			Engine.SetOnCustomSessionExpired(this.onCustomSessionExpired.bind(this));
		} catch(e) {
			log.info(e);
		}
	},
	onPreCacheComplete: function(technoId, name) {
		log.debug('pre cache complete. technoId:' + technoId + ' name:' + name);
        this.onGameReadyToPlayCB(technoId);
	},
	onCacheComplete: function(technoId, name) {
		log.debug('cache complete. technoId:' + technoId + ' name:' + name);
		// Start Metaboli modification.
		// delete the game from the cookie
		delete_game_in_downloadlist(technoId);
		this.blockYummyDownloadNotification = true;
		// start the next game to download list ONLY YUMMY !!!
		/*var url = new UrlSeoConstructor('ADD_TO_DOWNLOAD_LIST');
		buttonStartDownloadListAllTechno(url.construct());*/
		// End Metaboli modification.
        this.onGameReadyToUse(technoId);
	},
	onInstallComplete: function(technoId, name) {
		log.debug('install complete. technoId:' + technoId + ' name:' + name);
        if (Prototype.Browser.IE) {
        //    CreateShortCuts(technoId, name, DEFINE.get('YUMMY_SHORTCUT_KEY'));
        }
	},
	onDownloadProgressRawNumbers: function(downloadedBytes, totalBytesToPlay, totalBytes, timeToPlay, timeToFull, speedKBSec, technoId, name) {
        if (this.blockYummyDownloadNotification) return ;
		if (this.redirectionCheck(technoId)) return ;
		if (typeof(myGames) == 'object') myGames.updateProgressCB(technoId, downloadedBytes, totalBytesToPlay, totalBytes, timeToPlay, timeToFull, speedKBSec);
		log.debug('download progress. technoId:' + technoId + ' total bytes:' + totalBytes + ' downloaded bytes:' + downloadedBytes);
	},
	onGameEnded: function(technoId, name) {
		log.debug('game ended. technoId:' + technoId + ' name:' + name);
	},
	onGameSessionExpired: function(technoId, name) {
		log.debug('game session expired. technoId:' + technoId + ' name:' + name);
	},
	onGameSessionViolation: function(technoId, name) {
		log.debug('game session violation. technoId:' + technoId + ' name:' + name);
	},
	onGameStarted: function(technoId, name) {
        ww.hide();
        if (this.problematicModal) {
            this.problematicModal.close();
        }
		log.debug('game started. technoId:' + technoId + ' name:' + name);
	},
	onStateChange: function(state, technoId, name) {
		log.debug('state has been changed. state:' + state + ' technoId:' + technoId + ' name:' + name);
		switch(state) {
			case GAME_STATE_NONE :
                this.blockYummyDownloadNotification = true; 
                this.onGameDownloadingStopCB(technoId); 
            break;
			case GAME_STATE_DOWNLOADING: 
                this.blockYummyDownloadNotification = false;
				if (this.redirectionCheck(technoId)) return; 
				this.onGameDownloadingStartCB(technoId); 
			break;
			case GAME_STATE_PRECACHED: break;
			case GAME_STATE_READY: break;
			// Start Metaboli modification.
			case "GAME_STATE_REMOVE_DL":
				// delete the gameId in the cookie for remove to download list
				this.blockYummyDownloadNotification = true;
				delete_game_in_downloadlist(technoId);
			break;
			case "GAME_STATE_REMOVE":
				// delete the gameId in the cookie for remove game or game and saves.
				this.blockYummyDownloadNotification = true;
				delete_game_in_downloadlist(technoId);
			break;
			case "GAME_STATE_ADD_DL":
				// add the gameId in the cookie in the first position
				add_game_first_position_queue_list(technoId+"/yummy");
			break;
			// End Metaboli modification.
		}
	},
	onCustomSessionExpireNotice: function(technoId) {
		log.debug('custom session expire notice. technoId:' + technoId);
	},
	onCustomSessionExpired: function(technoId) {
		log.debug('custom session expired. technoId:' + technoId);
	},
	onGamePatching: function(technoId) {
		log.debug('game patcing');
        var url = new UrlSeoConstructor('PROFILE_GAMES');
        var modal = new Control.Modal(false, {
            contents: i18n('yummyOnGamePatching').replace(/\%my_games\%/, url.construct()),
            fade: true, fadeDuration: 0.4, opacity: 0.8, width: 500, containerClassName: 'mfmodal'
        });
        modal.open();
	},
	exentNotification: function(n) {
		log.debug(n);
    	var xmlDoc = getXmlDoc(n);
    	try {
    		var node = xmlDoc.selectSingleNode( "DownloadListGameStatusChangedNotification/ContentDescriptor" );
    		if (node) {
    			var status = parseInt(node.getAttribute('Status'));
    			var technoId = node.getAttribute('Id');
        		switch (status) {
	     		   case 10 : 
	     		   	log.debug("add to first position the game in the cookie queue : "+technoId)
	     		   	this.onGameAddToListCB(technoId);
	     		   	// Start Metaboli modification.
	     		   	add_game_first_position_queue_list(technoId+"/exent");
	     		   	// End Metaboli modification.
	     		   break;
	     		   case 20 :
	     		   	log.debug("delete the game in the cookie queue: "+technoId)  
	     		   	this.onGameRemoveFromListCB(technoId);
	     		   	// Start Metaboli modification.
	     		   	delete_game_in_downloadlist(technoId);
	     		   	// End Metaboli modification.
	     		   break;
	     		   //case 30 : this.onGameAddToListCB(technoId); break;
	     		}
        		return;
    		}
    	} catch(e) { log.err('Error on DownloadListGameStatusChangedNotification. ' + e.message); }
    	try {
    		var node = xmlDoc.selectSingleNode( "DownloadListStatusChangedNotification/ProviderDescriptor" );
    		if (node) {
    			var status = parseInt(node.getAttribute('Status'));
    			switch (status){
    				case 10 : this.onListStopCB(); break;
    				case 20 : this.onListStartCB(); break;
    			}
    			return;
    		}
    	} catch(e) { log.err('Error on DownloadListStatusChangedNotification. ' + e.message); }
    	try {
    		var node = xmlDoc.selectSingleNode( "GameRemovedNotification/ContentDescriptor" );
    		if (node) {
    			var saveInfo = parseInt(node.getAttribute('SaveInfoKept'));
    			this.onGameRemoveCB(node.getAttribute('Id'), saveInfo);
    			// Start Metaboli modification.
    			delete_game_in_downloadlist(node.getAttribute('Id'));
    			// End Metaboli modification.
    			return;
    		}
    	} catch(e) { log.err('Error on GameRemovedNotification. ' + e.message); }
    	try {
    		var node = xmlDoc.selectSingleNode( "DownloadInfoNotification/ContentDescriptor" );
    		if (node) {
	    		var technoId = node.getAttribute('Id');
	    		var readyToUse = parseInt(node.getAttribute('ReadyToUse'));
	    		var fullyCached = parseInt(node.getAttribute('FullyCached'));
	    		if (readyToUse)  { this.onGameReadyToPlayCB(technoId); }
	    		if (fullyCached) { this.onGameReadyToUse(technoId); delete_game_in_downloadlist(technoId); }  //fix freeze bug at download completion
	    		return;
    		}
    	} catch(e) { log.err('Error on DownloadInfoNotification. ' + e.message); }
    	try {
    		var node = xmlDoc.selectSingleNode( "ExecutionStateNotification/ContentDescriptor" );
    		if (node) {
    			var technoId = node.getAttribute('Id');
    			var active = parseInt(node.getAttribute('Active'));
    			var running = parseInt(node.getAttribute('GameRunning'));
    			var terminating = parseInt(node.getAttribute('Terminating'));
    			var connectionState = parseInt(node.getAttribute('ConnectionState'));
    			var downloadingState = parseInt(node.getAttribute('DownloadingState'));
                var sessionTypeId = parseInt(node.getAttribute('SessionTypeId'));
                log.debug("downloadingState : "+downloadingState+" : "+technoId)    			
    			if (downloadingState == 40) { this.onGameDownloadingStartCB(technoId); };
    			if (active == 0 || connectionState == 10) { this.onGameDownloadingStopCB(technoId); };
                if (running == 1) { this.onGameRunning(technoId); }
        		return;
    		}
    	} catch(e) { log.err('Error on ExecutionStateNotification. ' + e.message); }
    	
	},
    onGameRunning: function(technoId) {
        ww.hide();  
    },
	onGameAddToListCB: function(technoId) {
		if (this.redirectionCheck(technoId)) return; 
		if (typeof(myGames) == 'object') myGames.addToListCB(technoId);
	},
	onGameRemoveFromListCB: function(technoId) {
		if (typeof(myGames) == 'object') myGames.removeFromListCB(technoId);
	},
	onGameRemoveCB: function(technoId, saveInfo) {
		if (typeof(myGames) == 'object') myGames.removeGameCB(technoId, saveInfo);
	},
	onGameReadyToPlayCB: function(technoId) {
		if (typeof(myGames) == 'object') myGames.updateReadyToPlayCB(technoId);
	},
	onGameReadyToUse: function(technoId) {
		if (typeof(myGames) == 'object') myGames.moveGameToCompletedCB(technoId);
	},
	onListStopCB: function() {
		if (typeof(myGames) == 'object') myGames.refreshListStatusAll(false);
	},
	onListStartCB: function() {
		if (typeof(myGames) == 'object') myGames.refreshListStatusAll(true);
	},
	onGameDownloadingStartCB: function(technoId) {
		ww.hide();
		if (typeof(myGames) == 'object') myGames.gameDownloadingStartCB(technoId);
	},
	onGameDownloadingStopCB: function(technoId) {
		if (typeof(myGames) == 'object') myGames.gameDownloadingStopCB(technoId);
	},
	redirectionCheck: function(technoId) {
		if (this.redirectionInProcess) return true;
		if (this.context != 'profile_games' && this.actionClick) {
			this.redirectionInProcess = true;
            var url = new UrlSeoConstructor('PROFILE_GAMES');
            window.location = url.construct();
            return true;
		}
		return false;
	},
	getParamsString: function(p) {
		if (!Object.isString(p)) {
			p = Event.element(p);
            if (p.tagName.toLowerCase() != 'a') {
			    p = p.up('a');
            }
			if (p.href) {
                return p.href;
            }
		}
		return p;
	},
	getGameInfoFromString: function(str) {
		try {
			var res = this.getParamsString(str).match(/#([a-z]+)_(.+)_([a-z]+)_(\d+)$/i);
			return {
				action: res[1],
				title: res[2],
				technology: res[3],
				technoId: res[4]
			}
		} catch(e) {
			return false;
		}
	},
	despatcher: function(p) {
		try {
			var info = this.getGameInfoFromString(p);
			if (!info) return ;
			if (this.actionClick) return ;
			this.actionClick = true;
			switch (info.action) {
			   case 'download' :
				   this.addToDownloadList(info.technoId, info.technology, 1, info.title);
				   break;
			   case 'launch' :
				   this.launch(info.technoId, info.technology, 1);
				   break;
			   case 'browser' :
				   this.launchBrowserGame(info.technoId, info.technology);
				   break;
			} 
		} catch(e) {
			log.err(e);
		}
	},
	initGamePageButtons: function() {
        if (!parseInt(MvcSkel.getVar('isAuth'))) {
            $$('.downloadAction').each(function(el) {
                this.showElement(el);
            }.bind(this));
            return false;
        }
        var metaGame = null;
        $$('.downloadAction').each(function(el) {
            try {
                if (!metaGame) {
                    var info = this.getGameInfoFromString(el.href ? el.href : el.down('.action').href);
                    log.debug('Game techno id: ' + info.technoId);
                    metaGame = new MetaGame(info.technoId, info.technology);
                }
                if (!isOk || !metaGame.isReady()) this.showElement(el);
            } catch(e) {
            	log.err(e);
                this.showElement(el);
            }
        }.bind(this));

        $$('.launchAction').each(function(el) {
            try {
                if (!metaGame) {
                    var info = this.getGameInfoFromString(el.href ? el.href : el.down('.action').href);
                    metaGame = new MetaGame(info.technoId, info.technology);
                }
                if (isOk && metaGame.isReady()) this.showElement(el);
            } catch(e) {
            	log.err(e);
            }
        }.bind(this));

        if (metaGame && isOk && metaGame.isReady()) {
            var btnMultiPlayer = $$('div.buttonMultiplayer').first();
            var buttonOptions = $$('div.buttonOptions').first();
            var btnSubscribe = $('btnSubscribe');
            if (buttonOptions) this.showElement(buttonOptions, 'end');
            if (btnMultiPlayer) this.showElement(btnMultiPlayer, 'end');
            if (btnSubscribe) {
            	var gameId = btnSubscribe.down('a.subscribe').href.match(/.+_(\d+)$/)[1];
        		if (metaGame.isFullyCached()) {
        			this.showElement(btnSubscribe, 'end');
        			Event.observe(btnSubscribe, 'click', function() {
                		var url = new UrlConstructor('game/subscribe');
                		url.addVar('gameId', gameId);
                		window.open(url.construct(), '', 'width=1100,height=800,menubar=no,toolbar=no,location=no,scrollbars=yes');
        			});
        		}
            }
        }
	},
	initGamePageButtonsV2: function() {
        log.debug('init download/launch buttons. user logged');
        this.buttonLoading.hide();
        var launchMetaGame = null;
        //var exit = false;
        $$('.launchAction').each(function(el) {
            //if (exit) return;
            try {
                var btn = el.href ? el.href : el.down('.action').href;
                var info = this.getGameInfoFromString(btn);
                metaGame = new MetaGame(info.technoId, info.technology);
                if (isOk && metaGame.isReady()) {
                    this.showElement(el);
                    launchMetaGame = metaGame;
                    //exit = true;
                } 
            } catch(e) {
                log.err(e);
            }
        }.bind(this));
        
        if (launchMetaGame && isOk && launchMetaGame.isReady()) {
            var btnMultiPlayer = $('multiplayer-' + launchMetaGame.technoId);
            if (btnMultiPlayer) this.showElement(btnMultiPlayer, 'end');
            /*            
            var buttonOptions = $$('div.buttonOptions').first();
            var btnSubscribe = $('btnSubscribe');
            if (buttonOptions) this.showElement(buttonOptions, 'end');
            if (btnSubscribe) {
                var gameId = btnSubscribe.down('a.subscribe').href.match(/.+_(\d+)$/)[1];
                if (metaGame.isFullyCached()) {
                    this.showElement(btnSubscribe, 'end');
                    Event.observe(btnSubscribe, 'click', function() {
                        var url = new UrlConstructor('game/subscribe');
                        url.addVar('gameId', gameId);
                        window.open(url.construct(), '', 'width=1100,height=800,menubar=no,toolbar=no,location=no,scrollbars=yes');
                    });
                }
            }
            */
        }
        
        if (!launchMetaGame) {
            $$('.downloadAction').each(function(el) {
                try {
                    var btn = el.href ? el.href : el.down('.action').href;
                    var info = this.getGameInfoFromString(btn);
                    metaGame = new MetaGame(info.technoId, info.technology);
                    if (!isOk || !metaGame.isReady()) this.showElement(el);
                } catch(e) {
                    log.err(e);
                    this.showElement(el);
                }
            }.bind(this));
        }
	},
	showElement: function(el, q) {
        q = q ? q : '';
		el.setOpacity(0);
		el.removeClassName('displayNone');
		new Effect.Opacity(el, {
			queue: q, 
			from: 0.0, to: 1.0, 
			duration: this.myEffects.showButtons, 
			transition: Effect.Transitions.sinoidal
		});
	},
    initFavorites: function() {
        $$('div.favoriteItem').each(function(el) {
            var info = this.getGameInfoFromString(el.down('a.action').href);
            if (isOk) {
                metaGame = new MetaGame(info.technoId, info.technology);
                if (metaGame.isReady()) this.favoritesShowLaunch(info.technoId);
                else this.favoritesShowDownload(info.technoId);
            } else {
                this.favoritesShowDownload(info.technoId);
            }
        }.bind(this));    
    },
    favoritesShowLaunch: function(technoId) {
        $('play-' + technoId).removeClassName('displayNone');
        if (!$('expand-' + technoId)) return;
        if ($('expand-' + technoId).down('ul.optionList').childElements().size() > 1) {
            $('options-' + technoId).removeClassName('displayNone');
        }
    },
    favoritesShowDownload: function(technoId) {
        $('download-' + technoId).removeClassName('displayNone');
		if (!$('download-info-' + technoId)) return ;
        $('download-info-' + technoId).removeClassName('displayNone');
    },
	addToDownloadList: function(technoId, technology, cmd, title) {
    	log.debug('addToDownloadList call. Params: ' + technoId +' '+ technology +' '+ cmd +' '+ title);
        this.playerVersionCheck(technology, function() {
            var checkGameUrl = new UrlConstructor('profile/game_checker');
            checkGameUrl.addVar('process', 'download');
            checkGameUrl.addVar('technoId', technoId);
            checkGameUrl.addVar('technology', technology);
            checkGameUrl.addVar('commandLine', cmd);
            new Ajax.Request(checkGameUrl.construct(), {
                method: 'get',
                onSuccess: function(transport) {
            		var obj = transport.responseText.evalJSON();
                    this.checkUp(obj, function() {
                        var url = new UrlSeoConstructor('ADD_TO_DOWNLOAD_LIST');
                        log.debug('Checkup success. Call addToDownloadListAllTechno params: ' 
                        		+ url.construct() +' '+ technoId +' '+ cmd +' '+ technology +' '+ title);
                        this.downloadClick = technoId;
                        addToDownloadListAllTechno(url.construct(), technoId, cmd, technology, title);
                    }.bind(this));
                }.bind(this)
            });
        }.bind(this));
	},
	launch: function(technoId, technology, cmd) {
		log.debug('launch call. Params: ' + technoId +' '+ technology +' '+ cmd);
        this.playerVersionCheck(technology, function() {
		    var checkGameUrl = new UrlConstructor('profile/game_checker');
            checkGameUrl.addVar('process', 'launch');
		    checkGameUrl.addVar('technoId', technoId);
		    checkGameUrl.addVar('technology', technology);
            checkGameUrl.addVar('commandLine', cmd);
            new Ajax.Request(checkGameUrl.construct(), {
                method: 'get',
                onSuccess: function(transport) {
            		var obj = transport.responseText.evalJSON();
                    this.checkUp(obj, function() {
                		var url = new UrlSeoConstructor('LAUNCH_GAME');
                        this.inprocess.browser = false;
                        this.inprocess.technoId = technoId;
                		log.debug('call launchGameAllTechno');
                		launchGameAllTechno(url.construct(), technoId, cmd, technology);
                    }.bind(this));
        	    }.bind(this)
            });
        }.bind(this));
	},
	launchBrowserGame: function(technoId, technology) {
		log.debug('launchBrowserGame call. Params: ' + technoId +' '+ technology);
		if (typeof(playerLogin) == 'undefined' || typeof(ssoToken) == 'undefined') {
			log.err('web player login failed');
            var url = new UrlSeoConstructor('PROFILE_GAMES');
            window.location = url.construct();            
			return false;
		};
        var cntx = $('context').getValue();
		if (!/game_.*/.test(cntx)) {
			var speedLaunchBrowserGame = new UrlSeoConstructor('SPEED_LAUNCH');
			speedLaunchBrowserGame.addVar('gameId', technoId);
			window.location = speedLaunchBrowserGame.construct();
		}
	    var checkGameUrl = new UrlConstructor('profile/game_checker');
        checkGameUrl.addVar('process', 'browser');
	    checkGameUrl.addVar('technoId', technoId);
	    checkGameUrl.addVar('technology', technology);
        new Ajax.Request(checkGameUrl.construct(), {
            method: 'get',
            onSuccess: function(transport) {
        		var obj = transport.responseText.evalJSON();
                this.checkUp(obj, function() {
	            	$('containerBrowser').removeClassName('displayNone');
                    $('controlsDrawerContainer').removeClassName('displayNone');
                    gameControls.initVolume();
	            	this.inprocess.browser = true;
	            	this.inprocess.technoId = technoId;
					$('nameGameProduct').scrollTo();
					var img = $('btContainer').down('img'); 
                    if (img) img.src = img.src.replace(/_play/, '_play_disabled');
					img.up('a').href = 'javascript:void(0)';
                    webPlayer = new WebPlayer(playerLogin, ssoToken, technoId, 'browserPlayer');
	            	//insertComponentsTechnoEmulator(playerLogin, ssoToken, technoId, 'browserPlayer');
                }.bind(this));
    	    }.bind(this)
        });
	},
	updateBrowserGameController: function() {
		if (!this.inprocess.browser) return false;
		log.debug('Browser game in process: ' + this.inprocess.technoId);
		var controllerId = new String(player_getJoystickControllerId());
		if (controllerId.empty()) {
			return ;
			//controllerId = 'C218046D-0000-0000-0000-504944564944';
		}
		try {
        	var controlUrl = new UrlConstructor('game/browser_controller');
        	controlUrl.addVar('controllerId', controllerId);
        	controlUrl.addVar('technoId', this.inprocess.technoId);
        	log.debug('Controller: ' + controllerId);
            new Ajax.Request(controlUrl.construct(), {
                method: 'get',
                onSuccess: function(transport) {
					$('drawerJoypad').down('.contentKeyboardsBox').update(transport.responseText);
					gameControls.joypadActive();
        	    }.bind(this)
            });
    	} catch(e) {
    		log.err(e);
    	}
	},
    checkUp: function(obj, callback) {
        var run = true;
        if (obj.redirect) {
        	log.stop('Need redirect to: ' + obj.redirect);
            window.location = obj.redirect;
            return;
        }
        if (obj.previous) {
            var prevGame = new MetaGame(obj.previous.technoId, obj.previous.technology);
            if (prevGame.isReady()) {
                if (obj.previous.browser) {
                    this.launchBrowserGame(obj.previous.technoId, obj.previous.technology);
                } else {
                    this.launch(obj.previous.technoId, obj.previous.technology, 1);    
                }
                return;
            }
        }
        if (obj.gldeavs) {
            run = false;
            var modalGlde = new Control.Modal(false, {
                contents: i18n('loadingDialog'),
                fade: true, fadeDuration: 0.4, opacity: 0.8,
                width: 750, containerClassName: 'mfmodal'
            });
            modalGlde.open();
            var urlGldeAvs = new UrlConstructor('Glde/Avs');            
            new Ajax.Request(urlGldeAvs.construct(), {
                onComplete: function(request){
                    modalGlde.update(request.responseText);
                    Event.observe('avsButton', 'click', function() {
                        var exteralUrl = getExternalUrl('https') + 'gamesload/gsp/login.aspx' + 
                            '?provider=metaboli&avs=true&metaboli_avs=true' +
							'&MasterID=' + obj.info.technoId + 
							'&technology=' + obj.info.technology + 
							'&product_id=' + obj.info.gameId + 
							'&commandLine=' + obj.info.commandLine +
							'&act=' + obj.info.process +
                            '&st2=' + obj.info.st2;
                            window.open(exteralUrl, '', 'width=640,height=480,menubar=no,toolbar=no,location=no,scrollbars=yes');
                    });
                    Event.observe('modalClose', 'click', function() {
                        modalGlde.close();
                    }.bind(this));
                }.bind(this)
            });
            return;
        }
        /* credit card alerts */
        if (DEFINE.get('CREDITCARD_ALERT') && obj.html) {
            run = false;
            var modal = new Control.Modal(false, {
                contents: obj.html, fade: true, fadeDuration: 0.4, opacity: 0.8,
                overlayCloseOnClick: false,
                containerClassName: 'launch',
                afterOpen: function() {
                    if ($('continueActive') && $('continueUnactive')) {
                        var counter = 15;
                        if ($('timerImg')) {
                            new PeriodicalExecuter(function(pe) {
                                    $('timerImg').src = $('timerImg').src.replace(/_(\d+)\.gif$/i, function(str, p1) {
                                            p1 = parseInt(p1);
                                            p1 = (p1 == 1) ? 2 : 1;
                                            return '_' + p1 + '.gif';
                                    });
                                    $('timerCounter').update(counter);
                                    if (counter < 10) {
                                        $('timerCounter').addClassName('s');
                                    }
                                    if (counter == 0) {
                                        pe.stop();
                                        $('continueUnactive').addClassName('displayNone');
                                        $('continueActive').removeClassName('displayNone');
                                    }
                                    counter--;
                            }, 1);
                        }
                    }
                    Event.observe('continueActive', 'click', function() {
                            modal.close();
                            callback();
                    });
                }
            });
            modal.open();
            this.actionClick = false;
        }
        /* end of credit card alerts */        
        var er = new ErrorManager(obj);
        if (er.getErrors()) {
        	log.err('error(s) detected');
        	run = false;
            this.actionClick = false;
        }
        log.debug('checkUp status: ' + (run ? 'true' : 'false'));
        if (run) {
            this.blockYummyDownloadNotification = true;
            if (obj.problematic) {
                this.problematicModal = new Control.Modal(false, {
                    contents: obj.problematic,
                    overlayCloseOnClick: false, 
                    width: 600, fade: true, fadeDuration: 0.4, opacity: 0.8, containerClassName: 'mfmodal problematic',
                    afterEffect: function() {
                        setTimeout(function() { callback(); }, 1000);  
                    }
                });
                this.problematicModal.open();
            } else {
                callback();  
            }
        } 
    },
    playerVersionCheck: function(technology, callback) {
        if (!isOk) {
			if (parseInt(MvcSkel.getVar('isAuth')) == 0) {
                var url = new UrlSeoConstructor('INDEX_OFFERS');
				url.addVar('gameId', MvcSkel.getVar('gameId'));
                log.stop('user not logged');
                window.location = url.construct();            
			} else {
	            var url = new UrlSeoConstructor('PROFILE_GAMES');
	            log.stop('isDrmReadyOnClientComputer failed');
                window.location = url.construct();            
			}
        } else {
        	log.debug('isDrmReadyOnClientComputer success');
            if ([enumGameTechno.EXENT_TECHNO, enumGameTechno.YUMMY_TECHNO].include(technology)) {
                if (isTheGoodVersionInstalledMultiTechno(DEFINE.get('PLAYER_EXENT_VERSION'), DEFINE.get('PLAYER_YUMMY_VERSION'))) {
                    ww.show(function() {
                        log.debug('wait window is appear. call callback');
                        callback();
                    });
                } else {
                    var url = new UrlSeoConstructor('PROFILE_GAMES');
                    log.stop('Update player required');
                    window.location = url.construct();            
                }                
            } else {
                ww.show(function() {
                    log.debug('wait window is appear. call callback');
                    callback();
                });
            }
        }
    },
    initAutorun: function() {
        var autorun = $('speedLaunch');
        if (!autorun) return;
        log.debug('try autorun game. params: ' + autorun.value);
        var res = autorun.value.match(/(\d+)_(.+)_(\d+)_(.+)/);
        var technoId = res[1];
        var technology = res[2];
        var commandLine = res[3];
        var action = res[4];
        if (action == 'browser') {
        	this.launchBrowserGame(technoId, technology);
        } else if (action == 'launch') {
            this.launch(technoId, technology, commandLine);
        } else {
            this.addToDownloadList(technoId, technology, commandLine, '');
        }
    },
	myact1: function() {
		myGames.moveGameToCompletedCB(441050);
    },
	myact2: function() {
		myGames.moveFromDownloadedToNotInDownload(278854);
	},
	myact3: function() {
		myGames.addToListCB(448054);
	}
});

ButtonLoading = Class.create({
    initialize: function() {
        this.s = $('waitInit');
        if (!this.s) return; 
        this.eff = this.s.down('span');
        this.perExecuter = null;
        this.counter = 1;
        this.initLoading();
    },
    initLoading: function() {
        new PeriodicalExecuter(function(pe) {
            this.perExecuter = pe;
            this.eff.update('.'.times(this.counter++));
            if (this.counter > 3) this.counter = 0;
        }.bind(this), 0.5);
    },
    hide: function() {
        if (this.perExecuter) this.perExecuter.stop();
        if (this.s) this.s.hide();
    }
});

GamePage = Class.create({
    initialize: function() {
        try {
            this.gameId = $('gameId').getValue();
        } catch(e) {
            return false;
        }
        this.initFavorites('addGame');
        this.initFavorites('listGame');
        this.initAddRemoveFavorites();
    },
    initFavorites: function(elId) {
        if (!$(elId)) { return false; }
        Event.observe(elId, 'mouseover', function(event) {
            clearTimeout(this.ftimer);
            this.showFavoriteTip(elId);
        }.bind(this));
        Event.observe(elId, 'mouseout', function(event) {
            this.closeFavoriteTip(elId);
        }.bind(this));
    },
    showFavoriteTip: function(el) {
        if ($(el).down('div')) {
            $(el).down('div').setStyle({
                display: 'block'
            });
        }
    },
    closeFavoriteTip: function(el) {
        this.ftimer = setTimeout(function() {
            if ($(el).down('div')) {
                $(el).down('div').setStyle({
                    display: 'none'
                });
            }
        }, 1000);
    },
    initAddRemoveFavorites: function() {
        if (!$('addGame') || !$('listGame')) { return false; }
        Event.observe('addGame', 'click', function() {
            var url = new UrlConstructor('favorite/add');
            url.setAction(true);
            url.addVar('id', this.gameId);
            new Ajax.Request(url.construct(), {
                onSuccess: function(transport, json) {
                    this.toggleFavoritesIcon();
                }.bind(this)
            });
        }.bind(this));
        Event.observe('listGame', 'click', function() {
            var url = new UrlConstructor('favorite/remove');
            url.setAction(true);
            url.addVar('id', this.gameId);
            new Ajax.Request(url.construct(), {
                onSuccess: function(transport, json) {
                    this.toggleFavoritesIcon();
                }.bind(this)
            });
        }.bind(this));
    },
    toggleFavoritesIcon: function() {
        if ($('addGame').getStyle('display') == 'block') {
            $('addGame').setStyle({display: 'none'});
            $('listGame').setStyle({display: 'block'});
            if ($('bubbleGT')) {
                $('bubbl2').removeClassName('displayNone');
                $('bubbl1').addClassName('displayNone');
            }
        } else {
            $('addGame').setStyle({display: 'block'});
            $('listGame').setStyle({display: 'none'});
            if ($('bubbleGT')) {
                $('bubbl1').removeClassName('displayNone');
                $('bubbl2').addClassName('displayNone');
            }
        }
    }
});

if (typeof(browserGame) == 'undefined') {
	browserGame = false;
}

if (typeof(displayErrorMessage) == 'undefined') {
    function displayErrorMessage(errorCode) {
        log.debug('display error message. code: ' + errorCode);
        var err = new ModalErrorWindow(errorCode);
        err.open();
        if (gameManager) gameManager.actionClick = false;
    }
}

var enumGameState = {DOWNLOADING: 'DOWNLOADING', DOWNLOAD_STOP: 'DOWNLOAD_STOP', RUNNING: 'RUNNING'};
var gameManager = null;
isOk = (typeof(isOk) == 'undefined') ? false : isOk;

Event.observe(window, 'load', function() {
	log.debug('Player(s) isOk: ' + (isOk ? 'true' : 'false'));
	gameManager = new GameManager();
    if (typeof(__meta) != 'undefined' && __meta) {
        gameManager.initFavorites();
        gameManager.initAutorun();
    }
});
