(function($) {
	
	function hash2array(hash) {
		var result = [];
		$.each(hash, function(key, value) {
			result.push({
				key: key,
				value: value
			})
		});
		return result;
	}
	
	function usort(inputArr, sorter) {
	    // http://kevin.vanzonneveld.net
	    // +   original by: Brett Zamir (http://brett-zamir.me)
	    // +   improved by: Brett Zamir (http://brett-zamir.me)
	    // %        note 1: This function deviates from PHP in returning a copy of the array instead
	    // %        note 1: of acting by reference and returning true; this was necessary because
	    // %        note 1: IE does not allow deleting and re-adding of properties without caching
	    // %        note 1: of property position; you can set the ini of "phpjs.strictForIn" to true to
	    // %        note 1: get the PHP behavior, but use this only if you are in an environment
	    // %        note 1: such as Firefox extensions where for-in iteration order is fixed and true
	    // %        note 1: property deletion is supported. Note that we intend to implement the PHP
	    // %        note 1: behavior by default if IE ever does allow it; only gives shallow copy since
	    // %        note 1: is by reference in PHP anyways
	    // *     example 1: stuff = {d: '3', a: '1', b: '11', c: '4'};
	    // *     example 1: stuff = usort(stuff, function (a, b) {return(a-b);});
	    // *     results 1: stuff = {0: '1', 1: '3', 2: '4', 3: '11'};
	    var valArr = [],
	        k = '',
	        i = 0,
	        strictForIn = false,
	        populateArr = {};

	    if (typeof sorter === 'string') {
	        sorter = this[sorter];
	    } else if (Object.prototype.toString.call(sorter) === '[object Array]') {
	        sorter = this[sorter[0]][sorter[1]];
	    }

	    // BEGIN REDUNDANT
	    this.php_js = this.php_js || {};
	    this.php_js.ini = this.php_js.ini || {};
	    // END REDUNDANT
	    strictForIn = this.php_js.ini['phpjs.strictForIn'] && this.php_js.ini['phpjs.strictForIn'].local_value && this.php_js.ini['phpjs.strictForIn'].local_value !== 'off';
	    populateArr = strictForIn ? inputArr : populateArr;


	    for (k in inputArr) { // Get key and value arrays
	        if (inputArr.hasOwnProperty(k)) {
	            valArr.push(inputArr[k]);
	            if (strictForIn) {
	                delete inputArr[k];
	            }
	        }
	    }
	    try {
	        valArr.sort(sorter);
	    } catch (e) {
	        return false;
	    }
	    for (i = 0; i < valArr.length; i++) { // Repopulate the old array
	        populateArr[i] = valArr[i];
	    }

	    return strictForIn || populateArr;
	}
	
	function numericDeclension(n, nominative, genitive, plurallyGenitive)
	{
	    mod10 = n %10;
	    mod100 = n % 100;
	    if ( (mod100 >= 5) && (mod100 <= 20) )
	        return plurallyGenitive;

	    if ( (mod10 >= 5) && (mod10 <= 9) || (mod10 == 0) )
	        return plurallyGenitive;

	    if ( (mod10 >= 2) && (mod10 <= 4) )
	        return genitive;

	    return nominative;
	}
	
	
	$.thermomirFilter = function(options) {
		
		var lastChangeTime = (new Date()).getTime();
		var delay = 1000;
		var counter = 0;
		var jqxhr = null;
		var showButton = $('<div class="show-button">Показать все модели</div>');
		var resetButton = $('<div class="reset-button">Сбросить</div>');
		var closeButton = $('<div class="close-button">свернуть</div>');
		var queue = null;
		var form = null;
		var leftColumn;
		var rightColumn;
		var splash;
		var cid = parseInt(options.id);
		
		function sliceUrl() {
			if (form) {
				return '/slice.plx?' + form.serialize();
			} else {
				return '/slice.plx';
			}
		}
		
		showButton.click(function() {
			window.location = sliceUrl();
		});
		
		function isInRightColumn(context) 
		{
			return context.parents().index(rightColumn) != -1;
		}
		
		function showSplash(context, count, url)
		{
			if (splash) {
				$(splash).remove();
				splash = null
			}
			
			var div = $('<div class="filter-splash" />').text(
				'Выбрано '+count+' '+numericDeclension(count, 'модель', 'модели', 'моделей')+' '
			);
			isRight = isInRightColumn(context);
			div
				.addClass(isRight ? 'filter-splash-right' : 'filter-splash-left')
				.append($('<a>Показать</a>').attr('href', url));
			
			var offset = $(context).offset();
			
			if (isRight) {
				div.css({
					position: 'absolute',
					left: offset.left + 310,
					top: offset.top - 15,
					zIndex: 10000
				});
			} else {
				div.css({
					position: 'absolute',
					right: $(window).width() - offset.left + 1,
					top: offset.top - 15,
					zIndex: 10000
				});
			}
			
			$(document.body).prepend(div);
			splash = div;
			setTimeout(function() {
				div.fadeOut(function() {
					$(this).remove();
				});
			}, 3000);
		}
		
		function change(context) {
			if (jqxhr) {
				jqxhr.abort();
				jqxhr = null;
			}
			
			var now = (new Date()).getTime();
			if (lastChangeTime + delay < now) {
				lastChangeTime = now;
				
				var jqxhr = $.ajax({
					success: function(data, textStatus, jqXHR) {
						showButton.text('Показать '+data.matchedItems+' '+numericDeclension(data.matchedItems, 'модель', 'модели', 'моделей') );
						if (context) {
							showSplash(context, data.matchedItems, sliceUrl());
						}
					},
					data: {},
					dataType: 'json',
					url: '/filter.plx?' + form.serialize() + '&count=1',
					context: context
				});
				
			} else {
				if (queue) {
					clearTimeout(queue);
					queue = null;
				}
				queue = setTimeout(function() {
					change(context);
				}, delay);
			}
		}
		
		function renderList(cnt, id, options, listType) {
			var arr = hash2array(options);
			var sorted = usort(arr, function (a, b) {
				return a.value > b.value;
			});
			
			if (listType == 1) {
				var select = $('<select><option value="">--</option></select>').attr({
					name: id
				}).change(function() {
					change(cnt);
				});
				
				$.each(sorted, function(i, item) {
					select.append(
						$('<option />', {
							value: item.key,
							text: item.value
						})
					);
				});
				
				cnt.append(select);
				
			} else {

				$.each(sorted, function(i, item) {
					cnt.append(
						$('<label />').html(' ' + item.value).prepend(
							$('<input type="checkbox" class="checkbox" />')
								.val(1)
								.attr('name', id+'v'+item.key)
								.change(function() {
									change(cnt);
								})
						)
					).append(' ');
				});
				
			}
		}
		
		function render(content) {
			var container = $('<form action="" method="get" />');
			form = container;
			
			form.append($('<input type="hidden" name="id" />').val(cid));
			
			content = $(content);
			
			$.ajax({
				url: '/filter.plx',
				data: {id: cid},
				success: function(json, textStatus) {
					
					$(content).dialog('option', "height", 'auto');
					
					content.empty().append(container);
					
					container 
						.append(closeButton)
						.append($('<h1 />').text(json.title));
					
					var table = $('<table cellspacing="0" cellpadding="0"><tr><td class="column"></td><td class="delimiter"><div></div></td><td class="column"></td></tr></table>');
					leftColumn = table.find('td').eq(0);
					rightColumn = table.find('td').eq(2);
					
					var leftDec = 0;
					if (json.image && json.image.src) {
						leftColumn.append($('<img alt="" class="catalogue" />').attr(json.image));
						leftDec = 4;
					}
					
					container.append(table);
					
					var leftList = $('<dl />');
					var rightList = $('<dl />');
					
					var filtersCount = json.attrs.length;
					if (json.brands) {
						filtersCount += 1;
					}
					
					var leftColumnCount = (filtersCount-leftDec)/2;
					if (json.brands) {
						var dd = $('<dd />');
						var dt = $('<dt />').text('Производитель');
						
						renderList(dd, 'brand', json.brands, 0);
						
						var currentList = (0 >= leftColumnCount) ? rightList : leftList;
						currentList.append(dt).append(dd);
					}
					
					$.map(json.attrs, function(attr, i) {
						
						var dd = $('<dd />');
						var dt = $('<dt />').text(attr.name);
						if (attr.unit) {
							dt.append($('<span class="unit"></span>').text(' ('+attr.unit+')'));
						}
						
						switch(attr.type) {
							case 0: // int
							case 1: // float
								var from = $('<input type="text" class="text" size="2" />').attr('name', 'a'+attr.id+'f');// .val(attr.min)
								var to = $('<input type="text" class="text" size="2" />').attr('name', 'a'+attr.id+'t'); // .val(attr.max)
								var indicator = $('<div class="indicator" />')
									.append($('<label>от</label>').append(from))
									.append($('<label>до</label>').append(to));
								dt.prepend(indicator);
								
								var slider = $('<div class="slider" />').slider({
									range: true,
									min: attr.min,
									max: attr.max,
									values: [ attr.min, attr.max ],
									slide: function( event, ui ) {
										from.val(ui.values[0]);
										to.val(ui.values[1]);
										change(dd);
									}
								}); 
								
								from.change(function() {
									var val = $(this).val();
									if (val.length) {
										slider.slider("values" , 0, val);
									} else {
										slider.slider("values" , 0, attr.min);
									}
									change(dd);
								});
								to.change(function() {
									var val = $(this).val();
									if (val.length) {
										slider.slider("values" , 1, val);
									} else {
										slider.slider("values" , 1, attr.max);
									}
									change(dd);
								});
								
								attr.slider = slider;
								
								dd.append(slider);
								break;
								
							case 3: // list
								renderList(dd, 'a'+attr.id, attr.options, attr.listType);
								break;
								
							case 5: // checkbox
							case 6: // checkbox
								renderList(dd, 'a'+attr.id, {
									0: 'нет',
									1: 'да'
								}, 1);
								break;
						}
						
						
						var currentList = (i+1 >= leftColumnCount) ? rightList : leftList;
						currentList.append(dt).append(dd);
						
					});
					
					leftColumn.append(leftList);
					rightColumn.append(rightList);
					
					resetButton.unbind('click').click(function() {
						$.map(json.attrs, function(attr, i) {
							
							switch(attr.type) {
								case 0: // int
								case 1: // float
									$('input[name=a'+attr.id+'f]', form).val('');
									$('input[name=a'+attr.id+'t]', form).val('');
									attr.slider.slider("values" , 0, attr.min);
									attr.slider.slider("values" , 1, attr.max);
									break;
							}
							
							$(':checkbox', form).removeAttr('checked');
							
							showButton.text('Показать все модели');
						});
					});
					
					container.append(showButton);
					container.append(resetButton);
				}, 
				dataType: 'json'
			});
		}
		
		var width = 652;
		var height = 'auto';
		var minHeight = 300;
		if ($.browser.msie && ($.browser.version == '6.0')) {
			width = 682;
			height = 600;
			minHeight = 600;
		}
		
		function start() {
			$('<div id="filter-content">Загрузка...</div>').dialog({
				width: width,
				height: height,
				minHeight: minHeight,
				modal: true,
				resizable: false,
				title: false,
				dialogClass: 'no-title',
				position: ['center',50],
				open: function(event, ui) {
					var self = this;
					closeButton.unbind('click').click(function() {
						$(self).dialog("close");
					});
					render(this);
				},
				close: function(event, ui) {
					$(this).remove();
				}
			});
		}
		
		if (options.button) {
			$(options.button).click(function() {
				start();
				return false;
			});
		}
		
		if (options.autostart) {
			start();
		}
		
		/*$(options.button).colorbox({
			html: ,
			innerWidth: '660px',
			height: '600px',
			top: '10%',
			onComplete: function(a) {
				
				
				
			}
		});*/ 

	}
	
})(jQuery);
