// (called just before </body>)

Function.prototype.startsWith = function () { return false; };

// Fancy tooltips
window.addEvent('domready', function () {

	var tooltipBubble = $('tooltipBubble');

	$$('.tooltip').each(function (el, index) {
		el.addEvents({
			'mouseenter': function (e) {
				var coords = el.getCoordinates();
				coords.center = coords.left + parseInt(coords.width / 2, 10);

				tooltipBubble.getElement('.text').innerHTML = el.getElement('span').innerHTML;
				var bubbleSize = tooltipBubble.getSize();
				tooltipBubble.setStyle('opacity', 0);
				tooltipBubble.setStyle('top', coords.top + (coords.height - 10));
				tooltipBubble.setStyle('left', parseInt(coords.center - (bubbleSize.x / 2), 10));
				tooltipBubble.fade(1);

			},
			'mouseleave': function (e) {
				tooltipBubble.fade(0);
			}
		});
	});

	// global window click handler
	window.onBodyClick = (function () {
		var app = {
			_handlers: [],
			registerHandler: function (handler, container) {
				app._handlers.push({ fn: handler, el: container });
			},
			dispatchEvent: function (e) {
				if (app._handlers.length > 0) {
					for (var i = 0, j = app._handlers.length; i < j; i++) {
						var o = app._handlers[i];
						if (app.isOuterClick(e.target, o.el)) {
							o.fn();
						}
					}
				}
			},
			isOuterClick: function (target, container) {
				return !target.getParents().contains(container);
			}
		};

		return app;
	})();

	$(window).addEvent('click', onBodyClick.dispatchEvent);


	var friendslistSettings = Cookie.read('friendslist');
	if (friendslistSettings && $('friendsList')) {
		friendslistSettings = JSON.decode(friendslistSettings);

		if (friendslistSettings.expanded === true) {
			friendsList.show(true);
		}
	}

	if ($('achievementNotification')) {
		var achievement = $('achievementNotification');
		achievement.getElement('.close').addEvent('click', function (e) {
			e.stop();
			achievement.dissolve();
		});

		var data = JSON.decode(achievement.getElement('input').get('value'));
		facebook.streamPublish(data, 'fa');

		(function () {
			achievement.reveal();
		}).delay(1000);
	}

	if ($('unlockNotification')) {
		var data = JSON.decode($('unlockNotification').getElement('input').get('value'));
		facebook.streamPublish(data, 'ul');
	}

	if ($('quickNav')) {
		$('quickNav').getElements('li').each(function (el) {
			el.addEvents({
				'mouseenter': function () {
					var coordinates = this.getCoordinates();
					var bubble = $(this.get('rel'));
					bubble.setStyles({
						'left': coordinates.left - ((250 - coordinates.width) / 2),
						'top': coordinates.top + coordinates.height + 2
					});
					bubble.show();
				},
				'mouseleave': function () {
					$(this.get('rel')).hide();
				}
			});
		});
	}
});

var reloadCaptcha = function (id) {
	var captchaImage = $(id);
	var urls = [
		'/images2/transparent.png', 
		'/PublicPages/Captcha.aspx?nocache=' + parseInt(1000000 * Math.random(), 10)];
	
	var updateImg = (function () {
		captchaImage.src = urls[1];
		return false;
	}).delay(700);
	
	if (captchaImage.src.contains(urls[0])) {
		return updateImg;
	}
	
	captchaImage.src = urls[0];
	return updateImg;
};

