﻿var soundManager;

var invitesReceiver = $.init(function() {
	var 
	self = this,
	invites = {},
	isCollapsed = false,
	blinkQueue = [], // Очередь для инвайтов, которые показываются при isCollapsed == true
	blinkQueueInterval,  // Функция, которая будет показывать инвайты из blinkQueue
	readyToBlink = true, // Флаг для определения того, можно ли показать следующий инвайт из blinkQueue
	notifyID = {},
	minimizedCallback,
	popup,
	template,
	templates = {},
	container,

	types = {
		'invitation-notification:urn:com.anastasiadate.chat': 'chat',
		'virtual-gifts-notification:urn:com.anastasiadate.chat': 'gift'
	},

	togglePopup = this.togglePopup = function(empty) {
		empty = empty === undefined ? !popup.find('li:not(.template)').length : !!empty;

		if (popup.is(':visible') == empty)
			popup.removeClass('empty').css($.browser.msie ? {} : { opacity: empty ? 1 : 0 })
				.animate($.browser.msie ? {} : {
					opacity: empty ? 0 : 1
				}, {
					duration: 1100,
					complete: function() {
						popup.css($.browser.msie ? {} : { opacity: 1 }).toggleClass('empty', empty);
					}
				});

		return popup;
	},

	closeInvitation = this.closeInvitation = function() {
		var type, attendee, callback, complete, sender;

		for (var i = 0; i < arguments.length; i++) {
			if (arguments[i] != null) {
				$.isFunction(arguments[i])
					? (callback
						? complete = arguments[i]
						: callback = arguments[i])
					: arguments[i] && arguments[i].isNumeric && arguments[i].isNumeric()
						? attendee = arguments[i] || attendee
						: $.isPlainObject(arguments[i])
							? sender = arguments[i]
							: (typeof arguments[i] == 'string') && (type = arguments[i])
					;
			}
		}

		if (!(invites[type] && invites[type][attendee]))
			return;

		$.each(attendee ? invites[type][attendee] : invites[type], function(id) {
			if ($(this).parents().index(container) == -1)
				return;

			id = attendee || id;

			if (callback)
				callback.call($(this), id, sender);

			var start = {};
			var end = { height: 1 };

			if (!$.browser.msie) {
				start.opacity = 1;
				start.opacity = 0;
			}

			$(this)
				.css(start)
				.animate(end, 1000, function() {
					$(this).remove();

					togglePopup();

					if (complete)
						complete.call($(this), id, sender);
				});

			invites[type][id] = $('html:empty'); // пустой элемент
		});
	};

	var blink = function(type) {
		($.browser.msie) && ($.browser.version == 6)
			? $('.i-count.' + type + 's .i-number', popup).css({ display: 'none' }).each(function() {
				var that = this;

				setTimeout(function() {
					that.style.display = 'block';
				}, 500);
			})
			: $('.i-count.' + type + 's .i-number', popup).animate({ opacity: .01 }, 250).animate({ opacity: 1 }, 250)
		;
	};

	self.startNotify = function(type) {
		if (notifyID[type]) return;

		blink(type);

		notifyID[type] = setInterval(function() {
			blink(type);
		}, 1000);
	}

	self.stopNotify = function(type) {
		notifyID[type] && (notifyID[type] = clearInterval(notifyID[type]));
	}

	self.toggleNotify = function(type, state) {
		if (typeof state === 'undefined')
			state = false;

		return state ? this.startNotify(type) : this.stopNotify(type);
	};

	self.getChatHost = function() {
		var host = window.location.hostname;

		return 'http://' + (host.match(/^chat\./i) ? '' : 'chat.') + host.replace(/^www\./i, '');
	};

	self.init = function(_popup) {
		container = (popup = _popup).find('.template:first').parent(':first');

		for (var ns in types) {
			var type = types[ns];

			templates[type] = popup.find('.template.' + type);
			$('#' + type + 's').parents('.i-count:first').css({ display: 'none', visibility: 'hidden' });
		}

		$.notify('gift-received', function(gifts, _attendee) {
			preprocess(gifts, _attendee, true);
		});

		return this;
	};

	var preprocess = function(gifts, attendee, update) {
		for (var i = gifts.length; i--; )
			gifts[i].member = { id: attendee };

		self.process(gifts, attendee, 'gift', update || false);
	};

	self.process = function(notifications, attendee, type, update) {
		if (!type)
			type = 'chat';

		update = update || false;

		var 
		ivts = invites[type] || (invites[type] = {}),
		template = templates[type];

		if (!template)
			throw 'Template not found for invitation type: ' + type;

		$.each(ivts, function() {
			this.fresh = !(this.stale = true);
		});

		$.each(notifications, function() {
			this.sender || (this.sender = this.member);

			if (this.sender.id === attendee)
				return;

			var invite = (ivts[this.sender.id] || (ivts[this.sender.id] = template.bindo(this)));

			invite.data('type', type);
			invite.data('sender', this.sender);
			invite.stale = (invite.fresh = !invite.stale) && false;
			invite.timestamp = this.timestamp; // delete me

			invite.find('.bar').css({ width: invite.lifetime || this.lifetime + '%' });

			if (invite.fresh && (!update || this.fresh)) {
				invitesReceiver.enqueueInvite(invite);

				if (!!soundManager) {
					soundManager.playInvite();
					soundManager.toggleMute();
				}
			}
		});

		if (!!soundManager && soundManager.isMuted())
			soundManager.toggleMute();

		invitesReceiver.cleanUp(ivts, type);
	};

	self.cleanUp = function(invites, type) {
		if (!invites)
			return;

		var invitations = 0;

		for (var id in invites) {
			!invites[id].length && invites[id].stale
				? delete invites[id]
				: !invites[id].stale
					? (invitations += invites[id].length)
					: closeInvitation(type, id);
		};

		if (invitations) {
			$('#' + type + 's')
				.each(function() {
					self.toggleNotify(type, !!invitations && invitesReceiver.isCollapsed);
				})
				.text(invitations)
				.parents('.i-count:first').css({ display: 'block', visibility: 'visible' })
				;
		} else {
			$('#' + type + 's').parents('.i-count:first').css({ display: 'none', visibility: 'hidden' });
		}
	};

	self.toggleInvitations = function(minimize) {
		if (!popup) return;

		popup.find('li:not(.template)').each(function() {
			var invite = $(this);

			container.removeClass('notify');

			var animation = { height: minimize ? 0 : invite.restore('height') };
			var animend = { display: minimize ? 'none' : '' };

			if (!$.browser.msie) {
				animation.opacity = minimize ? 0 : 1;
				animend.opacity = '';
			}

			invite.parent().stop(true, true);
			invite.stop(true, true).animate(animation, 200, function() {
				invite.css(animend);
			});
		});

		if (!minimize) {
			readyToBlink = true;
			blinkQueue = [];
			clearInterval(blinkQueueInterval);
			blinkQueueInterval = null;
		}

		for (var ns in types)
			this.toggleNotify(types[ns], minimize);
	};

	self.enqueueInvite = function(invite) {
		if (invite.length && invite.fresh && invite.parents().index(container) == -1) {
			togglePopup(false);

			$("img.smile", invite).attr("src", function() {
				return invitesReceiver.getChatHost() + this.src.substring(this.src.indexOf("/i/"));
			});

			invite
				.prependTo(container)
				.css({ display: 'block' })
				.filter(':visible')
				.each(function() {
					$(this).store('height', $(this).height());
				})
				.height(0);

			// Разная анимация для разного состояния invitesReceiver.isCollapsed
			if (invitesReceiver.isCollapsed) {
				blinkQueue[blinkQueue.length] = invite;

				blinkQueueInterval = blinkQueueInterval || setInterval(function() {

					if (readyToBlink) {
						readyToBlink = false;

						var blinkingInvite = blinkQueue[0];

						if (!blinkQueue[0])
							return;

						blinkingInvite.hover(
							function() {
								clearTimeout($(this).restore('fadeTimeout'));
								blinkingInvite.parent().stop().css({ opacity: null });
							},

							function() {
								blinkingInvite.store('fadeTimeout', setTimeout(function() {
									if (invitesReceiver.isCollapsed) {
										blinkingInvite.parent().animate({ opacity: 0.01 }, 2400, function() {
											blinkingInvite.parent().css({ opacity: 1 }).removeAttr('filter');
											blinkingInvite.css({ display: 'none', height: 0 });
											container.removeClass('notify');
											readyToBlink = true;
										});
									}

									blinkQueue.shift();

									if (blinkQueue.length == 0) {
										clearInterval(blinkQueueInterval);
										blinkQueueInterval = null;
									}

									readyToBlink = !invitesReceiver.isCollapsed;
								}, 2500)); // blinkingInvite.store
							}
						); // blinkingInvite.hover

						container.addClass('notify');
						blinkingInvite.each(function() {
							$(this).animate({ height: $(this).restore('height') }, 1000);
						}).mouseout();

					} // if (readyToBlink)

				}, 500); // setTimeout
			} // if (invitesReceiver.isCollapsed)
			else {
				invite.each(function() {
					$(this).animate(
						{ height: $(this).restore('height') },
						1000,
						'linear',
						function() { }
					);
				});
			}

		}
	};
});

