gg = {};
gg.ui = {
	init: function() {	 	      
		gg.user.init();		
		gg.ui.login.init();	 

		//automagic setup of game lists	
		$('.game_list').each(function() {
	        new gg.ui.Gamelist(this);
	    });
	
	    //setup footer quickjump
		if($('#quickjump')) { 
		    $('#quickjump select').change( function() { 
		        document.location = this.options[this.selectedIndex].value; return false;  
		    }); 
		};	

		//preload images - god what a crappy hack
		preload = new Array('/_img/nav_allgames_1.png', '/_img/nav_home_1.png', '/_img/nav_latest_1.png', '/_img/nav_whatshot_1.png');
		$.each(preload, function(i, e) { $('<img>').attr("src", e); });		
	}
}
$(gg.ui.init);


gg.user = {
	favorites: new Array(),
	
	init: function() {	    
	    if($('#user-id')){		   
		    gg.user.id = $('#user-id').val();
		}
	},
    
	save: function() {
		var self = gg.user;		
		if(!self.dateCreated) { self.dateCreated = new Date(); }	
		if(!self.id) { self.id = 45; }	
		var v = serializeJSON(self);
		gg.utility.setCookie('user', v, 50, '/', '', false);
	},

	addFavorite: function(game, s, f) {
		self = gg.user;
		if(self.id) {
			//save via ajax
			var success = function(obj) {
				var r = eval(obj);
				if(r.success) {
					self.favorites = r.data;
					log('favorite saved successfully');
					if(s) { s(); }
				} else {
					log('saving favorite to DB failed');					
				}								
			}

			var fail = function(err) { 
				gg.utility.AJAXFail(err);
				if(f) { f(); }
			}			
			gg.utility.AJAXRequest('addFavorite', { gameid: game.id }, success, fail);
			
		}		
	},

	removeFavorite: function(game, s, f) {
		self = gg.user;
		if(self.id) {
			//save via ajax
			var success = function(obj) {
				var r = eval(obj);
				if(r.success) {
					self.favorites = r.data;
					log('favorite removed successfully');
					if(s) { s(); }
				} else {
					log('removing favorite to DB failed');									}								
				}

			var fail = function(err) { 
				gg.utility.AJAXFail(err);
				if(f) { f(); }
			}			
			gg.utility.AJAXRequest('removeFavorite', {userid: self.id, gameid: game.id}, success, fail);
			
		} 		
	}
}


gg.utility = {	
	AJAX_URL : '/ajax/',

	AJAXRequest: function(act, parms, success, fail) {	   
		var p = { action: act };
		$.extend(p, parms);
		if(gg.user.id) { $.extend(p, { userid: gg.user.id }); }		
		$.ajax({
		   type: "GET",
		   url: gg.utility.AJAX_URL,
		   dataType: "json",
		   success: success,
		   error: fail,
		   data: p
		});		
	},

	AJAXFail : function(err) {
		log('AJAX request failed', err);
	},

	hideFlash : function() { $('embed').css('visibility', 'hidden'); $('object').css('visibility', 'hidden'); },
	showFlash : function() { $('embed').css('visibility', 'visible'); $('object').css('visibility', 'visible'); },

	display : function(message, type, id) {		 
	    id = id || '#message';	    
		$(id).addClass(type).append(message);
	},
	
	setCookie : function(name, value, expires, path, domain, secure) {   
	    var val = escape(value);
	    if (document.cookie.length + val.length > 4000) {
				throw new MochiKit.Base.NamedError("MochiKit.Cookies.NoMemory")
		  }
		  var today = new Date();
			today.setTime( today.getTime() );
			if ( expires ) {
				expires = expires * 1000 * 60 * 60 * 24;
			}
			var expires_date = new Date( today.getTime() + (expires) );
		  document.cookie = name + "=" + val +
			((expires) ? "; expires=" + expires_date.toGMTString() : "") +
			((path) ? "; path=" + path : "") +
			((domain) ? "; domain=" + domain : "") +
			((secure) ? "; secure" : "");
	},

	getCookie : function(name) {
    	var dc = document.cookie;
    	var prefix = name + "=";
    	var begin = dc.indexOf("; " + prefix);
    	if (begin == -1) {
        	begin = dc.indexOf(prefix);
        	if (begin != 0) return null;
    	} else {
        	begin += 2;
    	}
    	var end = document.cookie.indexOf(";", begin);
    	if (end == -1) {
        	end = dc.length;
    	}
    	return unescape(dc.substring(begin + prefix.length, end));    	
	},

	createGame : function(str) { return gg.utility.decodeJSON(str); },
	decodeJSON : function(str) { return eval( "(" + gg.utility.sanitize(unescape(str)) + ")"); },

	sanitize : function(str) {
		var self = gg.utility;
		str = self.replace(str, '\n', '');
		str = self.replace(str, '\r', '');
		str = self.replace(str, '\t', '');
		return str
	},

	replace : function(str, from, to) {
           var i = str.indexOf(from);
           if (!from || !str || i == -1) return str;
           var newstr = str.substring(0, i) + to;
           if (i+from.length < str.length)
           newstr += gg.utility.replace(str.substring(i+from.length,str.length),from,to);
           return newstr;
	 },
	 
	 commafy : function(nStr) {
     	nStr += '';
     	x = nStr.split('.');
     	x1 = x[0];
     	x2 = x.length > 1 ? '.' + x[1] : '';
     	var rgx = /(\d+)(\d{3})/;
     	while (rgx.test(x1)) {
     		x1 = x1.replace(rgx, '$1' + ',' + '$2');
     	}
     	return x1 + x2;
     }
}


