String.prototype.trim = function() {
    a = this.replace(/^\s+/, '');
    return a.replace(/\s+$/, '');
};

Date.prototype.toStringYmd = function() {
	var ret = this.getFullYear() + '-';
	var month = this.getMonth();
	if (month < 9) ret += '0';
	ret += (month + 1.0) + '-';
	var day = this.getDate();
	if (day < 10) ret += '0';
	ret += day;
	return ret;
};

jQuery.fn.outerHtml = function(s) {
	return (s)
	? this.before(s).remove()
	: jQuery("<p>").append(this.eq(0).clone()).html();
};

jQuery.fn.unwrapInner = function() {
	return this.replaceWith(this.html());
};

jQuery.fn.addOptions = function(opt) {
	for (var val in opt) {
		this.append('<option value="' + val + '">' + opt[val] + '</option>');
	}
	return this;
};

jQuery.fn.serializeObject = function()
{
    var o = {};
    var a = this.serializeArray();
    $.each(a, function() {
        if (o[this.name]) {
            if (!o[this.name].push) {
                o[this.name] = [o[this.name]];
            }
            o[this.name].push(this.value || '');
        } else {
            o[this.name] = this.value || '';
        }
    });
    return o;
};



jQutils = {
	
	autoComplete: function(opt){
		opt.element.addClass('autoComplete');
		opt.element.data.autoCompleteSeq = 0;
		opt.element.data.timeoutId = -1;
		var callback = opt.callback;
		if (typeof callback != "undefined" && typeof callback == "function") opt.element.data('autoCompleteCallback', callback);
		if (opt.placement) opt.element.parent().css('position', 'relative');
		opt.element.blur(function(){
			//opt.element.parent().find('div.autoComplete').hide();
		});
		var label = opt.element.closest('div.Form_Area').find('div.Form_Label');
		if (label.length) {
			var markupRemoveSelector = "span.autocomplete_info";
			var markup = '<span class="autocomplete_info" style="float: right;"><img src="/images/icon_autocomplete.png" alt="Pole z podpowiedzią (auto-uzupełnianie)" title="Pole z podpowiedzią (auto-uzupełnianie)" /></span>';
			label.find(markupRemoveSelector).remove();
			label.html(label.html() + markup);
		}
		opt.element.keyup(function(ev){
			if (opt.element.val().length < opt.minLength) {
				if ($(this).data.timeoutId > -1) clearTimeout($(this).data.timeoutId);
				opt.element.parent().find('div.autoComplete div.item').remove();
				opt.element.parent().find('div.autoComplete').hide();
				ev.stopPropagation();
				return false;
			}
			
			var ignoreKeyCodes = [13, 16, 17, 18, 20, 27, 35, 36, 37, 38, 39, 40, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123];
			//arrows, home, end, pageUp, pageDn, shift, ctrl, escape, alt, capsLock, f1-f12
			for (code in ignoreKeyCodes) {
				if (ignoreKeyCodes[code] == ev.keyCode) {ev.stopPropagation(); return false;}
			}
			
			opt.element.addClass('waiting');
			
			if ($(this).data.timeoutId > -1) clearTimeout($(this).data.timeoutId);
			var val = $(this).val();
			var seq = ++($(this).data.autoCompleteSeq);
			
			$(this).data.timeoutId = setTimeout(
				function(){
					$.getJSON(
						opt.url,
						{seq: seq, value: val},
						function(data){
							if (data.seq != opt.element.data.autoCompleteSeq) return; //react only to last request's response
							opt.element.removeClass('waiting');
							if (data.matches.length < 1) {
								opt.element.parent().find('div.autoComplete .item').remove();
								opt.element.parent().find('div.autoComplete').hide();
							}
							var aCoptions = opt.element.parent().find('div.autoComplete');
							
							if (aCoptions.length == 0) {
								opt.element.after('<div class="autoComplete"></div>');
								aCoptions = opt.element.parent().find('div.autoComplete');
								
								if (opt.placement == 'bottom') {
									aCoptions.css({
										position: 'absolute',
										zIndex: 99,
										top: opt.element.outerHeight(),
										width: opt.element.width(),
										left: 0
									});
								}
								else if (opt.placement == 'top') {
									aCoptions.css({
										position: 'absolute',
										zIndex: 99,
										bottom: opt.element.offsetParent().outerHeight(),
										width: opt.element.width(),
										left: 0
									});
								}
								
								opt.element.keydown(function(ev){
									var aCoptions = $(this).parent().find('div.autoComplete'); //change of scope!
									var options = aCoptions.find('div.item');
									
									if (ev.keyCode == 40) {
										aCoptions.show();
										if (aCoptions.data.selectedItem < options.length) {
											aCoptions.data.selectedItem++;
											options.removeClass('selected');
											$(options[aCoptions.data.selectedItem-1]).addClass('selected');
										}
									}//down
									else if (ev.keyCode == 38) {
										aCoptions.show();
										if (aCoptions.data.selectedItem > 1) {
											aCoptions.data.selectedItem--;
											options.removeClass('selected');
											$(options[aCoptions.data.selectedItem-1]).addClass('selected');
										}
									}//up
									else if (ev.keyCode == 13) {
										if (!($(this).parent().find('div.autoComplete').is(':visible'))) {
											$(this).closest('form').submit();
											return false;
										}
										
										if (options.length == 0) {
											return true;
											//ev.StopPropagation();
											//return false;
										}
										
										if (aCoptions.data.selectedItem > 0) {
											var activeOpt = $(options[aCoptions.data.selectedItem-1]);
											$(this).val(activeOpt.data('value'));
											aCoptions.hide();
											ev.stopPropagation();
											if (opt.element.data('autoCompleteCallback')) setTimeout(function(){
												var callback = opt.element.data('autoCompleteCallback');
												callback(activeOpt.data('value'))
											});
											return false;
										}
									}//enter
									else if (ev.keyCode == 27) {
										aCoptions.hide();
										ev.stopPropagation();
										return false;
									}
								});//add handler only if newly created container
							}
							else {
								aCoptions.find('.item').remove();
							}
							
							aCoptions.show();
							aCoptions.data.selectedItem = 0;
							var val = data.search_val; //opt.element.val();
							
							for (var item in data.matches) {
								var label = data.matches[item].label.replace(new RegExp(val , "gi"), function(str){ return '<strong>' + str + '</strong>'; });
								aCoptions.append($('<div class="item">' + label + '</div>').data('value', data.matches[item].value));
							}
							if (data.matches.length > 0) {
								//aCoptions.find('.item:first').addClass('selected');
								aCoptions.data.selectedItem = 0;
							}
							else {
								aCoptions.hide();
							}
							
							aCoptions.find('div.item')
								.css('cursor', 'pointer')
								.hover(
									function(){
										aCoptions.find('div.item').removeClass('selected');
										$(this).addClass('selected');
										aCoptions.data.selectedItem = $(this).prevAll().length + 1;
									},
									function(){
										$(this).removeClass('selected');
										aCoptions.find('div.item:first').addClass('selected');
										aCoptions.data.selectedItem = 1;
									}
								)
								.click(function(ev){
									var options = $(this).closest('div.autoComplete').find('div.item');
									var activeOpt = $(options[aCoptions.data.selectedItem-1]);
									opt.element.val(activeOpt.data('value'));
									aCoptions.hide();
									if (opt.element.data('autoCompleteCallback')) setTimeout(function(){
										var callback = opt.element.data('autoCompleteCallback');
										callback(activeOpt.data('value'))
									});
								})
							;
						}//success handler
					);//getJSON
				},
				opt.delay
			);
		});
	},
	
	currencyRound: function(value) {
		return Math.round(value * 100.0) / 100.0;
	},
	
	expandableMenu: {
		init: function(){
			$(".ExpandableMenu").each(function(){
			$(this).find("ul").hide().css({width: $(this).width()});
			$(this).hover(
				function(){$(this).css({cursor: 'pointer'});},
				function(){$(this).css({cursor: 'default'});}
			);
			$(this).find("li").hover(
				function(){$(this).addClass('hover');},
				function(){$(this).removeClass('hover');}
			);
			$(this).find(".MenuLabel").click(function(){
				$(this).parent().find("ul").toggle();
				if ($(this).is(':visible')) {
					$("body").click(jQutils.expandableMenu.clickOutsideHandler);
					return false;
				}
			});//onClick
			$(this).find("li").click(function(e){
				if ($(this).find("a").length == 1) {
					e.preventDefault();
					window.location = $(this).find("a").attr("href");
				}
			});
		});
		},
		clickOutsideHandler: function(){
			$(".ExpandableMenu").find("ul").hide();
			$("body").unbind('click', jQutils.expandableMenu.clickOutsideHandler);
		}
	},//expandableMenu
	
	dependentSelect: function(s1, map, s2) {
		s1.change(function(){
			if (typeof map[s1.val()] != "undefined") {
				s2.val(map[s1.val()]);
			}
			else {
				//try empty/zero options
				s2.val('0');
				s2.val('');
			}
		});
		s1.keypress(function(){
			$(this).change();
		});
	},//dependentSelect
	
	extractId: function(str){
		var id = str.split(' ');
		if (id.length < 1) return false;
		id = id[0].split(':');
		if (id.length < 2 || id[0].toLowerCase() != 'id') return false;
		id = id[1];
		return id;
	},
	
	popup: function(title, addr, width) {
		try {
			return window.open(addr, title, 'width=' + width + ',height=750,scrollbars=1');
		}
		catch (e) {
			try {
				var win = window.open(addr);
				win.document.title(title);
				return win;
			}
			catch (e) {return null;}
		}
	},//popup
	
	showDetails: {
		hide: function() {
			$("#DetailsArea").remove();
		},
		init: function() {
			$("img.showDetails").hover(
				function(){$(this).css({cursor: 'pointer'});},
				function(){$(this).css({cursor: 'normal'});}
			);
		},
		post: function(title, url, boxWidth, data){
			if ($("#DetailsArea").length) $("#DetailsArea").remove();
			var boxHtml = '<div id="DetailsArea"><div id="DetailsBox"><div class="Details_Title">' + title + '<span><a href="javascript:void(null)" onclick="$(\'#DetailsArea\').change();$(\'#DetailsArea\').remove();">Zamknij</a></span></div><div id="response">Wczytywanie</div></div></div>';
			$("body").append(boxHtml);
			
			$("#DetailsArea").css({
				visibility: 'visible'
			}).css({
				left: ($('body').width() - $("#DetailsArea").width())/2
			});
			
			$("#DetailsBox").css({width: boxWidth});
			$("#DetailsArea #response").load(url, data, jQutils.showDetails.scrollAdjust);
			$(document).keypress(function(ev){
				if (ev.keyCode == 27) {
					$("#DetailsArea").change();
					$("#DetailsArea").remove();
				}
			});
		},
		scrollAdjust: function() {
			if (!$("#DetailsArea").length) return;
			var winH = $(window).height();
			var boxH = $("#DetailsBox").height() + parseInt($("#DetailsBox").css('margin-top').replace('px', ''), 10) + 20;
			if (boxH > winH) {
				$("#DetailsArea").css({position: 'absolute', height: $("body").height() + 70});
			}
			else {
				var DetAr = $("#DetailsArea");
				if (DetAr.css('position') == 'absolute') DetAr.css('position', 'fixed');
			}
		},
		show: function(title, url, boxWidth){
			if ($("#DetailsArea").length) $("#DetailsArea").remove();
			var boxHtml = '<div id="DetailsArea"><div id="DetailsBox"><div class="Details_Title"><span><a href="javascript:void(null)" onclick="$(\'#DetailsArea\').change();$(\'#DetailsArea\').remove();">Zamknij</a></span>' + title + '</div><div id="response">Wczytywanie</div></div></div>';
			$("body").append(boxHtml);
			
			$("#DetailsArea").css({
				visibility: 'visible'
			}).css({
				left: ($('body').width() - $("#DetailsArea").width())/2
			});
			
			$("#DetailsBox").css({width: boxWidth});
			$("#DetailsArea #response").load(url, null, jQutils.showDetails.scrollAdjust);
			
			$(document).keypress(function(ev){
				if (ev.keyCode == 27) {
					$("#DetailsArea").change();
					$("#DetailsArea").remove();
				}
			});
		},
		showHtml: function(title, html, boxWidth) {
			if ($("#DetailsArea").length) $("#DetailsArea").remove();
			var boxHtml = '<div id="DetailsArea"><div id="DetailsBox"><div class="Details_Title"><span><a href="javascript:void(null)" onclick="$(\'#DetailsArea\').change();$(\'#DetailsArea\').remove();">Zamknij</a></span>' + title + '</div><div id="response">Wczytywanie</div></div></div>';
			$("body").append(boxHtml);
			
			$("#DetailsArea").css({
				visibility: 'visible'
			}).css({
				left: ($('body').width() - $("#DetailsArea").width())/2
			});
			
			$("#DetailsBox").css({width: boxWidth});
			$("#DetailsArea #response").html(html);
			jQutils.showDetails.scrollAdjust();
			
			$(document).keypress(function(ev){
				if (ev.keyCode == 27) {
					$("#DetailsArea").change();
					$("#DetailsArea").remove();
				}
			});
		}
	},//showDetails
	
	toString: function(){
		return "[object jQutils]";
	}//toString
	
}//jQutils class

$(document).ready(function(){
	jQutils.showDetails.init();
	$(window).resize(jQutils.showDetails.scrollAdjust);
	
	jQutils.expandableMenu.init();
	
	//$(".datepicker").datepicker($.datepicker.regional['pl']);
	
	//console.log('ok');
});
