function ShowUniversalTransition(divID, txt)
{
	if (0 == jQuery('#' + divID).find('#' + divID + '_transition').length)
	{
		var div = jQuery('#' + divID);
		div.prepend('<div id="' + divID + '_transition" class="All_LoginAnim" style="width: ' + div.css('width')
			+ '; height:' + div.css('height') + ';"><div>'+ txt +'</div></div>');
	}
}
function ShowTransition(divID)
{
	if (0 == jQuery('#' + divID).find('#' + divID + '_transition').length)
 	{
 		var div = jQuery('#' + divID);
		div.prepend('<div id="' + divID + '_transition" class="transitionAnim1" style="width: ' + div.css('width')
			+ '; height:' + div.css('height') + ';"><div class="transitionAnim2" style="width: ' + div.css('width')
			+ '; height:' + div.css('height') + ';"></div></div>');
 	}
}
function HideUniversalTransition(divID)
{
	jQuery('#' + divID).find('#' + divID + '_transition').remove();
}
function ShowGameFlash(mode)
{
	return jQuery.ark.toggleFlash(mode);
}
function Game(pageName, width, height, hasEnhanced)
{
	this.pageName = pageName;
	this.width = width;
	this.height = height;
	this.hasEnhanced = hasEnhanced;
	this.getHasEnhanced = function() { return this.hasEnhanced; }
	this.getPageName = function() { return this.pageName; }
	this.getWidth = function() { return this.width; }
	this.getHeight = function() { return this.height; }		
	
}
function RunGame(game, adjustWidth, adjustHeight, gameEndHeight)
{
	this.game = game;
	this.adjustWidth = adjustWidth;
	this.adjustHeight = adjustHeight;
	this.minWidth = 728;
	this.Open = function()
	{
		var width = this.game.getWidth();
		var height = this.game.getHeight();
		if (width < this.minWidth)
		{
			width = this.minWidth;
		}
		if (height < gameEndHeight)
		{
			height = gameEndHeight;
		}
		width += this.adjustWidth;
		height += this.adjustHeight;
		var scroolbars = 0;
		var resizable = 1;
		/*if (screen.height <= 810) {
		resizable = 1;
		scroolbars = 1;
		width += 20;
		height += 5;
		}*/
		var url = 'http://www.greatdaygames.com/games/{0}/{0}.aspx'.replace(/\{0\}/g, this.game.getPageName());
		var hasEnhanced = this.game.getHasEnhanced();
		if(hasEnhanced)
		{
		    url = 'http://www.greatdaygames.com' + '/monetization/gameversionselector.aspx?pagename=' +  this.game.getPageName();
		}		
		var wndParams = 'top=70px,left=300px,width=' + width + 'px,height=' + height + 'px,status=0,resizable=' + resizable + ',location=0,scrollbars=' + scroolbars;
		var wnd = window.open(url, null, wndParams);
		if (wnd) { wnd.focus(); } else { alert('popups denied'); }
	}
}