gg.ui.my = {	
	init : function() {
		var self = gg.ui.my;
		if($('#my')) {
			$('#my-favorites/a:nth(0)').click(function() { self.toggleItem('#my-favorites-panel'); self.loadFavorites(); return false; });
			$('#my-recent/a:nth(0)').click(function() { self.toggleItem('#my-recent-panel'); self.loadRecent(); return false; });
			$('#my-bests/a:nth(0)').click(function() { self.toggleItem('#my-bests-panel'); self.loadBests(); return false; });					
		}
	},
	
	loadFavorites : function() {
		gg.ui.waiting.show('#my-favorites-panel');
		var o = { 'userid' : gg.user.id }
		var s = function(r) {				
			list = $.UL(null,		
				$.map(r.data, function(e) {
					return $.LI(null,
						$.A({'href': e.permalink, 'class': 'img'}, $.IMG({'src': '/_include/lib/phpthumb/phpThumb.php?src=/_assets/'+e.image+'&w=50&h=50&zc=1'}, null)),
						$.A({'href': e.permalink}, $.STRONG(null, e.title))
					);
				})	
			);
			$('#my-favorites-panel').empty().append(list);			
		}		
		gg.utility.AJAXRequest('getFavorites', o, s, gg.utility.AJAXFail);
	},
	
	loadRecent : function() {
		gg.ui.waiting.show('#my-recent-panel');
		var o = { 'userid' : gg.user.id }
		var s = function(r) {			
			list = $.UL(null,
				$.map(function(e) {
					return $.LI(null,
						$.A({'href': e.permalink, 'class': 'img'}, $.IMG({'src': '/_include/lib/phpthumb/phpThumb.php?src=/_assets/'+e.image+'&w=50&h=50&zc=1'}, null)),
						$.A({'href': e.permalink}, $.STRONG(null, e.title))
					);
				}, r.data)
			);			
			$('#my-recent-panel').empty().append(list);			
		}		
		gg.utility.AJAXRequest('getRecent', o, s, gg.utility.AJAXFail);
	},
	
	loadBests : function() {
		gg.ui.waiting.show('#my-bests-panel');
		var o = { 'userid' : gg.user.id }
		var s = function(r) {			
			list = $.TABLE(null,
				$.THEAD(null, $.TR(null,
					$.TH(null, 'Game'),
					$.TH(null, 'Score'),
					$.TH(null, 'Level'),
					$.TH(null, 'Date')
				)),
				$.TBODY(null,
					$.map(r.data, function(e) {
						return $.TR(null, 
							$.TD(null, $.A({'href': e.game.permalink}, $.IMG({'src': '/_include/lib/phpthumb/phpThumb.php?src=/_assets/'+e.game.image+'&w=20&h=20&zc=1'}), e.game.title)),
							$.TD(null, e.score),
							$.TD(null, e.level),
							$.TD(null, e.nicedate)
						);
					})
				)				
			);
			$('#my-bests-panel').empty().append(list);			
		}		
		gg.utility.AJAXRequest('getScores', o, s, gg.utility.AJAXFail);
	},
	
	toggleItem : function(element) {
		gg.ui.my.closeAll();
		$(element).removeClass('hide');
		gg.ui.my.bodyevent = function(e){ gg.ui.my.closeAll() };
		$(document.body).click(gg.ui.my.bodyevent);		
	},
	
	closeAll : function() {
		$('#my-favorites-panel').addClass('hide');
		$('#my-recent-panel').addClass('hide');
		$('#my-bests-panel').addClass('hide');
		$(document.body).unbind("click", gg.ui.my.bodyevent);		
	}
}