// friendslist
var friendsList = {

	isVisible: false,
	container: null,
	size: null,
	fx: null,
	currentPage: 1,
	totalPages: 0,
	rowHeight: 38,
	pageSize: 5,
	scrollFx: null,
	scrollTo: 0,
	isScrolling: false,
	totalFriends: 0,
	fetchedFriends: 0,
	initialized: false,
	friendsReq: null,
	messageReq: null,
	popup: null,
	user: null,

	init: function () {
		this.totalFriends = $('friendsListData').get('value').split(',')[0].toInt();

		this.loader = new Element('div', {
			id: 'friendsLoader',
			styles: { display: 'none' }
		}).inject($('friendsList'), 'top');

		if (this.totalFriends < this.pageSize) {
			this.totalPages = 1;
		} else {
			this.totalPages = Math.ceil((this.totalFriends * this.rowHeight) / (this.rowHeight * this.pageSize));
		}

		this.initialized = true;
	},

	getFx: function () {
		if (!this.initialized) {
			this.init();
		}

		if (!this.fx) {
			var that = this;

			if (this.totalFriends !== 0) {
				that.friendsReq = that.createRequest('GetFriends', that.injectItems.bind(that));
				that.friendsReq.onRequest = function () {
					$('friendItemWrapper').fade(0.3);
					friendsList.loader.show();
				};
				that.friendsReq.send(JSON.encode({ offset: 0, limit: 5 }));
			}

			that.container = $('friendsList');
			that.size = that.container.getSize();
			that.container.setStyle('margin-top', parseInt('-' + that.size.y, 10));
			that.fx = new Fx.Tween(that.container, {
				wheelStops: false,
				onComplete: function () {
					that.onShowFriendsComplete();
				}
			});
		}

		return this.fx;
	},

	onShowFriendsComplete: function () {
		if (this.isVisible) {
			Cookie.write('friendslist', JSON.encode({ expanded: true }), { path: '/' });
			$('toggleFriendsList').removeClass('closed').addClass('open');
		} else {
			Cookie.write('friendslist', JSON.encode({ expanded: false }), { path: '/' });
			$('toggleFriendsList').removeClass('open').addClass('closed');
		}
	},
	show: function (fast) {
		if (fast) {
			this.getFx().set('margin-top', 0);
		} else {
			this.getFx().start('margin-top', 0);
		}

		this.isVisible = true;
	},
	hide: function () {
		var to = parseInt('-' + this.size.y, 10);
		this.getFx().start('margin-top', to);
		this.isVisible = false;
	},
	toggle: function () {
		this.isVisible ? this.hide() : this.show();
	},

	injectItems: function (rows) {
		var numRows = rows.length, targetEl = $('friendItemWrapper'), that = this;
		if (numRows > 0) {
			that.fetchedFriends += numRows;

			for (var i = 0; i < numRows; i++) {
				var wrapper = new Element('div', {
					'class': 'friendItem'
				});
				var trigger = new Element('div', {
					'class': 'trigger',
					html: '<img src="/images2/transparent.png"/>',
					events: {
						click: function (e) {
							that.onFriendItemClick(this, e);
						}
					}
				});

				wrapper.innerHTML = rows[i];
				trigger.inject(wrapper);
				wrapper.inject(targetEl);
			}
		}

		$('friendItemWrapper').fade(1);
		friendsList.loader.hide();
	},

	onFriendItemClick: function (el, event) {
		event.stop();
		var pos = el.getPosition();
		var arr = el.getParent().getElement('input').get('value').split('|');
		this.showUserPopup({ userid: arr[0].toInt(), username: arr[1], avatar: arr[2] }, pos);
	},

	// scroller
	getScrollFx: function () {
		if (!this.scrollFx) {
			this.scrollFx = new Fx.Scroll($('friendItemWrapper'));
		}

		return this.scrollFx;
	},
	getPrevPage: function () {
		if (this.currentPage === 1) {
			return;
		}

		var to = this.scrollTo - (this.pageSize * this.rowHeight);
		to = to < 0 ? 0 : to;

		this.getScrollFx().start(0, to);
		this.scrollTo = to;
		this.currentPage--;
	},
	getNextPage: function () {
		if (this.currentPage === this.totalPages) {
			this.getScrollFx().toTop();
			this.currentPage = 1;
			this.scrollTo = 0;
			return;
		}

		if (this.fetchedFriends === this.totalFriends || this.fetchedFriends > (this.currentPage * this.pageSize)) {
			// all is fetched, just animate
			this._scrollToNextPage();
		} else {
			// fetch from server
			this.friendsReq.onSuccess = function (response) {
				friendsList.injectItems(response.d);
				friendsList._scrollToNextPage();
			};

			var params = { offset: 0, limit: 0 };
			params.offset = this.fetchedFriends;
			var _limit = this.totalFriends - params.offset;
			params.limit = (_limit <= this.pageSize) ? _limit : this.pageSize;
			this.friendsReq.send(JSON.encode(params));
		}
	},
	_scrollToNextPage: function () {
		var 
			to = this.scrollTo + (this.pageSize * this.rowHeight),
			max = (this.totalFriends - this.pageSize) * this.rowHeight;

		if (max < to) {
			to = max;
		}

		this.getScrollFx().start(0, to);
		this.scrollTo = to;
		this.currentPage++;
	},

	getPopup: function () {
		if (!this.popup) {
			var Popup = function () {
				var 
					timerId = null,
					_el = $('friendsListPopup'),
					_avatar = _el.getElement('img'),
					_username = _el.getElement('b'),
					_textarea = _el.getElement('textarea'),
					_loadingPanel = _el.getElementById('sendingMessage'),
					_composePanel = _el.getElementById('composeMessage'),
					_statusPanel = _el.getElementById('messageStatus');

				return {
					element: _el,
					initialize: function (user, position) {
						clearTimeout(this.timerId);
						this.setAvatarUrl(user.avatar).setUsername(user.username).setMessageText('').hideLoading().hideStatusMessage();
						return this;
					},
					show: function (position) {
						_el.setStyles({ top: position.y, left: position.x - 270 });
						_el.show();
						_textarea.focus();
						return this;
					},
					hide: function (delay) {
						delay = delay || 0;
						clearTimeout(this.timerId);
						this.timerId = window.setTimeout(function () {
							_el.hide();
						}, delay);

						return this;
					},
					setAvatarUrl: function (url) {
						_avatar.set('src', url);
						return this;
					},
					setUsername: function (username) {
						_username.set('text', username);
						return this;
					},
					setMessageText: function (message) {
						_textarea.set('value', message);
						return this;
					},
					getMessageText: function () {
						return _textarea.get('value');
					},
					showLoading: function () {
						_composePanel.hide();
						_loadingPanel.show();
						return this;
					},
					hideLoading: function () {
						_composePanel.show();
						_loadingPanel.hide();
						return this;
					},
					showStatusMessage: function (type) {
						_composePanel.hide();
						_statusPanel.set('class', 'notify ' + type).show();
						return this;
					},
					hideStatusMessage: function () {
						_statusPanel.set('class', '').hide();
						return this;
					}
				};
			};

			this.popup = new Popup();
			window.onBodyClick.registerHandler(this.popup.hide, this.popup.element);
		}

		return this.popup;
	},
	showUserPopup: function (user, position) {
		this.getPopup().initialize(user, position).show(position);
		this.user = user;
	},
	hideUserpopup: function () {
		this.getPopup().hide();
	},
	sendMessage: function () {
		var 
			that = this,
			message = that.getPopup().getMessageText().trim();

		if (message.length === 0) {
			return false;
		}

		that.getPopup().showLoading();

		if (!that.messageReq) {
			that.messageReq = that.createRequest('SendMessage', function (res) {
				that.getPopup().hideLoading();
				if (res === true) {
					that.popup.showStatusMessage('success').hide(1500);
				} else {
					that.popup.showStatusMessage('error');
				}
			});
		}

		that.messageReq.send(JSON.encode({ userid: that.user.userid, message: message }));
	},
	visitProfile: function () {
		window.location = '/Publicpages/UserProfile.aspx?userid=' + this.user.userid;
	},
	createRequest: function (path, callback) {
		if (!path) {
			return false;
		}

		callback = callback || function () { };

		var req = new Request.JSON({
			method: 'post',
			url: '/WebServices/FriendsListData.asmx/' + path,
			urlEncoded: false,
			headers: {
				'Content-Type': 'application/json; charset=utf-8'
			},
			onSuccess: function (response) {
				callback(response.d);
			},
			onComplete: function () {
				if (this.status === 500) {
					// server error
				}
			}
		});

		return req;
	}

};