function GenerateRecaptcha(recaptchaDivID, tabIndex)
{
	Recaptcha.create('6LfxVwUAAAAAAA80DGEK6GZIXTkHx7usxrjQhxio', recaptchaDivID, {
		theme: 'clean'
		,tabindex: tabIndex
		//, callback: Recaptcha.focus_response_field
	});
}
function AjaxPanelClass(serviceUrl, containerDivID)
{
	this.serviceUrl = serviceUrl;
	this.clientID = containerDivID;
	this.containerDivSelector ='#' + containerDivID;
	this.LoadDiv = function(isSubmitDiv)
		{
			var params;
			if (isSubmitDiv)
			{
				params = this.CollectSubmitParams(this.containerDivSelector);
				params._s = true;
			}
			this.CallService(params);
		};
	this.CollectSubmitParams = function (containerSelector)
	{
		var input = jQuery(containerSelector).find('*').filter(':input').filter(function()
			{
				return ((this.type != 'radio' && this.type != 'checkbox') || this.checked);
			});
		var params = {};
		jQuery.each(input, function() 
			{
				//if (this.type == 'checkbox')
				params[this.name] = (this.type == 'checkbox' ? true : this.value);
				//params[this.name] = this.value;
			});
		return params;
	}
	this.CallService = function(params)
	{
		if (!params) { params = {}; }
		params._id = this.clientID;
		params._ = Math.random();
		jQuery(this.containerDivSelector).children().fadeTo('fast', 0.33);
		jQuery(this.containerDivSelector).load(this.serviceUrl, params);
	}
}
function AjaxViewEditClass(serviceUrl, containerDivID, editDivID)
{
	this.serviceUrl = serviceUrl;
	this.clientID = containerDivID;
	this.containerDivSelector ='#' + containerDivID;
	this.editDivSelector = '#' + editDivID;
	this.LoadPage = function(mode) { this.CallService(mode); };
	this.SavePage = function ()
	{
		var input = jQuery(this.editDivSelector).find('*').filter(':input').filter(function() {
				return (this.type != 'radio' && this.type != 'checkbox' || this.checked);
			});
		var params = {};
		jQuery.each(input, function() { params[this.name] = this.value; });
		this.CallService('Save', params);
	}
	this.CallService = function(mode, params)
	{
		if (!params)
		{
			params = {};
		}
		params._id = this.clientID;
		params._mode = mode;
		params._ = Math.random();
		jQuery(this.containerDivSelector).load(this.serviceUrl, params);
	}
}

// create jQuery.ark namespace
if (jQuery) (function(jQuery) {
	jQuery.extend(jQuery, {
		ark: function() {
		}
	})
})(jQuery);

if (jQuery) (function(jQuery) {
	jQuery.extend(jQuery.ark, { 
		SiteBaseUrl: 'http://www.greatdaygames.com',
		GetFunction: function(action)
		{
            if (action)
            {
                if (typeof (action) == 'function') { return action; }
                else if (typeof (action == 'string')) { return new Function('action', action); }
                else { alert('Actions of type "' + typeof (action) + '" are not supported!'); }
            }
            return action;
		}
	});
})(jQuery);

if (jQuery) (function(jQuery) {
	jQuery.extend(jQuery.ark, { string: function() { } });
	jQuery.extend(jQuery.ark.string, {
		ToLiteral: function(str)
		{
			return str.replace(/\\/g, '\\\\').replace(/\'/g, '\\\'').replace(/\"/g, '\\\"');
		}
	});
})(jQuery);

// jQuery.ark namespace
if (jQuery) (function(jQuery) {
	jQuery.extend(jQuery.ark, {

		// Common method to launch ajax request
		// it's always POST. JSON used for both request and response.
		// @param url to WCF service
		// @param data string in '' represents JSON request data like
		//   '{"leaderboardRequest":{'
		//	+ '"Type":"' + leaderboard.Type + '"'
		//	+ ',"Period":"' + leaderboard.Period + '"'
		//	+ ',"Group":"' + leaderboard.Group + '"'
		//	+ ',"UserID":' + leaderboard.UserID
		//	+ ',"GameID":' + leaderboard.GameID
		//	+ ',"NTop":' + leaderboard.NTop
		//	+ '}}'
		// if there is no request params then use '{}' as value for data parameter
		// @param callback is a function with one response argument. it's called on success response
		// @param optional jQuery reference to DOM element to add/remove ajax css class
		// TODO: provide ShowUniversalTransition instead of just css class add/remove
		ajaxJSON: function(url, data, callback, element) {
			if (element != null && typeof (element) != 'undefined')
			   ShowTransition(jQuery(element).attr('id'));
			//element.addClass("ajax");
			jQuery.ajax({
				url: url,
				data: data,
				type: "POST",
				processData: true,
				contentType: "application/json; charset=utf-8",
				/*timeout: 30000,*/
				dataType: "json",
				success: function(response) {
					if (typeof (element) != 'undefined')
						HideUniversalTransition(element.attr('id'));
					//element.removeClass("ajax");
					callback(response)
					return true;
				},
				error: function(xhr) {
					if (typeof (element) != 'undefined')
						HideUniversalTransition(element.attr('id'));
					//element.removeClass("ajax");
					/*if (xhr.responseText)
						alert("Ajax: " + xhr.responseText);
					else
						alert("Ajax: Unknown server error or timeout");
						*/
					return true;
				}
			});
		}

		,ajaxHTML: function(url, data, callback, element) {
			if (element != null && typeof (element) != 'undefined')
				ShowTransition(jQuery(element).attr('id'));
			jQuery.ajax({
				url: url,
				data: data,
				type: "POST",
				processData: true,
				/*contentType: "application/json; charset=utf-8",*/
				/*timeout: 30000,*/
				dataType: "html",
				success: function(response) {
					if (typeof (element) != 'undefined')
						HideUniversalTransition(element.attr('id'));
					callback(response);
					return true;
				},
				error: function(xhr) {
					if (typeof (element) != 'undefined')
						HideUniversalTransition(element.attr('id'));
					/*if (xhr.responseText)
						alert("Ajax: " + xhr.responseText);
					else
						alert("Ajax: Unknown server error or timeout");
						*/
					return true;
				}
			});
		}

		,pause: function(ms) {
			var date = new Date();
			var curDate = null;
			do { curDate = new Date(); }
			while (curDate - date < ms);
		}

		,toggleFlash: function(mode)
		{
			var visibility = mode ? 'visible' : 'hidden';
			var flashes = document.getElementsByTagName('object');
			for(i = 0; i < flashes.length; i++)
			{
				flashes[i].style.visibility = visibility;
			}
			var flashes2 = document.getElementsByTagName('embed');
			for(i = 0; i < flashes2.length; i++)
			{
				flashes2[i].style.visibility = visibility;
			}
		}

		,treats: 0
		,update_treats: function(new_value)
		{
			var setNewValue = function(new_value)
			{
				jQuery.ark.treats = new_value;
				jQuery('.listen_treats').trigger('treats');
				if (window.opener)
					window.opener.jQuery.ark.update_treats(jQuery.ark.treats);
			}
			if (typeof new_value != 'undefined')
				setNewValue(new_value);
			else
				jQuery.ark.ajaxJSON(
					baseUrl + '/ajaxServices/UserBalance.svc/Get'
					,'{}'
					,function(response) {
						setNewValue(response.d);
					}
					,undefined);
		}
		
		
        ,addCommas: 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;
        }
		
	});


})(jQuery);