//Class for login panel
gg.ui.login = {

	init : function(e) {
		$('#login-panel').jqm({
			onHide : function(hash) { gg.utility.showFlash(); hash.w.hide(); hash.o.remove(); }
		});
		$('#login-button').click(function() { gg.ui.login.show(); return false; });			
	},
	
	show : function(message) {
	    gg.utility.hideFlash();	    
	    if(message) {
		    $('#login-message').empty().append(message).removeClass('hide');
		} else {
		    $('#login-message').addClass('hide');
		}		
		$('#login-panel').jqmShow();		
	},
	
	hide : function(element) {
		$('#login-panel').jqmHide();		
	}
}


//Class for loading animation
gg.ui.waiting = {
	show : function(element, text) { 
	    var t = text || 'Loading'
	    $(element).empty().append(
	        $.DIV({'class': 'loading'}, 
	            $.IMG({'src': '/_img/g_loader_lghtblue.gif'}), 
	            $.STRONG(null, t)
	        )
	    ); 
	},
	hide : function(element) { /* $(e) removeChildNodes(e, getElementsByTagAndClassName('div', loading, e)); */ }
}

//Class to build leaderboards
gg.ui.ScoreBoard = function(table_elm, list_elm, onupdate) {
    this.scores = null;
    this.boards = null;
    this.select = null;
    this.board = null;
    
    this.scoreTableElm = $(table_elm);
    this.boardListElm = $(list_elm);
    this.onupdate = onupdate;
    
    if($$('#board_data')) {
        this._getBoardList();
        this._drawBoardList();
        this._getScores();
    }    
}

$.extend(gg.ui.ScoreBoard.prototype, {
    
    refresh : function() {
        this._getScores();
    },
    
    getUserScore : function(id, callback) {
        var self = this;
        var success = function(data) {
  	        if(!data.success)
  	            fail();
  	        callback(data.data);
  	    }	    
  	    var fail = function() {
  	        
  	    }          

  	    //put together ajax call
  	    gg.utility.AJAXRequest('memberboardscore', {
  	       boardid: self.board.id,
  	       userid: id
  	    }, success, fail);
    },
    
    _getBoardList : function() {           
         
        this.boards = gg.utility.decodeJSON($('#board_data').val());
    },
    
    _getScores : function() {
        var self = this;
        var success = function(data) {
	        if(!data.success)
	            fail();
	        self.scores = data.data;
	        self._drawTable();
	        
	        if(self.onupdate)
	            self.onupdate(self.board);
	    }	    
	    var fail = function() {
	        $(self.scoreTableElm).empty().append('Ooops board scores failed.');
	    }
	    
        self.board = self._getBoard(self.select.val()); 
        
        if(!self.board)
            return;
	    
	    //put together ajax call
	    gg.utility.AJAXRequest('boardscores', {
	       boardid: self.board.id
	    }, success, fail);
    },
    
    _getBoard : function(id) {
        var self = this;
        var board;
        $.each(self.boards, function(b){
            var bd = self.boards[b];
            if(bd.id == id) {
                board = bd;
            }                
        })
        return board;
    },
    
    _drawBoardList : function() {
        var self = this;
        
        self.select = $.SELECT(
            {'id' : 'board_list_select'}, 
            $.map(self.boards, function(b) {               
                return $.OPTION({'value': b.id}, b.title);
            })
        );
        self.boardListElm.html(self.select)
        self.select = $(self.select);
        self.select.change(function(){
            self.refresh();
        });  
        
        if(self.boards.length <= 1)
            self.select.addClass('hide');        
    },
    
    _drawTable : function() {
        var self = this;
        var rank = 0;
        var t = $.TABLE(null,
            $.THEAD(null,
                $.TR(null,
                    $.TH(null, null),
                    $.TH(null, 'member'),
                    $.TH(null, 'score')
                )                
            ),
            $.TBODY(null,
                $.map(self.scores, function(s) { 
                    rank++;                   
                    return $.TR(null,
                        $.TD(null, rank),
                        $.TD(null, $.A({'href': s.user.permalink}, s.user.displayname)),
                        $.TD(null, gg.utility.commafy(s.score))
                    );
                })
            )
        )
        self.scoreTableElm.html(t);                                    	
    }
});

//Ratings Class for game list
gg.ui.Gamelist = function(elm) {
    this.element = $(elm);    
    this.games = new Array();
    this._init();
    return this;
}
$.extend(gg.ui.Gamelist.prototype, {
    
    _init : function() {
        var self = this;


        self.element.find('.game').each(function(i, game) {                        
            game = $(game);            
            var g = gg.utility.decodeJSON(game.find('.data').val());
            self.games.push(g);
        
            //connect ratings
            game.find('.ratings').each(function(j, el) {
    		    var i = parseFloat(el.innerHTML.replace(' ', ''));
    		    new gg.ui.Ratings(el, i); 
    		});            
    		
    		//look for lb enabled
    		if(g.lb_enabled == 1) {
    		    game.addClass('lb_enabled');
    		    game.find('a.img').append($.SPAN({'title': 'Top Score Enabled!'}, null));
    		}
        });       
    }
});