// Countdown
var Countdown = function (to, events, speed) {
	var _events = {
		start: events.onStart || function () { },
		finish: events.onFinish || function () { },
		tick: events.onTick || function () { }
	};

	var _to = {
		days: to.days > 0 ? to.days : 0,
		hours: to.hours > 0 ? to.hours : 0,
		minutes: to.minutes > 0 ? to.minutes : 0,
		seconds: to.seconds > 0 ? to.seconds : 0
	};

	var _ticker = null;

	var _tick = function (self) {
		if (_to.seconds !== 0) {
			_to.seconds -= 1;
		} else if (_to.minutes !== 0) {
			_to.minutes -= 1;
			_to.seconds = 59;
		} else if (_to.hours !== 0) {
			_to.hours -= 1;
			_to.minutes = 59;
			_to.seconds = 59;
		} else if (_to.days !== 0) {
			_to.days -= 1;
			_to.hours = 23;
			_to.minutes = 59;
			_to.seconds = 59;
		} else {
			_to.days = 0;
			_to.hours = 23;
			_to.minutes = 59;
			_to.seconds = 59;
		}
		_events.tick(_to);

		if ((_to.days + _to.hours + _to.minutes + _to.seconds) === 0) {
			_events.finish(null);
			return self.stop();
		}
	};

	this.stop = function () {
		clearInterval(_ticker);
	};

	this.start = function () {
		_events.start(_to);
		if ((_to.days + _to.hours + _to.minutes + _to.seconds) !== 0) {
			_ticker = setInterval(_tick, speed || 1000, this);
		} else {
			_events.finish(null);
			this.stop();
		}
	};

	return this;
};