var popupController = $.init(function() {
	var 
	chats = {},
	invites,
	options = {
		chat: {
			height: 680,
			width: 815,
			toolbar: 0,
			scrollbars: 0,
			status: 0,
			resizable: 1,
			location: 0,
			menuBar: 0
		},
		invites: {
			height: 625,
			width: 260,
			toolbar: 0,
			scrollbars: 0,
			status: 0,
			resizable: 0,
			location: 0,
			menuBar: 0
		}
	},
	buildWindowFeatures = function(features) {
		var s = '';

		for (var key in features)
			if (key != 'name' && !$.isFunction(features[key]))
			s += ',' + key + '=' + features[key];

		return s.replace(/^,/, '');
	};

	this.init = function(o) {
		for (var k in o)
			for (var p in ((options[k] || (options[k] = {})) && o[k]))
			options[k][p] = o[k][p];
	};

	this.checkInvitesPopup = function() {
		try {
			if (invites && invites[0] && 'sleeve' == invites[0].name)
				return true;

			if (!window.invitesSubscribed)
				return false;

			invites = window.open('', options.invites.name || 'invitespopup');

			return window.invitesSubscribed = (invites && invites[0] && 'sleeve' == invites[0].name);
		} catch (e) {
			return window.invitesSubscribed = !!(invites = undefined);
		}
	};

	this.openChat = function() {
		var a, w;

		for (var i = 0; i < arguments.length; i++)
			typeof arguments[i] == 'number'
				? a = arguments[i]
				: typeof arguments[i] == 'string'
					? w = arguments[i]
					: null
				;

		try {
			chats[(a = a || '') || 'chat'] = window.open(
				invitesReceiver.getChatHost() + '/chat/' + a + (a && '/'),
				w || options.chat.name || ('chat' + (a || '')),
				buildWindowFeatures(options.chat)
			);

			chats[a || 'chat'].focus();
		} catch (e) {
			$.browser.safari && console && console.log(e && e.message);
		}
	};

	this.switchChat = function(id, sender) {
		contactListUpdatesReceiver.getContactElement(sender);
		chatController.changeAttendee(sender.id);
	};

	this.openInvites = function() {
		options.invites.left =
			($.browser.msie
				? window.screenLeft + document.documentElement.clientWidth
					: window.screenX + window.outerWidth) - 260;

		options.invites.top =
			($.browser.msie
				? window.screenTop + document.documentElement.clientHeight
					: window.screenY + window.outerHeight) - 700;

		var wd = 800;
		var hg = 600;
		var lf = screen.availWidth / 2 - wd / 2;
		var tp = screen.availHeight / 2 - hg / 2;

		invites = window.open(
			'http://chat.' + window.location.hostname.replace(/^www\./, '') + '/invites/',
			options.invites.name || 'invitespopup',
			buildWindowFeatures(options.invites),
			'chat',
			'width=' + wd + ',height=' + hg + ',top=' + tp + ',left=' + lf + ',toolbar=no,menubar=no,scrollbars=yes,resizable=yes,location=no,directories=no,status=no'
		);

		invites.focus();
	};
});