//Ratings Class for star ratings
gg.ui.Ratings = function(elm, value) {
    this.element = elm;
    this.value = value || null;          
    this._createStars(5, value);    
    this.onRate = null;
    return this;
}

$.extend(gg.ui.Ratings.prototype, {
    star : "/_img/rating_off.gif",
    	
	_createStars : function(total, value) {
		var self = this;
		self.stars = [];
			
		if(value != null) {
		    var thefloor = Math.floor(value);
		    var theceiling = Math.ceil(value);
        	var	theremainder = value - thefloor;
        	if (theremainder > 0) { theremainder = theremainder * 100; }
        			        
		    for(i = 1; i <= total; i++) {	
    			var staron = null;		
    			if(i <= thefloor) { staron = $.DIV({'class': 'active'}, null); }
    			if((i > value) && (i == theceiling)) { 
    			    var t = $.DIV({'class': 'active partial'}, null); 
    			    $(t).attr('style', 'width: '+theremainder+'%'); 
    			    staron = t 
    			}			
    			self.stars.push($.DIV({'class': 'star'}, staron));			
    		}
		} else {
		    for(i = 1; i <= total; i++) {	        	    
    	        var s = $.DIV({'class': 'star'}, 
    	            $.A({'class': 'left', rel: (i-.5), href: '#'}, null),
    	            $.A({'class': 'right', rel: i, href: '#'}, null)
    	        );
    	        $(s).children('a')
    	            .mouseover(function() {
    	                self._highlightStar(this);
    	            })
    	            .click(function() {
    	                self._sendRating(this);
    	                return false;
    	            });
    	        self.stars.push(s);
    	    }	    
    	    $(self.element).mouseout(function() {
    	        self._clearAll();
    	    });
		}	
		return $(self.element).empty().append(self.stars);
	},
	
	_highlightStar: function(star) {
	    var self = this;	    
	    var r = $(star).attr('rel');	   
	    var s = $(self.stars).find('a').each(function() {
	        if($(this).attr('rel') <= r) {
	            $(this).addClass('selected');	            
	        } else {
	            $(this).removeClass('selected');
	        }
	    });
	},
	
	_sendRating: function(star) {
	    var self = this;
	    var rating = $(star).attr('rel');
	    	    
	    //get game id
	    input = $$('#game_data')
		if(input) { game = gg.utility.decodeJSON(input.value); }
				
		if(gg.user)
		    userid = gg.user.id
	    		
	    if( (!rating) || (!game) )
    	    return false;
    		    
	    //show saving
	    $(self.element).empty()
	    gg.ui.waiting.show(self.element, 'Saving');
	    
	    var success = function(data) {
	        if(!data.success)
	            fail();

	        self._createStars(5, rating);
	        if(typeof(self.onRate) == 'function') {
	            self.onRate();
	        } 
	    }
	    
	    var fail = function() {
	        $(self.element).empty().append('Ooops rating failed.');
	    }
	    
	    //put together ajax call
	    gg.utility.AJAXRequest('rategame', {
	       userid: userid,
	       gameid: game.id,
	       rating: rating 
	    }, success, fail);
	    	    
	},
	
	_clearAll: function() {	    
	    $(this.stars).find('a').removeClass('selected');
	}
});


this.tooltip = function(){	
	/* CONFIG */		
		xOffset = 10;
		yOffset = 20;		
		// these 2 variable determine popup's distance from the cursor
		// you might want to adjust to get the right result		
	/* END CONFIG */		
	$("a.tooltip").hover(function(e){											  	
		this.t = this.title;
		this.title = "";									  
		$("body").append("<div id='tooltip'>"+ this.t +"</div>");
		$("#tooltip")
			.css("top",(e.pageY - xOffset) + "px")
			.css("left",(e.pageX + yOffset) + "px")
			.css("position", "absolute")
			.fadeIn("fast");		
    }, function(){
		this.title = this.t;		
		$("#tooltip").remove();
    });	
    
	$("a.tooltip").mousemove(function(e){
		$("#tooltip")
			.css("top",(e.pageY - xOffset) + "px")
			.css("left",(e.pageX + yOffset) + "px");
	});	
		
};



// starting the script on page load
$(document).ready(function(){
	tooltip();
});