// anchor_popup plugin
// e.g. used for user avatar popup
if (jQuery) (function(jQuery) {

	jQuery.ark.anchor_popup = {

		// plugin defaults
		defaults: {
			x: 0,
			y: 0,
			popup: null,
			tmpl: null,
			data: null
		},
		
		// public method to hide popup
		hidePopup: function(popup) {
			hidePopup(popup);
		}
	};

	jQuery.fn.extend({
		anchor_popup: function(options)
		{
			return this.each(function() {
				var $item = jQuery(this);
				$item.options = jQuery.extend({}, jQuery.ark.anchor_popup.defaults, options);

				jQuery($item)
					.mouseover(function() { onMouseover(false, $item); } )
					.mouseout(function() { onMouseout(popup); });

				var popup = $item.options.popup;

				popup
					.unbind('mouseover')
					.mouseover(function() { onMouseover(true, undefined); })
					.unbind('mouseout')
					.mouseout(function() { onMouseout(popup); } );

			});

		}
	});

	var showing = null;
	var hiding = null;
	function stopTimers() {
		if (showing) {
			clearTimeout(showing);
			showing = null;
		}
		if (hiding) {
			clearTimeout(hiding);
			hiding = null;
		}
	}
	function hidePopup(popup_panel) {
//		popup_panel.fadeOut(200);
		popup_panel.hide();
	}
	function showPopup(item) {
		if (item.options.beforeShow)
			item.options.beforeShow(item);
	
		var popup = item.options.popup;
		
		if (item.options.tmpl)
			popup.html(item.options.tmpl(item.options.data));

		if (item.options.x)
			popup.css('left', item.options.x + 'px');
		if (item.options.y)
			popup.css('top', item.options.y + 'px');
				
		if (! popup.is(':visible'))
			popup.fadeIn(300);

		if (item.options.afterShow)
			item.options.afterShow(item);
	}
	function onMouseover(the_same, item)
	{
		stopTimers();
		if (the_same)
			return;
		showing = setTimeout(function() {
			clearTimeout(showing);
			showing = null;
			showPopup(item);
		}, 300);
	}
	function onMouseout(popup)
	{
		stopTimers();
		hiding = setTimeout(function() {
			clearTimeout(hiding);
			hiding = null;
			hidePopup(popup);
		}, 400);
	}

})(jQuery);