// Gps
var gps = {

	buttons: {},
	panes: {},
	tooltips: null,
	currentMap: null,

	onWorldMapButtonClick: function (e) {
		e.stop();
		gps.toggleMenuPane('worldMap', this);
	},

	onHelpButtonClick: function (e) {
		e.stop();
		gps.toggleMenuPane('gpsHelp', this);
	},

	onCloseButtonClick: function (e) {
		e.stop();
		gps.hideAll();
		gps.currentMap.show();
	},

	toggleMenuPane: function (pane, el) {
		if (el.hasClass('active')) {
			gps.panes[pane].hide();
			el.removeClass('active');
			gps.currentMap.show();
		} else {
			gps.hideAll();
			gps.panes[pane].show();
			el.addClass('active');
		}
	},

	onWorldMapClick: function (e) {
		if (e.target.get('tag') === 'input') {
			if (e.target.hasClass('current')) {
				e.stop();
				gps.hideAll();
				gps.currentMap.show();
				return;
			}

			if (!e.target.hasClass('open')) {
				e.stop();
				return;
			}
		}
	},

	hasPane: function (pane) {
		return typeof (gps.panes[pane]) !== 'undefined';
	},

	hideAll: function () {
		var pane, button;
		for (pane in gps.panes) {
			gps.panes[pane].hide();
		}

		for (button in gps.buttons) {
			gps.buttons[button].removeClass('active');
		}
	},

	init: function () {
		var container = $('citymap');

		if (!container) {
			return;
		}

		container.getElements('.pane').each(function (el) {
			var id = el.get('id');
			gps.panes[id] = el;

			if (id === 'currentMap') {
				gps.currentMap = el;
			}
		});

		var elms = container.getElements('.helptip');
		gps.tooltips = new Tips(elms, { className: 'bubble', offset: { x: 16, y: 0} });

		container.getElements('.close').addEvent('click', gps.onCloseButtonClick);

		$('worldMap').addEvent('click', gps.onWorldMapClick);

		gps.buttons['worldMapButton'] = $('worldMapButton');
		gps.buttons['worldMapButton'].addEvent('click', gps.onWorldMapButtonClick);

		var miniMap = $('miniWorldMap');
		miniMap.addEvent('click', function (e) {
			e.stop();
			gps.buttons['worldMapButton'].fireEvent('click', e);
		});

		gps.blinkCurrentCity(miniMap.getElement('.current'), 40);

		gps.buttons['helpButton'] = $('helpButton');
		gps.buttons['helpButton'].addEvent('click', gps.onHelpButtonClick);

		var blinkEl = gps.currentMap.getElement('input.blink');
		if (blinkEl) {
			gps.showStartHere(blinkEl);
		}
	},

	blinkCurrentCity: function (el, times) {
		if (times > 0) {
			el.toggle();
			(function () {
				gps.blinkCurrentCity(el, (times -= 1));
			}).delay(500);
		}
	},

	showStartHere: function (el) {
		var pf = new PulseFade(el, {
			duration: 800
		});

		pf.start(10000);

		var arrow = $('mapStartHere');
		var offset = el.getPosition(gps.currentMap);

		arrow.setStyles({
			left: offset.x + 96,
			top: offset.y + 2
		});

		(function () {
			var tween = new Fx.Tween(arrow, { transition: Fx.Transitions.Elastic.easeOut, duration: 2000 });
			arrow.reveal(250);
			tween.start('left', (offset.x + 36));
		}).delay(2000);
	}
};

