var lang = null;
var GENERIC_ERROR = function() {
	alert("Wystąpił niespodziewany błąd. Spróbuj odświeżyć stronę i spróbować ponownie.\n" +
		"Jeśli błąd się powtarza, powiadom o tym administratora (jego adres można znaleźć w stopce).");
};
$(function() {
	lang = $(document.documentElement).attr('lang');
	function updatehints(input, hintsroot, data) {
		hintsroot.find('*').remove();
		if (data.hits.length > 0) {
			for (i=0; i<data.hits.length; i++) {
				item = $("<div class='" + data.hits[i]['class'] + "'>" + data.hits[i].html + "</div>")
				hintsroot.append(item);
				item.data('key', data.hits[i].key);
				if (item.hasClass('option')) {
					item.hover(
						function() { $(this).addClass('selected'); },
						function() { $(this).removeClass('selected'); }
					);
					item.click(function() {
						if ($(this).data('key'))
							input.attr('value', $(this).data('key'));
						input.blur();
						hintsroot.hide();
						if (input.data('autosubmit'))
							input.closest('form').submit();
					});
				}
			}
			hintsroot.show();
		} else {
			hintsroot.hide();
		}
	}
	$('.textbox_container').each(function() {
		var container = $(this);
		var label = $(this).attr('label');
		var input = $(this).find('input');
		input.focus(function() { container.addClass('focused_input'); });
		input.blur(function() { container.removeClass('focused_input'); });
		if (label) {
			var placeholder = $("<div class='placeholder' style='display: none'>" + label + "</div>");
			$(this).prepend(placeholder);
			$(this).click(function() { input.focus(); });
			input
				.focus(function() { placeholder.hide(); })
				.blur(function() { if (!input.attr('value')) placeholder.show(); });
			if (!input.attr('value')) placeholder.show();
		}
		if ($(this).attr('hintsfrom')) {
			var service = $(this).attr('hintsfrom');
			input.data('autosubmit', $(this).attr('autosubmit') ? true : false);
			var hintsroot = $("<div class='textbox_hints'></div>");
			var sentnumber = 0;
			var receivednumber = 0;
			var cache = {};
			$(this).before(hintsroot);
			hintsroot.hide();
			hintsroot.css({
				"top": container.position().top + container.height() + 4,
				"left": container.position().left
			});
			input.keydown(function(e) {
				if (e.which == 27) { // esc
					hintsroot.hide();
				} else if (e.which == 38 || e.which == 40) { // up || down
					items = hintsroot.find("div.option");
					if (items.length > 0)
					{
						selected = hintsroot.find("div.selected");
						if (selected.length == 0)
							selected = (e.which==38) ? items.first() : items.last();
						selected.removeClass("selected");
						if (e.which == 38) { // up
							selected = selected.prevAll('div.option').first();
							if (selected.length == 0)
								selected = items.last('div.option');
						} else {
							selected = selected.nextAll('div.option').first();
							if (selected.length == 0)
								selected = items.first('div.option');
						}
						selected.addClass("selected");
					}
				} else if (e.which == 37 || e.which == 39 || e.which == 9) { // left || right || tab
					// ignore
				} else if (e.which == 13) { // enter
					selected = hintsroot.find("div.selected");
					if (selected.length > 0) {
						e.returnValue = false;
						if (e.preventDefault)
							e.preventDefault();
						if (e.stopPropagation)
							e.stopPropagation();
						selected.click();
					}
				} else {
					// przetwarzamy w keyup
				}
			});
			input.keyup(function(e) {
				if (e.which == 27 || e.which == 38 || e.which == 40 || e.which == 37 || e.which == 39 || e.which == 9) { // esc || up || down || left || right || tab
					// ignore
				} else {
					var value = input.attr('value');
					if (value.length >= 3) {
						if (cache[value]) {
							updatehints(input, hintsroot, cache[value]);
						} else {
							$.ajax({
								url: service + "?type=json-hints&n=" + sentnumber + "&q=" + encodeURIComponent(value),
								dataType: 'json',
								success: function(data) {
									if (Number(data.n) < receivednumber)
										return;
									receivednumber = data.n;
									cache[value] = data;
									updatehints(input, hintsroot, data);
								}
							});
							sentnumber++;
						}
					}
					else
					{
						hintsroot.hide();
						hintsroot.find('*').remove();
					}
				}
			});
			input.focus(function() { $(this).keyup(); });
			input.blur(function() {
				setTimeout(function() { hintsroot.hide(); }, 200);
			});
		}
	});
	$(document).ajaxStart(function() {
		$('.ajax_loading').stop(true, false).fadeTo(300, .6);
	});
	$(document).ajaxStop(function() {
		$('.ajax_loading').stop(true, false).fadeTo(300, 0);
	});
	var errorMessageShown = false;
	$(document).ajaxError(function(event, XMLHttpRequest, ajaxOptions, thrownError) {
		if (errorMessageShown)
			return;
		errorMessageShown = true;
		if (confirm("Wystąpił błąd podczas próby kontaktu z serwerem. Być może nie jesteś zalogowany? " +
			"Spróbuj odświeżyć stronę.")) {
			location.reload(true);
		}
	});
	$('.iml').each(function() { apply_iml_aftereffects(this); });
});
var delayed_call = (function() {
	var klucze = {};
	var call = function() {
		var now_stamp = (new Date()).getTime();
		var byly_jakies = false;
		for (klucz in klucze) {
			if (klucze[klucz][0] <= now_stamp) {
				var func = klucze[klucz][1];
				delete klucze[klucz];
				func(klucz);
			}
			byly_jakies = true;
		}
		if (byly_jakies)
			setTimeout(call, 200);
	};
	var delayed_call = function(klucz, delay, func) {
		var now_stamp = (new Date()).getTime();
		if (klucze[klucz] == undefined)
			klucze[klucz] = [now_stamp + delay, func];
		else
			klucze[klucz][0] = now_stamp + delay;
		setTimeout(call, 200);
	};
	return delayed_call;
})();
function pokaz_przedmioty_grupy(grprz_kod, ajaxrequest_dir) {
	var setName = "gr" + Math.floor(Math.random() * 1000000);
	var okno = $("<div class='modalfr1' style='display: none'><div class='modalfr2'><div class='modalfrh'><div class='modalfrx'></div>" +
		"<div class='item'>" + ((lang == 'pl')?"Przedmioty w grupie":"Courses in this group") +
		"</div></div><div class='modalfrc iml'><div style='margin: 8px 12px; position: relative; padding-bottom: 25px;'><div class='ajax_loading' style='position: absolute; top: 10px; right: 0px;'></div>" +
		"<table cellspacing='1px' class='iml-siatka iml-siatka-grupy'><tbody><tr>" +
		"<th class='iml-first-col' id='nazwa_grupy'>" + (lang == 'pl' ? "Nazwa" : "Name") + "</th>" +
		"</tr></tbody><tbody id='" + setName + "_results'>" +
		"<tr class='iml-empty'><td class='iml-first-col'>Ładowanie...</td></tr></tbody></table>" +
		"<div class='ajax_ordering_pages_type2' setName='" + setName + "'></div></div></div></div></div>");
	var top_bottom_margin = 100;
	var width = 650;
	var height = ($(window).height() - (2*top_bottom_margin));
	if (height < 200)
		height = 200;
	okno.css({
		'left': (($(window).width() - width) / 2) + 'px',
		'width': width + 'px',
		'top': ($(window).scrollTop() + top_bottom_margin) + 'px',
		'height': height + 'px'
	});
	$(document.body).append(okno);
	
	var close_on_esc = null;
	var close = function() {
		okno.fadeOut(200, function() { okno.remove(); });
		$(document).unbind('keydown', close_on_esc);
	};
	close_on_esc = function(e) { if (e.which == 27) close(); };
	$(document).bind('keydown', close_on_esc);
	okno.find(".modalfrx").click(close);
	
	var contentHeight = height - 33;
	okno.find(".modalfrc").css({
		'height': contentHeight + 'px'
	});
	var receivednumber = 0;
	var sentnumber = 0;
	var receive_updateset = function(updates) {
		for (var i=0; i<updates.length; i++) {
			switch (updates[i].type) {
				case 'replace':
					okno.find('#' + updates[i].id).html(updates[i].html);
					apply_iml_aftereffects(okno.find('.iml'));
					break;
				case 'update-count':
					ordering.max = updates[i].count
					ordering.refreshDisplay();
					break;
				default:
					GENERIC_ERROR();
					break;
			}
		}
	};
	var update_contents = function() {
		ordering.refreshDisplay();
		var vars = {};
		vars['grprz_kod'] = grprz_kod;
		vars['tableState'] = ordering.getStateString();
		vars['setName'] = setName;
		sentnumber++;
		vars['n'] = sentnumber;
		$.ajax({
			'url': ajaxrequest_dir + "groupcourses",
			'type': 'GET',
			'data': vars,
			'dataType': 'json',
			'success': receive_updateset
		});
	};
	var ordering = AjaxOrdering.construct({
		lang: lang,
		setName: setName,
		order: (lang == 'pl') ? 'nazwaPL' : 'nazwaEN,nazwaPL',
		jump: 50,
		callback: function() { update_contents(); }
	});
	update_contents();
	okno.fadeIn(200);
	if (window._gaq) _gaq.push(['_trackPageview', ajaxrequest_dir + "groupcourses?grprz_kod=" + encodeURIComponent(grprz_kod)]);
}
function apply_iml_aftereffects(root) {
	$(root).find('table.iml-siatka tr td.iml-first-col a, table.iml-siatka tr td.iml-first-col span').each(function() {
		$(this)
			.hover(
				function() { $(this).closest('tr').addClass('iml-hover'); },
				function() { $(this).closest('tr').removeClass('iml-hover'); }
			);
	});
	$(root).find('a').each(function() {
		if ($(this).attr('grprz_kod')) {
			$(this).click(function() {
				pokaz_przedmioty_grupy($(this).attr('grprz_kod'), ajaxrequest_dir);
			});
			$(this).removeAttr('href');
		}
		if ($(this).attr('os_id')) {
			$(this).click(function() {
				pokaz_osobe($(this).attr('os_id'));
			});
			$(this).removeAttr('href');
		}
	});
	$(root).find('div.imlfield_editorlauncher').each(function() {
		var iml_id = $(this).attr('iml_id');
		var status = $(this).attr('status');
		var content_div = $(this).next();
		html = "<div class='bluebutton_container' style='float: right'><input class='imled_openeditor' type='button' value='" + ((lang == 'pl')?"Edytuj":"Edit") + "'></div>" +
			"<div class='draft_notice' style='display: none; float: right; margin: 3px 10px 0 0; color: #c00;'>" +
			((lang == 'pl') ? "Ta wersja robocza nie jest jeszcze opublikowana!" : "This draft version is not yet published!") + "</div>";
		$(this).html(html);
		var draft_notice = $(this).find(".draft_notice");
		var update_draft_notice = function() {
			if (status == 'draft')
				draft_notice.show();
			else
				draft_notice.hide();
		};
		update_draft_notice();
		$(this).find('input.imled_openeditor').click(function() {
			IMLEditor.open({
				'initial_tab': 'prosty',
				'content_source': 'db',
				'iml_id': iml_id,
				'close_callback': function() {
					content_div.html(IMLEditor.glob.find('.podglad_html').html());
					apply_iml_aftereffects(content_div);
					status = IMLEditor.content_status;
					update_draft_notice();
				}
			});
		});
	});
	$(root).find('a[iml_id]').click(function() {
		IMLEditor.open({
			'initial_tab': 'zaawansowany',
			'content_source': 'db',
			'iml_id': $(this).attr('iml_id')
		});
	});
}
function pokaz_osobe(os_id) {
	var okno = $("<div class='modalfr1' style='display: none'><div class='modalfr2'><div class='modalfrh'><div class='modalfrx'></div>" +
		"<div class='item'>" + ((lang == 'pl')?"Informacje kontaktowe":"Contact information") +
		"</div></div><div class='modalfrc iml'><div style='padding: 8px 12px 25px 12px; position: relative;'><div class='ajax_loading' style='position: absolute; top: 10px; right: 10px;'></div>" +
		"<div class='content'></div>" +
		"</div></div></div></div>");
	var width = 550;
	var height = 265;
	var top_bottom_margin = ($(window).height()/2 - height/2);
	if (top_bottom_margin < 20)
		top_bottom_margin = 20;
	okno.css({
		'left': (($(window).width() - width) / 2) + 'px',
		'width': width + 'px',
		'top': ($(window).scrollTop() + top_bottom_margin) + 'px',
		'height': height + 'px'
	});
	$(document.body).append(okno);
	
	var close_on_esc = null;
	var close = function() {
		okno.fadeOut(200, function() { okno.remove(); });
		$(document).unbind('keydown', close_on_esc);
	};
	close_on_esc = function(e) { if (e.which == 27) close(); };
	$(document).bind('keydown', close_on_esc);
	okno.find(".modalfrx").click(close);
	
	var contentHeight = height - 33;
	okno.find(".modalfrc").css({
		'height': contentHeight + 'px'
	});
	var url = ajaxrequest_dir + "contactinfo?os_id=" + os_id;
	okno.find('.content').load(url)
	if (window._gaq) _gaq.push(['_trackPageview', url]);
	okno.fadeIn(200);
}
var AjaxOrdering = {
	instances: {},
	setName: null,
	column_elements: null,
	page_selector_elements: null,
	orderRules: null,
	offset: null,
	jump: null,
	max: null,
	callback: null,
	lang: null,
	pagelist_margin: null,
	/**
	 * Zainicjuj i zwróć obiekt obsługujący sortowanie.
	 *
	 * Argumenty:
	 * - setName - musi być taka sama jak w elementach <span class='ajax_ordering_column' setName='nazwa' column='..'>,
	 * - order - początkowe sortowanie (np. "nazwisko,imie"),
	 * - offset - (opcjonalny, domyślnie zero) początkowy offset,
	 * - jump - (wymagany tylko przy użyciu paginacji) rozmiar skoku, czyli ilość elementów jednorazowo wyświetlanych na stronie,
	 * - max - (wymagany tylko przy użyciu paginacji) sumaryczna liczba elementów w tabeli (wliczając niewyświetlane),
	 * - callback(ordering) - funkcja, która zostanie wywołana, gdy użytkownik zmieni parametry sortowania,
	 * - lang - "pl" lub "en", domyślnie "pl",
	 * - pagelist_margin - domyślnie 4, ustaw lista odnośników jest zbyt szeroka.
	 */
	construct: function(args) {
		var ordering = $.extend({}, AjaxOrdering);
		AjaxOrdering.instances[args.setName] = ordering;
		ordering.setName = args.setName;
		ordering.column_elements = []
		ordering.page_selector_elements = []
		ordering.orderRules = AjaxOrdering.orderRulesFromString(args.order)
		ordering.offset = args.offset ? Number(args.offset) : 0
		ordering.jump = args.jump ? Number(args.jump) : null;
		ordering.max = args.max ? Number(args.max) : null;
		ordering.callback = args.callback;
		ordering.lang = args.lang ? args.lang : 'pl';
		ordering.pagelist_margin = args.pagelist_margin ? args.pagelist_margin : 4;
		$('.ajax_ordering_column').each(function() {
			if ($(this).attr('setName') == ordering.setName) {
				ordering.column_elements.push($(this));
				$(this).click(function() { ordering.columnClick($(this)); });
			}
		});
		$('.ajax_ordering_pages_type1, .ajax_ordering_pages_type2').each(function() {
			if ($(this).attr('setName') == ordering.setName) {
				ordering.page_selector_elements.push($(this));
			}
		});
		$('.ajax_ordering_pages_type1').each(function() {
			var html = "";
			html += "<a class='previous' style='display: none'>&lt; " + ((ordering.lang == 'pl') ? "Poprzednia" : "Previous") + "</a>";
			html += "<span class='current' style='display: none'><span class='numbers'></span>" + ((ordering.lang == 'pl') ? " z " : " of ") + "<span class='total'></span></span>";
			html += "<a class='next' style='display: none'>" + ((ordering.lang == 'pl') ? "Następna" : "Next") + " &gt;</a>";
			$(this).html(html);
			$(this).find('a').click(function() {
				var e = $(this).closest('.ajax_ordering_pages_type1');
				var ordering = AjaxOrdering.instances[e.attr('setName')];
				ordering.offset = Number($(this).attr('offset'));
				ordering.refreshDisplay();
				ordering.callback(ordering);
				e.find('.numbers').stop(false, true).fadeTo(0, 0).fadeTo(200, 1);
			});
		});
		ordering.refreshDisplay();
		return ordering;
	},
	/** Obsłuż zdarzenie kliknięcia w element uchwytu kolumny - zmień sposób sortowania (orderRules). */
	columnClick: function(element) {
		var clickedColumns = $(element).attr('column').split(',');
		this.offset = 0;
		var ascending = true;
		if (this.orderRules.length > 0
			&& this.orderRules[0].column == clickedColumns[0]
			&& this.orderRules[0].ascending == true)
				ascending = false;
		var references = [];
		var newRules = [];
		for (var i=0; i<this.orderRules.length; i++) {
			if ($.inArray(this.orderRules[i].column, clickedColumns) != -1)
				references[this.orderRules[i].column] = this.orderRules[i];
			else
				newRules.push(this.orderRules[i]);
		}
		var prefixRules = [];
		for (var i=0; i<clickedColumns.length; i++) {
			var rule = null;
			if (references[clickedColumns[i]]) {
				rule = references[clickedColumns[i]];
				rule.ascending = ascending;
			}
			else
				rule = {column: clickedColumns[i], ascending: ascending};
			prefixRules.push(rule);
		}
		this.orderRules = prefixRules;
		for (var i=0; i<newRules.length; i++)
			this.orderRules.push(newRules[i]);
		this.refreshDisplay();
		if (this.callback)
			this.callback(this);
	},
	/** Zmień orderRules (lista słowników) na string ("-wiek,nazwisko"). */
	orderRulesToString: function(orderRules) {
		return ($.map(orderRules, function(e) { return (e.ascending ? "" : "-") + e.column; })).join(",");
	},
	/** Odczytaj orderRules z przekazanej postaci stringowej. */
	orderRulesFromString: function(s) {
		return $.map(s.split(","), function(e) { return { column: e.replace("-", ""), ascending: e[0] != '-' }; });
	},
	/** Odśwież sposób wyświetlania elementów (m.in. uchwytów kolumn) związanych z danym setem. */
	refreshDisplay: function() {
		for (var i=0; i<this.column_elements.length; i++) {
			var e = $(this.column_elements[i]);
			e.removeClass('icon_asc');
			e.removeClass('icon_desc');
			if (e.attr('column').split(',')[0] == this.orderRules[0].column)
				e.addClass(this.orderRules[0].ascending ? 'icon_asc' : 'icon_desc');
		}
		for (var i=0; i<this.page_selector_elements.length; i++) {
			var e = $(this.page_selector_elements[i]);
			if (e.hasClass('ajax_ordering_pages_type1')) {
				if (this.jump != null && this.max > 0) {
					if (this.offset > 0)
						e.find('.previous').attr('offset', this.offset - this.jump).show();
					else
						e.find('.previous').hide();
					if (this.max > 0) {
						e.find('.numbers').text((this.offset + 1) + "-" + Math.min(this.offset + this.jump, this.max));
						e.find('.total').text(this.max);
						e.find('.current').show();
					} else
						e.find('.current').hide();
					if (this.offset < Math.floor((this.max - 1)/this.jump) * this.jump)
						e.find('.next').attr('offset', this.offset + this.jump).show();
					else
						e.find('.next').hide();
					e.show();
				} else {
					e.hide();
				}
			} else if (e.hasClass('ajax_ordering_pages_type2')) {
				var currentHash = this.offset+":"+this.jump+":"+this.max;
				if (this.jump != null && this.max > 0) {
					if (e.data('hash') != currentHash) {
						var currentPage = (this.offset/this.jump) + 1;
						e.stop(true, false).fadeTo(0, 0);
						var stopPage = Math.max(
							currentPage,
							Math.min(
								currentPage + this.pagelist_margin + Math.max(0, this.pagelist_margin - currentPage + 1),
								Math.floor((this.max - 1)/this.jump) + 1
							));
						var html = "";
						if (currentPage > 1)
							html += "<a page='" + (currentPage - 1) + "' class='ajax_ordering_previous'>" + ((this.lang == 'pl') ? "Poprzednia" : "Previous") + "</a>";
						if (stopPage > 1) {
							var page = Math.max(1, currentPage - this.pagelist_margin - Math.max(0,
								this.pagelist_margin - (Math.floor((this.max - 1)/this.jump) + 1 - currentPage)));
							for (; page <= stopPage; page++)
								if (page == currentPage)
									html += "<b>" + page + "</b> ";
								else
									html += "<a page='" + page + "'>" + page + "</a> ";
						}
						if (currentPage < stopPage)
							html += "<a page='" + (currentPage + 1) + "' class='ajax_ordering_next'>" + ((this.lang == 'pl') ? "Następna" : "Next") + "</a>";
						e.html(html);
						e.find('a').click(function() {
							var e = $(this).closest('.ajax_ordering_pages_type2');
							var ordering = AjaxOrdering.instances[e.attr('setName')];
							ordering.offset = (Number($(this).attr('page')) - 1) * ordering.jump;
							ordering.refreshDisplay();
							ordering.callback(ordering);
						});
						e.fadeTo(300, 1);
					}
				} else {
					e.html('');
				}
				e.data('hash', currentHash);
			}
		}
	},
	/** Zwróc string stanu (zserialiowane parametry dynamiczne; pomijamy te, który są niezmienialne przez usera). */
	getStateString: function() {
		return AjaxOrdering.orderRulesToString(this.orderRules) + ":" + this.offset;
	}
}