// user avatar popup
if (jQuery) (function(jQuery) {

	jQuery.ark.avatar_popup = {
		tmpl: null
		,popup: null
	};

	jQuery.fn.extend({
		avatar_anchor: function(options)
		{
			return this.each(function() {
				var $item = jQuery(this);

				$item.options = jQuery.extend({}, jQuery.ark.avatar_popup.defaults, options);

				$item.options.tmpl = jQuery.ark.avatar_popup.tmpl;
				$item.options.popup = jQuery.ark.avatar_popup.popup;

				var avatar_beforeShow = $item.options.beforeShow;

				$item.options.beforeShow = function(item)
				{
					var dx = item.attr('dx');
					var l_pos = item.offset();
					
					//alert(window.screen.height + ' ' + l_pos.top + ' ' + item.options.height);
					if (dx)
						item.options.x = l_pos.left + parseInt(dx);
					else
						item.options.x = l_pos.left + 35;
						
					if((l_pos.top + 465) > window.screen.height)
						item.options.y = l_pos.top - 265
					else
	                    item.options.y = l_pos.top;

					item.options.data = {
						UserName: item.attr('UserName')
						,UrlRating: item.attr('UrlRating')
						,TagLine: item.attr('TagLine')
						,UrlLargeAvatar: item.attr('UrlLargeAvatar')
						,UrlProfile: item.attr('UrlProfile')
					};

					if (avatar_beforeShow)
						avatar_beforeShow(item);
				}
				$item.options.afterShow = function(item)
				{
					jQuery("a.PopUp_Avatar_close", item.options.popup).click(function(event) {
						jQuery.ark.anchor_popup.hidePopup(item.options.popup);
						return false;
					});
				}

				$item.anchor_popup($item.options);

			});

		}
	});

	jQuery(function(){

		// prepare avatar popup template
		jQuery.ark.avatar_popup.tmpl = tmpl("tmplAvatarPopup");

		// get/create popup
		jQuery.ark.avatar_popup.popup = jQuery('#avatar_popup');
		if (jQuery.ark.avatar_popup.popup.length == 0) {
			jQuery(document.body).append('<div id="avatar_popup" class="PopUp_Avatar_block" style="display:none;"></div>');
			jQuery.ark.avatar_popup.popup = jQuery('#avatar_popup');
		}

		jQuery('.avatar_anchor').avatar_anchor();
		
	});
})(jQuery);