var carSelector = {
	scroller: null,
	leftButton: null,
	rightButton: null,
	xOffset: 0,
	itemWidth: 0,
	scrollWidth: 0,

	scrollRight: function () {
		var xTarget = carSelector.xOffset + carSelector.itemWidth;
		if (xTarget <= carSelector.scrollWidth) {
			carSelector.scroller.start(xTarget, 0);
			carSelector.xOffset = xTarget;
		}
	},
	scrollLeft: function () {
		var xTarget = carSelector.xOffset - carSelector.itemWidth;
		if (xTarget >= 0) {
			carSelector.scroller.start(xTarget, 0);
			carSelector.xOffset = xTarget;
		}
	},
	onScrollComplete: function (e) {
		carSelector.leftButton.removeClass('disabled');
		carSelector.rightButton.removeClass('disabled');

		if (carSelector.scrollWidth === carSelector.xOffset) {
			carSelector.rightButton.addClass('disabled');
		}

		if (0 === carSelector.xOffset) {
			carSelector.leftButton.addClass('disabled');
		}
	},
	init: function () {
		var container = $('carSelector');

		if (!container) {
			return;
		}

		var items = container.getElements('li');
		var itemWidth = items[0].getSize().x;
		var scrollEl = container.getElement('.body');
		var itemsVisible = Math.floor(scrollEl.getSize().x / itemWidth);

		container.getElement('ul').setStyle('width', itemWidth * items.length);
		carSelector.scrollWidth = itemWidth * items.length - itemWidth * itemsVisible;
		carSelector.itemWidth = itemWidth;

		carSelector.scroller = new Fx.Scroll(scrollEl, {
			onComplete: carSelector.onScrollComplete
		});

		carSelector.leftButton = container.getElement('.left').addEvent('click', carSelector.scrollLeft);
		carSelector.rightButton = container.getElement('.right').addEvent('click', carSelector.scrollRight);

		carSelector.onScrollComplete();
	}
};

// User Profile
var userProfile = {
	parseDiff: function (diff) {
		if (diff > 0) {
			return {
				days: Math.floor(diff / (60 * 60 * 24)),
				hours: Math.floor(diff / (60 * 60)) % 24,
				minutes: Math.floor(diff / (60)) % 60,
				seconds: Math.floor(diff) % 60
			};
		}

		return { days: 0, hours: 0, minutes: 0, seconds: 0 };
	},

	onTick: function (e) {
		var days = e.days;
		var hours = e.hours;
		hours += days * 24;
		hours = hours < 10 ? '0' + hours : hours;
		var minutes = e.minutes < 10 ? '0' + e.minutes : e.minutes;
		var seconds = e.seconds < 10 ? '0' + e.seconds : e.seconds;
		userProfile.display.set('text', hours + ':' + minutes + ':' + seconds);
	},

	onFinish: function () {
		userProfile.container.getParent().tween('height', 0);
	},

	getFormattedTime: function (e) {
		var days = e.days;
		var hours = e.hours;
		hours += days * 24;
		hours = hours < 10 ? '0' + hours : hours;
		var minutes = e.minutes < 10 ? '0' + e.minutes : e.minutes;
		var seconds = e.seconds < 10 ? '0' + e.seconds : e.seconds;
		return hours + ':' + minutes + ':' + seconds;
	},

	onRepairTick: function (e) {
		userProfile.repairTime.set('text', userProfile.getFormattedTime(e));
	},

	onReduceTick: function (e) {
		userProfile.jailWaitTime.set('text', userProfile.getFormattedTime(e));
	},

	initJailTimeCountdown: function () {
		var container = this.container = $('jailTimeLeft');

		if (container) {
			var diff = parseInt(container.getElement('input').get('value'), 10);
			this.display = container.getElement('strong');
			new Countdown(this.parseDiff(diff), { onTick: this.onTick, onFinish: this.onFinish }).start();
		}

		var repairTime = this.repairTime = $('repairAgainIn');

		if (repairTime) {
			var ttr = repairTime.get('text').split(':'); // time to repair
			new Countdown({ hours: ttr[0].toInt(), minutes: ttr[1].toInt(), seconds: ttr[2].toInt() }, { onTick: this.onRepairTick }).start();
		}

		var jailWaitTime = this.jailWaitTime = $('jailWaitTimeCounter');

		if (jailWaitTime) {
			var ttrcp = jailWaitTime.get('text').split(':');
			new Countdown({ hours: ttrcp[0].toInt(), minutes: ttrcp[1].toInt(), seconds: ttrcp[2].toInt() }, { onTick: this.onReduceTick }).start();
		}
	}
};

var currentPage = window.location.pathname.toLowerCase();
if (currentPage === '/publicpages/userprofile.aspx' || currentPage === '/pages/garage.aspx') {
	userProfile.initJailTimeCountdown();
	carSelector.init();
}
if (currentPage === '/pages/citymap.aspx' || currentPage === '/pages/startpage.aspx') {
	gps.init();
	carSelector.init();
}
