var AppInfo = {
	url: 'http://powerarrow-myspace.appspot.com/',
	gid: 'FSPARROW',
	title: 'Power Arrow',
	link: 'http://profile.myspace.com/Modules/Applications/Pages/Canvas.aspx?appId=129097',
	logo: 'http://powerarrow-myspace.appspot.com/image/logo.gif'
};
/**
*	Class name : OpenSocial
*
*	Instances :
*		os : opensocial container
*		os_token : myspace opensocial token
*		dataReqObj : object of data request
*	Methods :
*		init() : initialization function for opensocial
*		ajax() : ajax function using opensocial io gadget
*/
var OpenSocial = {
	/* Instances */
	os: null,
	os_token: null,
	dataReqObj: null,
	/* Methods */
	init : function (callback) {
		this.os = opensocial.Container.get();
		this.os_token = MyOpenSpace.MySpaceContainer.OSToken;

		this.dataReqObj = this.os.newDataRequest();
		
		if (typeof (callback) === 'function') {
			callback();
		}
	},
	/**
	*	method name : ajax()
	*
	*	url : target url of ajax request
	*	data : post data of ajax request
	*	callback: callback function of ajax request
	*/
	ajax : function (url, data, callback) {
		if (typeof(callback) === 'function') {
			var params = {};
		
			params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.JSON;
			params[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType.POST;
			params[gadgets.io.RequestParameters.POST_DATA]= gadgets.io.encodeValues(data);
			params[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType.SIGNED;
			
			gadgets.io.makeRequest(url, callback, params);
		}
		else {
			try {	// for firefox javscript console
				console.log('callback parameter makes error.');
			}
			catch (e) {
			}
		}
	}
};

/**
*	Class name : UserInfo
*
*	Instances :
*		uid : uid of viewer
*		name : display name of viewer
*		thumb : thumbnail image of viewer
*		profile_link : profile link of viewer
*	Methods :
*		req() : retrieve user inforamtion
*		reqCallback() : callback function for userReq()
*		update() : update user information to database
*/
var UserInfo = {
	/* instances */
	uid : null,
	name : null,
	thumb : null,
	profile_link : null,
	key: null,	// for google app engine datastore
	/* methods */
	req : function () {
		var viewerReq = OpenSocial.os.newFetchPersonRequest(opensocial.IdSpec.PersonId.VIEWER);

		OpenSocial.dataReqObj.add(viewerReq, 'userInfo');
		OpenSocial.dataReqObj.send(UserInfo.reqCallback);
	},
	reqCallback : function (res) {
		if (res.hadError()) {
			var data = res.get('userInfo');
			
			try {
				console.log(data.getErrorCode() + '\n' + data.getErrorMessage());	
			}
			catch(e) {
				
			}
		}
		else {
			var viewer = res.get('userInfo').getData();

			UserInfo.uid = viewer.getId();
			UserInfo.name = viewer.getDisplayName();
			UserInfo.thumb = viewer.getField(opensocial.Person.Field.THUMBNAIL_URL);
			UserInfo.profile_link = viewer.getField(opensocial.Person.Field.PROFILE_URL);

			UserInfo.update();
		}
	},
	update : function () {
		var data = {
			uid: this.uid,
			name: this.name,
			thumb: this.thumb,
			profile_link: this.profile_link
		};
		
		var url = AppInfo.url + 'member/add';
		
		OpenSocial.ajax(url, data, function (res) {
			if (res.data['error'] === 0) {
				UserInfo.key = res.data['data']['user_key'];	// for google app engine datastore

				$('win').update(res.data['data']['win']);
				$('lose').update(res.data['data']['lose']);
				$('best_score').update(res.data['data']['best_score']);
				
				Game.skip_howto = res.data['data']['skip_howto'];
				Game.view();

				Challenge.page = 0;
				Challenge.viewReceivedChallenges();

				$('challengeNext').observe('click', function () {
					Challenge.page += 1;
					Challenge.viewReceivedChallenges();
				});
				$('challengePrev').observe('click', function () {
					if (Challenge.page > 0) {
						Challenge.page -= 1;
						Challenge.viewReceivedChallenges();
					}
				});
				
				FriendsInfo.init('app', Rank.init);
			}
		});
	}
};

/**
*	Class name : FriendsInfo
*
*	Instances :
*		list : list of viewer's friends
*		obj : json obj of viewer's friends
*		callback : callback function for friends request
*		first : start number of friends request; default = 0
*/
var FriendsInfo = {
	/* instances */
	mode: 'app',
	added: [],
	data: [],
	callback: null,
	first: 1,
	max: 20,
	/* methods */
	init : function (mode, callback) {
		FriendsInfo.mode = mode;
		FriendsInfo.first = 1;

		if (typeof (callback) === 'function') {
			FriendsInfo.callback = callback;
		}
		
		if (FriendsInfo.mode === 'app') {
			FriendsInfo.added = [];
		}
		else if (FriendsInfo.mode === 'all') {
			FriendsInfo.data = [];
		}
		
		FriendsInfo.req();
	},
	req : function () {
		var params = {};
		params[opensocial.DataRequest.PeopleRequestFields.FIRST] = FriendsInfo.first;
		params[opensocial.DataRequest.PeopleRequestFields.MAX] = FriendsInfo.max;
		params[opensocial.DataRequest.PeopleRequestFields.SORT_ORDER] = opensocial.DataRequest.SortOrder.NAME;
		
		if (FriendsInfo.mode === 'all') {
			params[opensocial.DataRequest.PeopleRequestFields.FILTER] = opensocial.DataRequest.FilterType.ALL;
		}
		else if (FriendsInfo.mode === 'app') {
			params[opensocial.DataRequest.PeopleRequestFields.FILTER] = opensocial.DataRequest.FilterType.HAS_APP;
		}

		var friendsIdSpec = opensocial.newIdSpec({'userId' : 'VIEWER', 'groupId' : 'FRIENDS'});
		
		var viewerFriendsReq = OpenSocial.os.newFetchPeopleRequest(friendsIdSpec, params);
		OpenSocial.dataReqObj.add(viewerFriendsReq, 'friendsReq');
		
		OpenSocial.dataReqObj.send(FriendsInfo.reqCallback);
	},
	reqCallback : function (res) {
		if (res.hadError()) {
			var data = res.get('friendsReq');
			try {
				console.log(data.getErrorCode() + '\n' + data.getErrorMessage());	
			}
			catch (e) {
				
			}
		}
		else {
			var obj = res.get('friendsReq').getData();
			
			if (FriendsInfo.mode === 'app') {
				obj.each(function (friend) {
					FriendsInfo.added.push(friend.getId());
				});
			}
			else if (FriendsInfo.mode === 'all') {
				var handle_list = false;
				obj.each(function (friend) {
					FriendsInfo.data.push({
						'uid': friend.getId(),
						'name': friend.getDisplayName(),
						'thumb': friend.getField(opensocial.Person.Field.THUMBNAIL_URL),
						'profile_link': friend.getField(opensocial.Person.Field.PROFILE_URL),
						'has_app': FriendsInfo.added.indexOf(friend.getId()) === -1 ? false : true
					});
				});
			}
			
			if (obj.getTotalSize() < FriendsInfo.max) {
				FriendsInfo.first = 1;
				
				if (FriendsInfo.mode === 'app') {
					FriendsInfo.added.push(UserInfo.uid);
				}
				
				if (typeof (FriendsInfo.callback) === 'function') {
					FriendsInfo.callback();
				}
			}
			else {
				FriendsInfo.first += FriendsInfo.max;
				FriendsInfo.req();
			}
		}
	}
};

var Challenge = {
	key: null,
	page: 0,
	send: function (receiver_uid) {
		var data = {
			sender_key: UserInfo.key,
			receiver_uid: receiver_uid,
			score: Game.score
		};
		
		OpenSocial.ajax(AppInfo.url + 'challenge/send', data, function (res) {
			
		});
	},
	accept: function () {
		var data = {
			challenge_key: Challenge.key
		};
		
		OpenSocial.ajax(AppInfo.url + 'challenge/accept', data, function (res) {
			if (res.data['error'] === 0) {
				var data = res.data['data'];
				
				Game.mode = 1;
				Game.view();
				
				$('receivedChallengesWrapper').hide();
				$('vsWrapper').show();

				var strTemplate	=	'<h4>#{receiver_name} (You)</h4>' +
									'<div id=\"vs_#{receiver_uid}\">' +
									'	<img src=\"#{receiver_thumb}\" />' +
									'	<h4 class=\"score\">Score</h4>' +
									'	<span id=\"vsScore_#{receiver_uid}\">#{receiver_score}</span>' +
									'</div>' +
									'<div class=\"vs\">VS</div>' +
									'<h4>#{sender_name}</h4>' +
									'<div id=\"vs_#{sender_uid}\">' +
									'	<img src=\"#{sender_thumb}\" />' +
									'	<h4 class=\"score\">Score</h4>' +
									'	<span>#{sender_score}</span>' +
									'</div>';
				var template = new Template(strTemplate);
				
				$('vsWrapper').update(
					template.evaluate(
						{
							receiver_uid: data['receiver']['uid'],
							receiver_name: data['receiver']['name'],
							receiver_thumb: data['receiver']['thumb'],
							receiver_score: 'have not played',
							sender_uid: data['sender']['uid'],
							sender_name: data['sender']['name'],
							sender_thumb: data['sender']['thumb'],
							sender_score: data['sender']['score']
						}
					)
				);
				
				strTemplate	=	'<div id=\"challengeResult_#{receiver_uid}\">' +
								'	<img src=\"#{receiver_thumb}\" />' +
								'	<h4>#{recevier_name} (You)</h4>' +
								'	<h4>Score</h4>' +
								'	<span id=\"challengeResultScore_#{receiver_uid}\">#{receiver_score}</span>' +
								'</div>' +
								'<div id=\"challengeResult_#{sender_uid}\">' +
								'	<img src=\"#{sender_thumb}\" />' +
								'	<h4>#{sender_name}</h4>' +
								'	<h4>Score</h4>' +
								'	<span>#{sender_score}</span>' +
								'</div>';
				
				template = new Template(strTemplate);

				$('challengeResult').update(
					template.evaluate(
						{
							receiver_uid: data['receiver']['uid'],
							receiver_name: data['receiver']['name'],
							receiver_thumb: data['receiver']['thumb'],
							receiver_score: 'have not played',
							sender_uid: data['sender']['uid'],
							sender_name: data['sender']['name'],
							sender_thumb: data['sender']['thumb'],
							sender_score: data['sender']['score']
						}
					)
				);
			}
		});
	},
	ignore: function () {
		var data = {
			challenge_key: Challenge.key
		};
		
		OpenSocial.ajax(AppInfo.url + 'challenge/ignore', data, function (res) {
			if (res.data['error'] === 0) {
				$('receivedChallenges').update('');
				Challenge.viewReceivedChallenges();
			}
		});
	},
	viewReceivedChallenges: function () {
		$('receivedChallenges').hide();
		$('sidebar', 'receivedChallengesWrapper', 'sidebarLoading').invoke('show');
		
		var data = {
			user_key: UserInfo.key,
			page: Challenge.page
		}
		
		OpenSocial.ajax(AppInfo.url + 'challenge/view', data, function (res) {
			if (res.data['error'] === 0) {
				$('receivedChallenges').update('');
				
				res.data['challenges'].each(function (friend) {
					var strTemplate	=	'<li id=\"challengeLi_#{challenge_key}\">' +
										'	<img src=\"#{sender_thumb}\" />' +
										'	<span class=\"name\">#{sender_name}</span>' +
										'	<span class=\"score\">#{sender_score}</span>' +
										'	<span class=\"button small\">' +
										'		<button id=\"challengeBtn_#{challenge_key}\" type=\"button\">Accept</button>' +
										'		<button id=\"ignoreBtn_#{challenge_key}\" type=\"button\">Ignore</button>' +
										'	</span>' +
										'</li>';
					
					var challengeTemplate = new Template(strTemplate);
					
					$('receivedChallenges').insert(
						challengeTemplate.evaluate(
							{
								challenge_key: friend['challenge_key'],
								sender_thumb: friend['sender_thumb'],
								sender_name: friend['sender_name'],
								sender_score: friend['sender_score']
							}
						)
					);
											
					$('challengeBtn_' + friend['challenge_key']).observe('click', function (event) {
						Game.mode = 1;
						Challenge.key = friend['challenge_key'];
						Challenge.accept();
					});
					$('ignoreBtn_' + friend['challenge_key']).observe('click', function (event) {
						Game.mode = 0;
						Challenge.key = friend['challenge_key'];
						Challenge.ignore();
					});
				});
			}
			else {
				if (Challenge.page > 0) {
					Challenge.page -= 1;
					Challenge.viewReceivedChallenges();
				}
			}
			
			$('sidebarLoading').hide();
			$('receivedChallenges').show();
		});
	},
	viewFriendsList: function () {
		if (FriendsInfo.data.size() > 0) {
			var strTemplate	=	'<li>' +
								'	<a id=\"challengeUser_#{uid}\">' +
								'		<span class="name">#{name}</span>' +
								'		<span class="thumb">' +
								'			<img src=\"#{thumb}\" />' +
								'		</span>' +
								'		<img class=\"msgType\" src=\"#{msg_img}\" alt=\"#{msg_type}\" />' +
								'	</a>' +
								'	<input type=\"hidden\" name=\"hasapp[]\" id=\"hasapp_#{uid}\" value=\"#{has_app}\" />' +
								'</li>';

			var friendsTemplate = new Template(strTemplate);

			FriendsInfo.data.each(
				function (friend) {
					$('friendsList').insert(
						friendsTemplate.evaluate(
							{
								'uid': friend['uid'],
								'thumb': friend['thumb'],
								'name': friend['name'],
								'msg_img': AppInfo.url + (friend['has_app'] ? 'image/comment_icon.gif' : 'image/invite_icon.gif'),
								'msg_type': friend['has_app'] ? 'added' : 'have not added',
								'has_app': friend['has_app']
							}
						)
					);
				}
			);
			
			FriendsSelector.init();
		}
	}
};

var Feed = {
	selectedFriends: null,
	idx: 0,
	callback: null,
	init : function (callback) {
		Feed.selectedFriends = [];
		var selected = $('friendsList').getElementsByClassName('selected');
		
		for (var idx = 0; idx < selected.length; ++idx) {
			var uid = selected[idx].id.split('_')[1];
			Feed.selectedFriends.push({
				uid: uid,
				name: selected[idx].getElementsByClassName('name')[0].innerHTML,
				hasapp: $('hasapp_' + uid).value
			});
		}
		
		Feed.idx = 0;
		
		if (typeof (callback) === 'function') {
			Feed.callback = callback;
		}
		
		if (Feed.selectedFriends.size() > 0) {
			Feed.send();
		}
	},
	send : function () {
		if (typeof (Feed.callback) === 'function') {
			Feed.callback(Feed.selectedFriends[Feed.idx].uid);
		}
		
		if (Feed.selectedFriends[Feed.idx].hasapp === 'true') {
			var strTemplate	= 	'<img src=\"#{logo}\" alt=\"#{title}\" />' +
								'<p>' +
								'	#{sender} has just challenged you at #{title}! ' +
								'	<a href=\"#{link}\">Click here to accept the challenge.</a>' +
								'</p>';

			var template = new Template(strTemplate);
			
			var msg = opensocial.newMessage(template.evaluate({
				sender: UserInfo.name,
				title: AppInfo.title,
				logo: AppInfo.logo,
				link: AppInfo.link
			}));
			
			msg.setField(opensocial.Message.Field.TITLE, AppInfo.title);
			msg.setField(opensocial.Message.Field.TYPE, opensocial.Message.Type.PUBLIC_MESSAGE);
	
			OpenSocial.os.requestSendMessage(Feed.selectedFriends[Feed.idx].uid, msg, Feed.sendCallback);
		}
		else {
			var strTemplate	= 	'Hey #{receiver}, #{sender} has just challenged you at #{title}! ' +
								'#{sender} wants to play a fun music battle with you. ' +
								'Click \"Add\" below to Play!';

			var template = new Template(strTemplate);
			
			var msg = opensocial.newMessage(template.evaluate({
				receiver: Feed.selectedFriends[Feed.idx].name,
				sender: UserInfo.name,
				title: AppInfo.title
			}));
			
			msg.setField(opensocial.Message.Field.TITLE, AppInfo.title);
	
			OpenSocial.os.requestShareApp(Feed.selectedFriends[Feed.idx].uid, msg, Feed.sendCallback);
		}
	},
	sendCallback : function (res) {
		/*
		if (res === MyOpenSpace.PostTo.Result.ERROR) {
			console.log('callback gave error');
		}
		else if (res === MyOpenSpace.PostTo.Result.CANCELLED) {
			console.log('user cancelled PostTo');
		}
		else if (res === MyOpenSpace.PostTo.Result.SUCCESS) {
			console.log('WE ARE MEETING WITH GREAT SUCCESS!!!');
		}
		else {
			console.log('Unrecognized response: ' + res);
		}*/

		++Feed.idx;
		try {
			console.log(Feed.idx);
		}
		catch (e) {
			
		}
		if (Feed.idx < Feed.selectedFriends.size()) {
			Feed.send();
		}
		else {
			//Game.view();
			window.parent.location = AppInfo.link;
		}
	}
};

var Game = {
	mode: 0,	// 0 : default, 1 : challenge
	skip_howto: false,
	score: null,
	key: null,
	view: function () {
		var strTemplate	=	'<object classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\"\n' +
							'		codebase=\"http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,47,0\"\n' +
							'		width=\"550\" height=\"450\" id=\"gameFlash\" align=\"middle\">\n' +
							'	<param name=\"allowScriptAccess\" value=\"always\" />\n' +
							'	<param name=\"movie\" \n' +
							'			value=\"http://images.ijjimax.com/flash/public/skinFlashPublic07.swf?gameid=' + AppInfo.gid + '\" />\n' +
							'	<param name=\"quality\" value=\"high\" />\n' +
							'	<param name=\"swliveconnect\" value=\"true\" />\n' +
							'	<param name=\"wmode\" value=\"window\" />\n' +
							'	<embed src=\"http://images.ijjimax.com/flash/public/skinFlashPublic07.swf?gameid=' + AppInfo.gid + '\"\n' +
							'		quality=\"high\" wmode=\"transparent\" width=\"550\" height=\"450\"\n' +
							'		swliveconnect=\"true\" name=\"gameFlash\" align=\"middle\"\n' +
							'		allowScriptAccess=\"always\" type=\"application/x-shockwave-flash\"\n' +
							'		pluginspage=\"http://www.macromedia.com/go/getflashplayer\" />\n' +
							'</object>\n';
		
		$('gameWrapper').update(strTemplate);
		
		if (!Game.skip_howto) {
			$('newsWrapper', 'gameWrapper', 'challengeWrapper', 'challengeResultWrapper').invoke('hide');
			$('howtoWrapper').show();
			

			$('closeHowto').observe('click', function (event) {
				var data = {
					user_key: UserInfo.key
				};

				var url = AppInfo.url + 'member/skipHowto';

				OpenSocial.ajax(url, data, function (res) {
					if (res.data['error'] === 0) {
						Game.skip_howto = true;
						Game.view();
					}
				});
			});
		}
		else {
			$('newsWrapper', 'howtoWrapper', 'challengeWrapper', 'challengeResultWrapper').invoke('hide');
			$('gameWrapper', 'mute').invoke('show');
			$('contents').setStyle({
				'width': '550px'
			});
			Challenge.viewReceivedChallenges();
		}
		
		var soundvolume = 100;
		$('mute').observe('click', function() {
			soundvolume = (soundvolume === 100) ? 0 : 100;

			if(window.gameFlash) window.document["gameFlash"].SetVariable("/FMReceiver:volume", soundvolume);
			if(document.gameFlash) document.gameFlash.SetVariable("/FMReceiver:volume", soundvolume);

			if (soundvolume === 0) {
				$('mute_img').src = AppInfo.url + 'image/soundon.png';
				$('mute_img').alt = 'Sound On';
			}
			else if (soundvolume === 100) {
				$('mute_img').src = AppInfo.url + 'image/soundoff.png';
				$('mute_img').alt = 'Sound Off';
			}
		});
	},
	start: function () {
		var url = AppInfo.url + '/game/start';
		var data = {
			user_key: UserInfo.key,
			gid: AppInfo.gid
		};
		
		OpenSocial.ajax(url, data, function (res) {
			if (res.data['error'] === 0) {
				Game.key = res.data['data']['score_key']
			}
		});
	},
	over: function (score) {
		Game.score = (score === undefined) ? 0 : score;
		
		var data = {
			score_key: Game.key,
			gid: AppInfo.gid,
			score: Game.score
		};
		
		var url = AppInfo.url + '/game/over';
		
		OpenSocial.ajax(url, data, function (res) {
			if (Game.mode == 1) {
				$('gameWrapper', 'vsWrapper', 'sidebar', 'mute').invoke('hide');
				$('challengeResultWrapper').show();

				$('contents').setStyle({
					'width': '100%'
				});
				
				var data = {
					challenge_key: Challenge.key,
					score: Game.score
				};
				
				var url = AppInfo.url + 'challenge/result';
				
				OpenSocial.ajax(url, data, function (res) {
					if (res.data['error'] === 0) {
						var data = res.data['data'];
						
						$('best_score').update(data['best_score']);
						$('win').update(data['win']);
						$('lose').update(data['lose']);

						$('vsScore_' + UserInfo.uid).update(Game.score);

						$('challengeResultScore_' + UserInfo.uid).update(Game.score);

						$('challengeResultMsg').update(data['msg']);
						
						$('challengeResultOKBtn').observe('click', function (event) {
							/*
							Game.mode = 0;
							Game.view();
							*/
							window.parent.location = AppInfo.link;
						});
					}
				});
			}
			else {
				$('gameWrapper', 'sidebar', 'mute').invoke('hide');
				
				$('friendsList').update('');
				
				$('challengeWrapper').show();

				$('contents').setStyle({
					'width': '100%'
				});

				$('challengeScore').update('You got ' + Game.score + '. Challenge your friends!');
				
				FriendsInfo.init('all', Challenge.viewFriendsList);

				$('challengeBtn').observe('click', function () {
					Feed.init(Challenge.send);
				});

				$('challengeAllBtn').observe('click', function () {
					FriendsSelector.selectAll();
					Feed.init(Challenge.send);
				});

				$('challengeSkipBtn').observe('click', function () {
					/*
					Game.mode = 0;
					Game.view();
					*/
					window.parent.location = AppInfo.link;
				});
			}
			
			Rank.pageBtn['SCORE'] = 'GLOBAL';
			Rank.page['GLOBAL_SCORE'] = 0;
			Rank.view('GLOBAL_SCORE');
			Rank.init();
		});
	}
};

var Rank = {
	pageBtn : {
		SCORE: 'GLOBAL',
		WIN: 'GLOBAL'
	},
	url: {
		GLOBAL_SCORE: 'rank/global_score',
		FRIENDS_SCORE: 'rank/friends_score',
		GLOBAL_WIN: 'rank/global_win',
		FRIENDS_WIN: 'rank/friends_win'
	},
	page: {
		GLOBAL_SCORE: 0,
		FRIENDS_SCORE: 0,
		GLOBAL_WIN: 0,
		FRIENDS_WIN: 0
	},
	rankWrapper: {
		GLOBAL_SCORE: 'globalScoreRank',
		FRIENDS_SCORE: 'friendsScoreRank',
		GLOBAL_WIN: 'globalWinRank',
		FRIENDS_WIN: 'friendsWinRank'
	},
	makeRank : function (ul, list, mode) {
		list.each(function (element) {
			var strTemplate	=	'<li>' +
								'	<span class=\"order\">#{rank}</span>' +
								'	<img src=\"#{img}\" />' +
								'	<span class=\"name\">#{name}</span>' +
								'	<span class=\"score\">#{record}</span>' +
								'</li>';
			var ulTemplate = new Template(strTemplate);
			
			if (mode == 'GLOBAL_SCORE' || mode == 'FRIENDS_SCORE') {
				var record_msg = 'Score : ' + element['score'];
			}
			else if (mode == 'GLOBAL_WIN' || mode == 'FRIENDS_WIN') {
				var record_msg = 'Win : ' + element['win'];
			}
			
			ul.insert(
				ulTemplate.evaluate({
					rank: element['rank'],
					name: element['name'],
					img: element['thumb'],
					record: record_msg
				})
			);
		});
	},
	makeMyRank : function (ul, myRank, mode) {
		if (myRank !== null) {
			var strTemplate	=	'<li class=\"myRank\">' +
								'	<span class=\"order\">#{rank}</span>' +
								'	<img src=\"#{img}\" />' +
								'	<span class=\"name\">#{name} (You)</span>' +
								'	<span class=\"score\">#{record}</span>' +
								'</li>';
			var ulTemplate = new Template(strTemplate);
			
			if (mode == 'GLOBAL_SCORE' || mode == 'FRIENDS_SCORE') {
				var record_msg = 'Score : ' + myRank['score'];
			}
			else if (mode == 'GLOBAL_WIN' || mode == 'FRIENDS_WIN') {
				var record_msg = 'Win : ' + myRank['win'];
			}
			
			ul.insert(
				ulTemplate.evaluate({
					rank: myRank['rank'],
					name: myRank['name'],
					img: myRank['thumb'],
					record: record_msg
				})
			);
		}
	},
	view : function (mode) {
		var data = {
			'gid': AppInfo.gid,
			'user_key': UserInfo.key,
			'page': Rank.page[mode]
		};
		
		if (mode === 'FRIENDS_SCORE' || mode === 'FRIENDS_WIN') {
			data['friendsList'] = FriendsInfo.added;
		}

		OpenSocial.ajax(AppInfo.url + Rank.url[mode], data, function (res) {
			var rankWrapper = $(Rank.rankWrapper[mode]);
			
			if (res.data['data']['all_ranks'].size() > 0) {
				rankWrapper.update('');
				Rank.makeMyRank(rankWrapper, res.data['data']['user_rank'], mode);
				Rank.makeRank(rankWrapper, res.data['data']['all_ranks'], mode);
			}
			else {
				Rank.page[mode] -= 1;
			}
		});
	},
	init : function () {
		$('globalScoreRank').show();
		$('globalWinRank').show();
		
		Rank.page['GLOBAL_SCORE'] = 0;
		Rank.pageBtn['SCORE'] = 'GLOBAL';
		Rank.view('GLOBAL_SCORE');
		
		Rank.page['GLOBAL_WIN'] = 0;
		Rank.pageBtn['WIN'] = 'GLOBAL';
		Rank.view('GLOBAL_WIN');
		
		$('globalScoreRankBtn').observe('click', function () {
			if (Rank.pageBtn['SCORE'] == 'FRIENDS') {
				$('globalScoreRankBtn', 'friendsScoreRankBtn').invoke('toggleClassName', 'selected');
				$('friendsScoreRank').hide();
				Rank.pageBtn['SCORE'] = 'GLOBAL';
				Rank.view('GLOBAL_SCORE');
				$('globalScoreRank').show();
			}
		});
		$('friendsScoreRankBtn').observe('click', function () {
			if (Rank.pageBtn['SCORE'] == 'GLOBAL') {
				$('globalScoreRankBtn', 'friendsScoreRankBtn').invoke('toggleClassName', 'selected');
				$('globalScoreRank').hide();
				Rank.pageBtn['SCORE'] = 'FRIENDS';
				Rank.page['FRIENDS_SCORE'] = 0;
				Rank.view('FRIENDS_SCORE');
				$('friendsScoreRank').show();
			}
		});
		
		$('globalWinRankBtn').observe('click', function () {
			if (Rank.pageBtn['WIN'] == 'FRIENDS') {
				$('globalWinRankBtn', 'friendsWinRankBtn').invoke('toggleClassName', 'selected');
				$('friendsWinRank').hide();
				Rank.pageBtn['WIN'] = 'GLOBAL';
				Rank.view('GLOBAL_WIN');
				$('globalWinRank').show();
			}
		});
		$('friendsWinRankBtn').observe('click', function () {
			if (Rank.pageBtn['WIN'] == 'GLOBAL') {
				$('globalWinRankBtn', 'friendsWinRankBtn').invoke('toggleClassName', 'selected');
				$('globalWinRank').hide();
				Rank.pageBtn['WIN'] = 'FRIENDS';
				Rank.page['FRIENDS_WIN'] = 0;
				Rank.view('FRIENDS_WIN');
				$('friendsWinRank').show();
			}
		});
		
		$('scoreRankNext').observe('click', function () {
			if (Rank.pageBtn['SCORE'] == 'GLOBAL') {
				Rank.page['GLOBAL_SCORE'] += 1;
				Rank.view('GLOBAL_SCORE');
			}
			else if (Rank.pageBtn['SCORE'] == 'FRIENDS') {
				Rank.page['FRIENDS_SCORE'] += 1;
				Rank.view('FRIENDS_SCORE');
			}
		});
		$('scoreRankPrev').observe('click', function () {
			if (Rank.pageBtn['SCORE'] == 'GLOBAL') {
				if (Rank.page['GLOBAL_SCORE'] > 0) {
					Rank.page['GLOBAL_SCORE'] -= 1;
					Rank.view('GLOBAL_SCORE');
				}
			}
			else if (Rank.pageBtn['SCORE'] == 'FRIENDS') {
				if (Rank.page['FRIENDS_SCORE'] > 0) {
					Rank.page['FRIENDS_SCORE'] -= 1;
					Rank.view('FRIENDS_SCORE');
				}
			}
		});
		$('winRankNext').observe('click', function () {
			if (Rank.pageBtn['WIN'] == 'GLOBAL') {
				Rank.page['GLOBAL_WIN'] += 1;
				Rank.view('GLOBAL_WIN');
			}
			else if (Rank.pageBtn['WIN'] == 'FRIENDS') {
				Rank.page['FRIENDS_WIN'] += 1;
				Rank.view('FRIENDS_WIN');
			}
		});
		$('winRankPrev').observe('click', function () {
			if (Rank.pageBtn['WIN'] == 'GLOBAL') {
				if (Rank.page['GLOBAL_WIN'] > 0) {
					Rank.page['GLOBAL_WIN'] -= 1;
					Rank.view('GLOBAL_WIN');
				}
			}
			else if (Rank.pageBtn['SCORE'] == 'FRIENDS') {
				if (Rank.page['FRIENDS_WIN'] > 0) {
					Rank.page['FRIENDS_WIN'] -= 1;
					Rank.view('FRIENDS_WIN');
				}
			}
		});
	}
};

var FriendsSelector = {
	list: null,
	size: 0,
	selected_num: 0,
	handleInputBox: 'init',
	clear: function () {
		for (var idx = 0; idx < FriendsSelector.size; ++idx) {
			FriendsSelector.list[idx].className = '';
		}
	},
	seeAll: function () {
		for (var idx = 0; idx < FriendsSelector.size; ++idx) {
			FriendsSelector.list[idx].parentNode.style.display = '';
		}
	},
	selectAll: function () {
		$('searchUsersField').value = 'Start Typing a Friend\'s Name';
		FriendsSelector.handleInputBox = 'init';
		
		for (var idx = 0; idx < FriendsSelector.size; ++idx) {
			var friend = FriendsSelector.list[idx];

			friend.parentNode.style.display = '';
			
			if (!friend.hasClassName('selected')) {
				friend.toggleClassName('selected');
			}

			FriendsSelector.selected_num = FriendsSelector.size;
		}
	},
	init: function () {
		FriendsSelector.list = $('friendsList').getElementsByTagName('a');
		FriendsSelector.size = FriendsSelector.list.length;
		FriendsSelector.selected_num = 0;
		FriendsSelector.handleInputBox = 'init';
		
		$('searchUsersField').value = 'Start Typing a Friend\'s Name';
		
		for (var idx = 0; idx < FriendsSelector.size; ++idx) {
			Event.observe(FriendsSelector.list[idx], 'click', function (event) {
				Event.findElement(event, 'a').toggleClassName('selected');
			});
		}

		$('selectAllBtn').observe('click', function () {
			FriendsSelector.selectAll();
		});
		
		// clear selections
		$('clearBtn').observe('click', function () {
			for (var idx = 0; idx < FriendsSelector.size; ++idx) {
				var friend = FriendsSelector.list[idx];
				
				if (!friend.parentNode.style.display !== 'none' && friend.hasClassName('selected')) {
					friend.toggleClassName('selected');
				}

				--FriendsSelector.selected_num;
			}
		});
		
		// search users by keyword
		$('searchUsersField').observe('focus', function () {
			if (FriendsSelector.handleInputBox === 'init') {
				$('searchUsersField').value = '';
				FriendsSelector.handleInputBox = 'set';

				new Form.Element.Observer('searchUsersField', 0.2, function (element, value) {
					
					if (value !== '' && FriendsSelector.handleInputBox !== 'init') {
						for (var idx = 0; idx < FriendsSelector.size; ++idx) {
							var lower_value = value.toLowerCase();
							var nameSpan = FriendsSelector.list[idx].getElementsByClassName('name')[0];
							var lower_name = nameSpan.innerHTML.toLowerCase();
							
							if (lower_name.include(lower_value)) {
								FriendsSelector.list[idx].parentNode.style.display = '';
							}
							else {
								FriendsSelector.list[idx].parentNode.style.display = 'none';
							}
						}
					}
					else {
						FriendsSelector.seeAll();
					}
				});
			}
		});
		
		$('searchUsersField').observe('blur', function () {
			var inputBox = $('searchUsersField');

			if (inputBox.value.blank()) {
				inputBox.value = 'Start Typing a Friend\'s Name';
				FriendsSelector.handleInputBox = 'init';
			}
		});
		
		$('seeAllBtn').observe('click', function () {
			$('searchUsersField').value = 'Start Typing a Friend\'s Name';
			FriendsSelector.handleInputBox = 'init';

			FriendsSelector.seeAll();
		});
	}
};

function startGame() {
	Game.start();
}
function endGame(pt) {
	Game.over(pt);
}

/*
Event.observe(window, 'load', function () {
	OpenSocial.init(UserInfo.req);
});
*/
