window.uui = (function() {
	"use strict";
	
	// Named dialogs
	var dialogs = {};
	
	// Named tabs
	var namedTabs = {};
	
	//  Named selectors
	var namedSelectors = {};
	
	var bg = null;
	
	return {
		
		button: function(title, action) {
			var b = $('<button class="dialog-button"/>').click(action);
			return b;
		},
		
		
		dialog: function(options) {
			
			if (options.name != '' && typeof(dialogs[options.name]) != 'undefined')
				return dialogs[options.name];
			
			return (function() {
				
				var defaults = {
					width: '300px',
					title: 'Untitled dialog',
					name: '',
					content: '',
					buttons: [
						{title: 'Закрыть', action: function() {closeDialog();}}
					]
				};
				
				$.extend(defaults, options);
				
				var bg = $('<div class="dialog_bg"></div>');
				var d = $('<div class="dialog"><div class="dialog_header"><div class="dialog_x"></div><div class="dialog_title"></div></div><div class="dialog_content"></div><div class="dialog_buttons"></div></div>');
				d.css('width', defaults.width);
				$('body').append(bg).append(d);
				$('div.dialog_x', d).click(function() {closeDialog()});
				$('div.dialog_title', d).text(defaults.title);
				$('div.dialog_content', d).html(defaults.content);
				$(window).resize(function() {location()});
				bg.click(function() {closeDialog()});
				
				var bDiv = $('div.dialog_buttons', d);
				for (var i = defaults.buttons.length - 1; i >= 0; i--) {
					var b = $('<button>' + defaults.buttons[i].title + '</buttons>');
					if (defaults.buttons[i].action == 'close')
						b.click(function() {closeDialog()});
					else
						b.click(defaults.buttons[i].action);
					bDiv.append(b);
				}


				function location() {
					var left = Math.round(($(window).width() - d.width()) / 2);
					var top = Math.round(($(window).height() - d.height()) * 0.33);
					if (top < 0)
						top = 0;
					
					bg.css('width', '0').css('height', 0);
					d.css('left', String(left) + 'px').css('top', String(top) + 'px');
					bg.css('width', String($(document).width()) + 'px').css('height', String($(document).height()) + 'px');
				}


				function closeDialog() {
					d.hide();
					bg.fadeOut(200);
					if (defaults.name == '') {
						d.remove();
						bg.remove();
					}
				}

				var newDialog = {
					
					open: function() {
						location();
						bg.fadeTo(200, 0.2);
						d.show();
					},
					
					close: function() {
						closeDialog();
					}
				};
				
				if (defaults.name != '')
					dialogs[defaults.name] = newDialog;
			
				return newDialog;
				
			}());
				
		},
		
		getDialog: function(name) {
			return typeof(dialogs[name]) == 'undefined' ? null : dialogs[name];
		},
	
	
		regionSlider: function(options) {
			return (function() {
				
				function moveBulb(e) {
					if (isLeftMoving !== false) {
						
						var left = leftPosition + e.pageX - isLeftMoving;
						if (left < 0)
							left = 0;
						if (left > rightPosition)
							left = rightPosition;

						currentLeftPosition = left;
						lBulb.css('left', String(left) + 'px');
						updateLeftValue();
					}
					else if (isRightMoving !== false) {
						
						var right = rightPosition + e.pageX - isRightMoving;
						if (right < leftPosition)
							right = leftPosition;
						if (right > maxLeftPosition)
							right = maxLeftPosition;
						
						currentRightPosition = right;
						rBulb.css('left', String(right) + 'px');
						updateRightValue();
					}
				}
				
				
				function startLeftMoving(e) {
					isLeftMoving = e.pageX;
					currentLeftPosition = leftPosition;
				}
				
				function startRightMoving(e) {
					isRightMoving = e.pageX;
					currentRightPosition = rightPosition;
				}
				
				
				function stopMoving() {
					if (isLeftMoving !== false) {
						isLeftMoving = false;
						leftPosition = currentLeftPosition;
						defaults.callback(getMinValue(), getMaxValue());
					}
					else if (isRightMoving !== false) {
						isRightMoving = false;
						rightPosition = currentRightPosition;
						defaults.callback(getMinValue(), getMaxValue());
					}
				}
				
				function getMinValue() {
					var min = currentLeftPosition;
					min = (Math.log(defaults.max) - Math.log(defaults.min)) * min / (slideBarWidth - bulbWidth) + Math.log(defaults.min);
					return Math.exp(min);
				}
				
				function getMaxValue() {
					var max = (Math.log(defaults.max) - Math.log(defaults.min)) * (currentRightPosition + bulbWidth) / (slideBarWidth - bulbWidth) + Math.log(defaults.min);
					return Math.exp(max);
				}
				
				function updateLeftValue() {
					$('div', lBulb).text(Math.round(getMinValue()));
				}
				
				function updateRightValue() {
					$('div', rBulb).text(Math.round(getMaxValue()));
				}
				
				var isLeftMoving = false;
				var leftPosition = 0;
				var currentLeftPosition = 0;
				var isRightMoving = false;
				var rightPosition = 0;
				var currentRightPosition = 0;
				
				var defaults = {
					callback:  function(min, max) {},
					min: 0,
					max: 10
				};
				
				$.extend(defaults, options);

				if (typeof(defaults.id) == 'undefined' || defaults.id == '')
					return null;
				var slideBar = $('#' + defaults.id);
				if (slideBar.length == 0)
					return null;
				var slideBarWidth = slideBar.width();
				rightPosition = slideBarWidth;
				
				var lBulb = $('<div class="slider-left-bulb" ondragstart="return false;" unselectable="on"><div unselectable="on"></div></div>');
				lBulb.mousedown( function(e) {startLeftMoving(e)});
				var rBulb = $('<div class="slider-right-bulb" ondragstart="return false" unselectable="on"><div unselectable="on"></div></div>');
				rBulb.mousedown( function(e) {startRightMoving(e)});
				$(document).mouseup( function() {stopMoving();} );
				$(document).mousemove( function(e) {moveBulb(e);} );
				slideBar.append(lBulb).append(rBulb);
				
				var bulbWidth = lBulb.width();
				
				var maxLeftPosition = slideBarWidth - 2*bulbWidth;
				currentRightPosition = rightPosition = maxLeftPosition;
				rBulb.css('left', String(rightPosition) + 'px');
				
				
				
				updateLeftValue();
				updateRightValue();
				
				return {
					
					getValues: function() {
						var minV = getMinValue();
						var maxV = getMaxValue();
						return {min: minV, max: maxV};
					},
					
					setValues: function(min, max) {
						defaults.min = min;
						defaults.max = max;
						updateLeftValue();
						updateRightValue();
					}
				};
				
			}());
		},
		
		tabs: function(options) {
			return (function() {
				
				
				function setCurrent(num, noexec) {
					
					currentTabNum = num;
					for (var i in tabs) {
						if (i == num) {
							tabs[i].tab.addClass('current');
							tabs[i].body.show();
						}
						else {
							tabs[i].tab.removeClass('current');
							tabs[i].body.hide();
						}
					}
					
					if (opts.callback != null)
						opts.callback(tabs[num].value);
				}
				
				// Variables
				var opts = $.extend({
					id: '',
					name: '',
					callback: null
				}, options);
				
				var currentTabNum = 0;
				var tabs = new Array();
				var rootElement = null;
				var tabsContainer = null;
				
				// Go
				if (opts.name != '' && typeof(namedTabs[opts.name]) != 'undefined')
					return namedTabs[opts.name];
				
				if (opts.id == '' || $('#' + opts.id).length == 0)
					return null;
				
				rootElement = $('#'+ opts.id);
				tabsContainer = $('<div class="tabs-container"></div>');
				rootElement.append(tabsContainer);
				
				// Return object
				var tabsObject = {
					
					getValue: function() {
						return tabs[currentTabNum].value;
					},
					addTab: function(tabEl, bodyEl, options) {
						
						var o = $.extend({current: false, value: null}, options);
						
						var tabNum = tabs.length;
						tabEl.click(function(){setCurrent(tabNum);});
						tabs.push({tab: tabEl, body: bodyEl, value: o.value, tabNum: tabNum});
						
						tabsContainer.append(tabEl);
						rootElement.append(bodyEl);
						
						if (o.current)
							setCurrent(tabNum);
						else
							bodyEl.hide();
					}
				};
				
				if (opts.name != '')
					namedTabs[opts.name] = tabsObject;
				
				return tabsObject;
			}());
		},
		
		getTabs: function(name) {
			if (typeof(namedTabs[name]) != 'undefined')
				return namedTabs[name];
			else
				return null;
		},
	
		getTabsValue: function(name) {
			if (typeof(namedTabs[name]) != 'undefined')
				return namedTabs[name].getValue();
			else
				return null;
		},
		
		selector: function(options) {
			return (function() {
				
				function change(num) {

					if (opts.multiple) {
						if (values[num].checked)
							uncheck(num);
						else
							check(num);
						
						if (opts.callback != null)
							opts.callback(getValue());
					}
					else if (!values[num].checked) {
						
						for (var i in values) {
							if (i == num)
								check(i);
							else
								uncheck(i);
						}
						
						if (opts.callback != null)
							opts.callback(getValue());
					}
					
				}
			
			
				function check(num) {
					if (values[num].checked)
						return;
					
					values[num].el.addClass('checked');
					values[num].checked = true;
				}
			
			
				function uncheck(num) {
					if (values[num].checked === false)
						return;
					
					if (opts.multiple && !opts.empty) {
						var another = false;
						for (var i in values) {
							if (i != num && values[i].checked) {
								another = true;
								break;
							}
						}
						if (!another)
							return;
					}
					
					values[num].el.removeClass('checked');
					values[num].checked = false;
				}
				
				
				function getValue() {
					
					if (opts.multiple) {
						var v = opts.map ? 0 : new Array();
						for (var i in values) {
							if (!values[i].checked)
								continue;
							
							if (opts.map)
								v |= values[i].value;
							else
								v.push(values[i].value);
						}
						
						return v;
					}
					
					for (var i in values) {
						if (values[i].checked)
							return values[i].value;
					}
				}
				
				
				// Variables
				var opts = $.extend({
					id: '',
					name: '',
					callback: null,
					multiple: false,
					map: false,
					empty: false
				}, options);
				
				var values = new Array();
				var rootElement = null;
				
				// Go
				if (opts.name != '' && typeof(namedSelectors[opts.name]) != 'undefined')
					return namedSelectors[opts.name];
				
				if (opts.id == '' || $('#' + opts.id).length == 0)
					return null;
				
				rootElement = $('#'+ opts.id);
				rootElement.addClass('options-container');
				
				
				// Return object
				var selObject = {
					
					getValue: function() {
						return getValue();
					},
					addOption: function(el, options) {
						
						var o = $.extend({checked: false, value: null}, options);
						
						var vNum = values.length;
						el.click(function(){change(vNum);});
						values.push({el: el, value: o.value, num: vNum});
						
						rootElement.append(el);
												
						if (o.checked)
							check(vNum);
						else
							uncheck(vNum);
					},
					removeOptions: function() {
						values = new Array();
						rootElement.html('');
					},
					setChecked: function(value) {
						for (var i in values) {
							if (values[i].value == value) {
								if (values[i].checked)
									return;
								
								check(i);
								if (opts.callback != null)
									opts.callback(getValue());
								
								return;
							}
						}
					}
				};
				
				if (opts.name != '')
					namedSelectors[opts.name] = selObject;
				
				return selObject;
			}());
		},
	
		getSelector: function(name) {
			if (typeof(namedSelectors[name]) != 'undefined')
				return namedSelectors[name];
			else
				return null;
		},
	
		getSelectorValue: function(name) {
			if (typeof(namedSelectors[name]) == 'undefined')
				return namedSelectors[name].getValue();
			else
				return null;
		}
	}
	
}());