// rating_control plugin
if (jQuery) (function(jQuery) {

	jQuery(function(){
		jQuery.ark.rating_control.updateGlobal();
	});

	var global_loaded = 0; // 0-not loaded, 1-loaded for guest, 2-loaded for user
	function reset_game_list()
	{
		var games = [];
		jQuery('.star_rating').each(function(){
			games[games.length] = jQuery(this).attr('gameID');
		});
		return games.join(',');
	}
	function reset_avatar_list()
	{
		var avatars = [];
		jQuery('.av_star_rating').each(function(){
			avatars[avatars.length] = jQuery(this).attr('avatarID');
		});
		return avatars.join(',');
	}

	jQuery.ark.rating_control = {

		// plugin defaults
		defaults: {
			n: 10
			,step: 10
			,type: 1
			,state: 'blue'
			,rating: 0
			,avgRating: 0
			,css: ''
		}
		,setRating: function($item, $rating, $avgRating)
		{
			setRating($item, $rating, $avgRating);
		}
		,onLoginGlobal: function()
		{
			this.updateGlobal();
		}
		,onLogoutGlobal: function()
		{
			this.updateGlobal();
		}
		// update small stars for games
		,update_game_star_rating: function(parent, callback)
		{
		    jQuery(document).ratingGameItemsCount = 0;
		    var searchCssClass = IsLoggedIn()? ".mediumAV_rait_img" : ".star_rating";
			var games = [];
			jQuery(searchCssClass, parent).each(function(){
				games[games.length] = jQuery(this).attr('gameID');
			});
			
			var s_games = games.join(',');
			if(games.length > 0) {
			    jQuery.ark.ajaxJSON(
				    baseUrl + '/ajaxServices/UserGameRating.svc/GetList'
				    ,'{"gameIDs":"' + s_games + '"}'
				    ,function(response) {
					    var ratings = {};
					    for (var i in response.d)
						    ratings[response.d[i].ObjectID] = response.d[i];
					    jQuery(searchCssClass, parent).each(function(){
						    var $this = jQuery(this);
    						
						    var gameID = $this.attr('gameID');
						    if (! ratings[gameID])
							    return;
						    var game = ratings[gameID];
    						
						    jQuery('div', $this)
							    .width((IsLoggedIn() && game.UserRating ? game.UserRating : game.AvgRating)* $this.width() / 10);
						    $this.attr('title', 'Average rating: ' + (game.AvgRating / 2));
    						
						    var cssRemove = 'red';
						    var cssAdd =  'blue';
						    if (IsLoggedIn() && game.UserRating)
						    {
							    cssRemove = 'blue';
							    cssAdd =  'red';
						    }
						    $this
							    .removeClass($this.attr('ratingCSS') + cssRemove)
							    .addClass($this.attr('ratingCSS') + cssAdd);
					    });
    					
					    if (typeof callback == 'function')
						    callback();
				    }
				    ,undefined);
			}
		}

		,set_avatar_star_rating: function($this, avatar)
		{
			var w = $this.width() || (10 * $this.attr('step'));
			jQuery('div', $this)
				.width((IsLoggedIn() && avatar.UserRating ? avatar.UserRating : avatar.AvgRating)* w / 10);
			$this.attr('title', 'Average rating: ' + (avatar.AvgRating / 2));

			var cssRemove = 'red';
			var cssAdd =  'blue';
			if (IsLoggedIn() && avatar.UserRating)
			{
				cssRemove = 'blue';
				cssAdd =  'red';
			}
			$this
				.removeClass($this.attr('ratingCSS') + cssRemove)
				.addClass($this.attr('ratingCSS') + cssAdd);
		}
		
		// update small stars for avatars
		,update_avatar_star_rating: function(parent, callback)
		{
			var avatars = [];
			jQuery('.av_star_rating', parent).each(function(){
				avatars[avatars.length] = jQuery(this).attr('avatarID');
			});
			var s_avatars = avatars.join(',');

			jQuery.ark.ajaxJSON(
				baseUrl + '/ajaxServices/UserAvatarRating.svc/GetList'
				,'{"avatarIDs":"' + s_avatars + '"}'
				,function(response) {
					var ratings = {};
					for (var i in response.d)
					{
						ratings[response.d[i].ObjectID] = response.d[i];
					}
					jQuery('.av_star_rating', parent).each(function(){
						var $this = jQuery(this);
						
						var avatarID = $this.attr('avatarID');
						if (! ratings[avatarID])
							return;
						var avatar = ratings[avatarID];
						jQuery.ark.rating_control.set_avatar_star_rating($this, avatar);
					});

					if (typeof callback == 'function')
						callback();
				}
				,undefined);
		}

		// load all small stars for whole document both the games and the avatars		
		,updateGlobal: function()
		{
			if (global_loaded == 0 || (global_loaded == 1 && IsLoggedIn()) || (global_loaded == 2 && !IsLoggedIn()))
			{
				this.update_game_star_rating(
					jQuery(document)
					, function(){
						if (IsLoggedIn())
							global_loaded = 2;
						else
							global_loaded = 1;
					}
				);
				this.update_avatar_star_rating(
					jQuery(document)
					, function(){
						if (IsLoggedIn())
							global_loaded = 2;
						else
							global_loaded = 1;
					}
				);
				
			}
		}

	};

	function getRating($item)
	{
	    return ($item.options.rating != 0) ? $item.options.rating : $item.options.avgRating;
    }
	function initRating($item)
	{
	    setRating($item, -1, -1);
	}
	function setRating($item, $userRating, $avgRating)
	{
        if ($userRating != -1)
        {
		    $item.options.rating = $userRating;
		    $item.options.avgRating = $avgRating;
        }

        // change state: red or blue
	    var $state = 'blue';
		if (0 != $item.options.rating)
		    $state = 'red';
        if ($item.options.state)
		    $item.removeClass($item.options.css + $item.options.state);
		$item.options.state = $state;
		$item.addClass($item.options.css + $item.options.state);

        // set rating width
        var $rating = getRating($item);
		jQuery('div', $item)
			.width(
				($rating)
				* $item.options.step);

		// show avg. rating in tooltip
        var tooltip = $item.options.avgRating ? 'Average Rating: ' + ($item.options.avgRating / 2) : '';
		jQuery('span', $item).attr('title', tooltip);
	}
	function setWidth($item, $rating)
	{
		jQuery('div', $item)
			.width(
				($rating == -1 ? getRating($item) : $rating)
				* $item.options.step);
	}

/*
	function _setTooltip($item)
	{
		var tooltip = $item.options.avgRating ? 'Average Rating: ' + ($item.options.avgRating / 2) : '';
		jQuery('span', $item).attr('title', tooltip);
	}
	function setWidth($item, $rating)
	{
		jQuery('div', $item)
			.width(
				($rating == -1 ? $item.options.rating : $rating)
				* $item.options.step);
	}
	function setState($item, $state)
	{
		if ($state)
		{
			$item.removeClass($item.options.css + $item.options.state);
			$item.options.state = $state;
		}
		$item.addClass($item.options.css + $item.options.state);
	}
*/
	jQuery.fn.extend({
		rating_control: function(options)
		{
			return this.each(function() {
				var $item = jQuery(this);
				jQuery.ark.rating_control.rating_edit = $item; // ?
				$item.options = jQuery.extend({}, jQuery.ark.rating_control.defaults, options);

				if ($item.options.beforeShow)
					$item.options.beforeShow($item);

				// compose special float div and 5 span's-strars-buttons
				var s = '';
				var n = $item.options.n / 2;
				for (var i = 1; i <= n; ++i)
					s += '<span n="' + i + '"></span>';
				s += '<div class="rating_control_slider"></div>';
				$item.html(s);

                initRating($item);

				// need for mouse_move over 5 span's
				var reseting = null;
				var clearResetting = function()
				{
					if (reseting)
					{
						clearTimeout(reseting);
						reseting = null;
					}
				}

				// stars (span's) handlers
				jQuery('span', $item)
					.click(function() {
						var new_rating = 2 * jQuery(this).attr('n');
						if ($item.options.onSelect)
						{
							if (IsLoggedIn())
								$item.options.onSelect($item, new_rating);
							else
							{
								jQuery.ark.toggleFlash(false); // hide flash
								
								loginAction.LoginThenDo(
									function(){
										jQuery.ark.toggleFlash(true); // open flash
										
										$item.options.onSelect($item, new_rating);
										
										if (typeof FillUserAfterLogin == 'function')
											FillUserAfterLogin(); // Ura poprosil sdelat' na vsiakii sluchai
									}, 
									"jQuery.ark.toggleFlash(true)" // open flash
								);
							}
						}
					})
					.mouseover(function() {
						clearResetting();
						setWidth($item, 2 * jQuery(this).attr('n'));
					})
					.mouseout(function() {
						clearResetting();
						reseting = setTimeout(function() {
							clearResetting();
							setWidth($item, -1);
						}, 20);
					});

				// add handlers for login, logout events
				$item.addClass('listen_login');
				$item.bind('login', function() { if ($item.options.onLogin) $item.options.onLogin($item); });
				$item.addClass('listen_logout');
				$item.bind('logout', function() { setRating($item, 0, $item.options.avgRating); });

			});

		}
	});

})(jQuery);


//----- utils -----
function IsEmail(email) {
	var regex = /^([a-zA-Z0-9_\.\-\+])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
	if (regex.test(email)) return true;
	return false;
}

function trim(string) {
	return jQuery.trim(string); //string.replace(/(^\s+)|(\s+$)/g, '');
}

function isNumeric(x) {
	var RegExp = /^(-)?(\d*)(\.?)(\d*)$/;
	return x.match(RegExp);
}

function redirect(url) {
	if(document.getElementById('loginBox')) {
		window.location.href = url;
		return;
	}
	window.opener.location.href = url;
}


