if (Object.isUndefined(Puzzle)) { var Puzzle = { } };
if (Object.isUndefined(Puzzle.Controls)) { Puzzle.Controls = { } };

function hideFlash() {
	if ($('flashMessage')) {
		Effect.Fade('flashMessage');
	}
	if ($('errorMessage')) {
		Effect.Fade('errorMessage');
	}
}
document.observe('click', function() {
	hideFlash();
});


document.observe('dom:loaded', function() {
	
	$$(".error-message").each(function(el) {
		$(el).up(".item").addClassName("error");
	});
	
	if ($("errorMessage")) {
		Effect.Pulsate($("errorMessage"), { pulses: 3, duration: 1.2 });
	}
	
	// setTimeout('hideFlash()', 5000);
});


/**
 * Flash-message
 */

Puzzle.Controls.Flash = Class.create({
	initialize: function(message) {
		this.message = $('flashMessage') || null;
		
		if (!this.message) {
			this.message = new Element('div', { 'id': 'flashMessage', 'class': 'message' } );
			$(document.body).insert(this.message);
		}
		
		this.message.update(message);
		Effect.Appear(this.message);
		
		// setTimeout('hideFlash()', 5000);
	}
});

/**
 * Функции для определения размеров экрана/документа
 */
function getBodyScrollLeft() {
	  return self.pageXOffset || (document.documentElement && document.documentElement.scrollLeft) || (document.body && document.body.scrollLeft);
	}
function getBodyScrollTop() {
  return self.pageYOffset || (document.documentElement && document.documentElement.scrollTop) || (document.body && document.body.scrollTop);
}
function getClientCenterX() {
    return parseInt(getClientWidth()/2)+getBodyScrollLeft();
}
function getClientCenterY() {
    return parseInt(getClientHeight()/2)+getBodyScrollTop();
}
function getClientWidth() {
  return document.compatMode=='CSS1Compat' && !window.opera?document.documentElement.clientWidth:document.body.clientWidth;
}
function getClientHeight() {
  return document.compatMode=='CSS1Compat' && !window.opera?document.documentElement.clientHeight:document.body.clientHeight;
}
function getDocumentWidth() {
    return (document.body.scrollWidth > document.body.offsetWidth)?document.body.scrollWidth:document.body.offsetWidth;
}
function getDocumentHeight() {
    return (document.body.scrollHeight > document.body.offsetHeight)?document.body.scrollHeight:document.body.offsetHeight;
}

/**
 * Кастомизированный селект
 */
Puzzle.Controls.Select = Class.create({
	
	initialize: function(select) {
		var e = Prototype.emptyFunction;
		this.config = Object.extend({
			afterCreate: e,
			beforeDropDown: e,
			afterSelect: e,
			label: 'Select',
			classNames: {
				selector: 'PuzzleSelector',
				dropdown: 'PuzzleSelect',
				arrow: 'arrow',
				closer: 'closer',
				selected: 'selected'
			}
		}, arguments[1] || { });
		
	    this.select = $(select);
		this.active = false;
		
		this.build();
		this.initMouseEvents();
		this.config.afterCreate.call(this);
	},
	
	build: function() {
		
		if (this.select.up().hasClassName('__PuzzleSelect')) {
			this.wrapper = this.select.up();
			this.selector = this.select.next('label'); 
		} else {		
			this.wrapper = this.select.wrap(new Element('div', { 'class': '__PuzzleSelect' }));
			this.selector = new Element('label', { 'class': this.config.classNames.selector }).update(new Element('span').update(this.config.label));
			//this.arrow = new Element('span', { 'class': 'icon i-arrow-down ' + this.config.classNames.arrow });
			//this.selector.insert(this.arrow);
			this.wrapper.insert(this.selector);		
		}
		
		this.dropdown = new Element('div', { 'class': this.config.classNames.dropdown, 'style': 'display: none;' });
		this.closer = new Element('div', { 'class': 'icon i-close ' + this.config.classNames.closer, 'title': 'Закрыть' });
		this.list = new Element('ul');
		this.list.insert(this.closer);
		
		$A(this.select.options).each(function(option, i) {
			var item = new Element('li').update(option.text);
			//item.writeAttribute('value', i);
			this.list.insert(item);
		}.bind(this));
		
		this.dropdown.insert(this.list);
		
		document.body.appendChild(this.dropdown);
		
		this.select.hide();
		
		this.set(this.select.selectedIndex);
		
 		//new Puzzle.Effects.Shadow(this.dropdown);
 	},
	
	initMouseEvents: function() {
		this.select.observe('change', this.onSelectChanged.bind(this));
		this.select.observe('PuzzleSelect:change', this.onSelectChanged.bind(this));
		this.selector.observe('click', this.onDropDown.bind(this));
		Event.observe(document, 'click', this.onDocumentClick.bind(this));
		new Puzzle.Controls.RadioList(this.list, { onChange: this.onSelect.bind(this) });
		
		if (this.closer) {
			this.closer.observe('click', this.hide.bind(this));
		}
	},
	
	onDocumentClick: function(event) {
		if (!this.active || Event.element(event).up('.__PuzzleSelect') == this.select.up()) return;
		this.hide();
	},
	
	onDropDown: function() {
		this.config.beforeDropDown.call(this);
		(this.active) ? this.hide() : this.show();
	},
	
	onSelect: function(selected) {
		this.list.select('li').each(function(option, i) {
			if (option == selected) {
				this.set(i);
				this.config.afterSelect.call(this);
			}
		}.bind(this));	
	},
	
	onSelectChanged: function() {
		this.set(this.select.selectedIndex);
		this.config.afterSelect.call(this);
	},
	
	show: function() {
		this.move();
		this.active = true;
		this.dropdown.appear({ duration: 0.2 });
	},
	
	hide: function() {
		this.active = false;
		this.dropdown.fade({ duration: 0.2 });
	},
	
	move: function() {
		position = this.wrapper.cumulativeOffset();
		this.dropdown.setStyle({
			'left': position.left + 'px',
			'top': position.top + 'px'
		});
	},
	
	set: function(index) {
		this.selector.down('span').update(this.select.options[index].text);
		this.select.selectedIndex = index;
		// TODO переложить переключение классов на Puzzle.Controls.RadioList
		this.list.select('li').invoke('removeClassName', this.config.classNames.selected);
		this.list.down('li', index).addClassName(this.config.classNames.selected)
		this.hide();
	},

	setValue: function(value) {
		$A(this.select.options).each(function(option, i) {
			if (value == option.value) {
				this.set(i);
				return;
			}
		}.bind(this));	
	},
	
	getValue: function() {
		return this.select.options[this.select.selectedIndex].value;
	}
});

/**
 * Всплывающий слой
 */
Puzzle.Controls.Popup = Class.create({
	
	initialize: function(popup) {
		var e = Prototype.emptyFunction;
		this.config = Object.extend({
			afterLoad: e,
			closeOnDocumentClick: true,
			draggable: false,
			showCurtain: true,
			fixedPosition: false
		}, arguments[1] || { });
		
		this.popup = $(popup);
		this.active = false;
		this.opener = null;
		
		var position = this.config.fixedPosition ? 'fixed' : 'absolute';
		
		this.container = new Element('div', {
			'className': 'PuzzlePopupContainer',
			'style': 'position: ' + position + '; z-index:100; display:none;'
		});
		document.body.appendChild(this.container);
		this.container.update(this.popup.remove());
		this.closer = this.popup.down('.closer');
		//new Puzzle.Effects.Shadow(this.container);
		
		this.popup.show();
		
		if (this.config.draggable) {
			new Draggable(this.container);
		}
		
		this.initMouseEvents();
	},
	
	initMouseEvents: function() {
		if (this.config.closeOnDocumentClick) {
			Event.observe(document, 'click', this.onDocumentClick.bind(this));
		}
		if (this.closer) {
			this.closer.observe('click', this.hide.bind(this));
		}
	},
	
	onDocumentClick: function(event) {
		if (!this.active) return;
		var el = Event.element(event);
		if (this.opener && (el == this.opener || el.up() == this.opener)) return;
		if (el == this.container || el.up('.PuzzlePopupContainer') == this.container) return;
		this.hide();
	},
	
	show: function(position) {
		if (this.config.showCurtain) {
			this.showCurtain();
		}
		if (Object.isElement(position)) {
			this.opener = position; 
		}
		if (position == 'center') {
			this.container.show();
			this.move([Math.round(getClientCenterX() - this.container.offsetWidth / 2),
			           Math.round(getClientCenterY() - this.container.offsetHeight / 2)]);
		} else if (position) {
			this.opener = position;
			this.move(position);
		}
		this.active = true;
		this.container.setStyle({'z-index': 1000});
		this.container.appear({ duration: 0.2 });
	},
	
	hide: function() {
		this.hideCurtain();
		this.active = false;
		this.container.fade({ duration: 0.2 });
	},
	
	move: function(position) {
		if (Object.isArray(position)) {
			position = { left: position[0], top: position[1] };
		} else if (Object.isElement(position) || Object.isString(position)) {
			position = $(position).cumulativeOffset();
		}
		
		var w = (document.body.scrollWidth > document.body.offsetWidth)?document.body.scrollWidth:document.body.offsetWidth;
		var h = (document.body.scrollHeight > document.body.offsetHeight)?document.body.scrollHeight:document.body.offsetHeight;
		var offset = 20;
		
		if ((position.left + this.container.getWidth()) > (w - offset)) {
			position.left -= (position.left + this.container.getWidth()) - (w - offset); 
		}
		if ((position.top + this.container.getHeight()) > (h - offset)) {
			position.top -= (position.top + this.container.getHeight()) - (h - offset); 
		}
		
		this.container.setStyle({
			'left': position.left + 'px',
			'top': position.top + 'px'
		});
	},
	
	showCurtain: function() {
		if (!this.curtain) {
			var height	= (document.body.scrollHeight > document.body.offsetHeight)?document.body.scrollHeight:document.body.offsetHeight;
			var width	= (document.body.scrollWidth > document.body.offsetWidth)?document.body.scrollWidth:document.body.offsetWidth;
			this.curtain = new Element('div', {
				'style': 'position: absolute; z-index: 1; left: 0; top: 0; width: ' + width + 'px; height: ' + height + 'px; background-color: #000; opacity: 0.5; //filter:progid:DXImageTransform.Microsoft.Alpha(opacity=50);'
			});
			document.body.appendChild(this.curtain);
		}
		this.curtain.show();
	},
	
	hideCurtain: function() {
		if (this.curtain) {
			this.curtain.hide();
		}
	}
});

/**
 * Всплывающий слой с загрузкой контента
 */
Puzzle.Controls.AjaxPopup = Class.create(Puzzle.Controls.Popup, {
	
	initialize: function(url) {
		var e = Prototype.emptyFunction;
		this.config = Object.extend({
			method: "get",
			parameters: { },
			afterLoad: e
		}, arguments[1] || { });
		
		this.url = url;
		this.container = null;
		this.active = false;
		this.opener = null;
		this.loading = false;
	},
	
	load: function(position, bShow) {
		if (this.loading) return;
		this.loading = true;
		new Ajax.Request(this.url, {
			method: this.config.method || "get", 
			parameters: this.config.parameters || { },
			onSuccess: function(response) {
				this.build(response.responseText);
				this.initMouseEvents();
				this.config.afterLoad.call(this);
			 	if (bShow) this.show(position);
			 	this.loading = false;
			 }.bind(this)
		});
	},
	
	build: function(content) {
		this.container = new Element('div', {
			'className': 'PuzzlePopupContainer',
			'style': 'position: absolute; z-index:100; display:none;'
		});
		this.container.update(content);
		document.body.appendChild(this.container);
		//new Puzzle.Effects.Shadow(this.container);
		
		this.closer = this.container.down('.closer');
	},
	
	show: function(position) {
		if (this.config.showCurtain) {
			this.showCurtain();
		}
		if (Object.isElement(position)) {
			this.opener = position; 
		}
		if (!this.container) {
			this.load(position, true);
			return;
		}
		if (position) {
			this.move(position);
		}
		this.active = true;
		this.container.appear({ duration: 0.2 });
	}
});

/**
 * Разворачиватель чего-либо.
 */
Puzzle.Controls.Expander = Class.create({
	
	initialize: function(link, div, bExpand) {
		this.link = $(link);
		this.div = $(div);
		
		this.link.observe('click', this.handleClick.bind(this));

		this[bExpand ? 'expand' : 'collapse']();
	},
	
	handleClick: function(event) {
		this.div.toggleClassName('collapsed');
		this[this.div.hasClassName('collapsed') ? 'collapse' : 'expand']();
		this.link.blur();
		
		Event.stop(event);
	},
	
	collapse: function() {
		this.link.update('Развернуть');
	},
	
	expand: function() {
		this.link.update('Свернуть');
	}
});


/**
 * Добавляет в инпуты примера значения
 */
Puzzle.Controls.PlaceHolder = Class.create({
	
	initialize: function(element, msg, restore) {
		this.element = $(element);
		this.msg = msg;
		this.restore = restore || false;
		
		this.element.observe('focus', this.clearMsg.bind(this));

		if (this.element.form) {
			$(this.element.form).observe('submit', this.clearMsg.bind(this));
		}

		if (this.restore) {
			this.element.observe('blur', this.setMsg.bind(this));
		}

		this.setMsg();
	},
	
	setMsg: function() {
		if (!this.element.value || this.element.value == this.msg) {
			this.element.addClassName('placeholder');
			this.element.value = this.msg;
		} else {
			this.element.removeClassName('placeholder');
		}
	},
	
	clearMsg: function() {
		this.element.value = (this.element.value == this.msg) ? '' : this.element.value;
		this.element.removeClassName('placeholder');
	}
});


/**
 * Менеджер блоков формы
 */
Puzzle.Controls.FormBlockManager = Class.create({
	
	initialize: function(container, blockType) {
		this.BlockType = blockType || Puzzle.Controls.FormBlock;
		this.container = $(container);
		this.init();
	},
	
	init: function() {
		this.createList();
		this.createSortable();
		this.format();
	},
	
	createList: function() {
		this.blocks = new Array();
		
		this.container.select('.form-block').each(function(block, i) {
			this.blocks[i] = new this.BlockType(this, block, i);
		}.bind(this));
	},
	
	createSortable: function() {
		if (this.blocks.size() > 1) {
			Sortable.create(this.container, {
				tag: 'div',
				scroll: window,
				onChange: function() {
					this.format();
				}.bind(this)
			});
		} else {
			Sortable.destroy(this.container);
		}
	},
	
	format: function() {
		this.container.select('.form-block').each(function(block, i) {
			block.down('h2')[i == 0 ? 'show' : 'hide']();
			block.down('.form-block-add')[i < this.blocks.size() - 1 ? 'hide' : 'show']();
		}.bind(this));
	},
	
	add: function() {
		var block = this.blocks[0].clone();
		this.container.insert(block.getElement());
		this.blocks[this.blocks.size()] = block;
		this.createSortable();
		this.format();
		
		return false;
	},
	
	remove: function(block) {
		block.getElement().remove();
		this.blocks = this.blocks.without(block);
		this.createSortable();
		this.format();
	}
});

Puzzle.Controls.FormBlock = Class.create({
	
	initialize: function(manager, block, i) {
		this.manager = manager;
		this.block = $(block);
		
		this.getElement().down('.add-link').observe("click", this.manager.add.bind(this.manager));
		this.getElement().down('.remove-link').observe("click", this.remove.bind(this));
		
		this.init();
	},
	
	init: function() {
	},
	
	getElement: function() {
		return this.block;
	},
	
	clear: function() {
		this.getElement().select('input').each(function(_field) {
			_field.clear();
		});
		this.getElement().select('select').each(function(_field) {
			_field.selectedIndex = 0;
		});
		this.getElement().select('textarea').each(function(_field) {
			_field.clear();
		});
	},
	
	remove: function() {
		if (this.manager.blocks.size() > 1) {
			this.manager.remove(this);
		} else {
			return this.clear();
		}
		
		return false;
	},
	
	clone: function() {
		var new_el = new Element('div', { 'className': 'form-block relative' } );
		var _html = this.getElement().innerHTML;
		
		// Replace 'name' attriutes
		_html = _html.gsub(/data\[(\w+)\]\[(\d+)\]/, function(match) {
			return 'data[' + match[1] + '][' + this.manager.nextIndex + ']';
		}.bind(this));
		
		// Replace 'id' attriutes
		_html = _html.gsub(/([\"\'])([A-Za-z]+)(\d+)([A-Za-z]+)\1/, function(match) {
			return match[2] + this.manager.nextIndex + match[4];
		}.bind(this));
		
		this.manager.nextIndex++;
		
		var block = new this.manager.BlockType(this.manager, new_el.update(_html));
		block.clear();
		
		return block;
	}
});


/**
 * Менеджер тегов
 */
Puzzle.Controls.TagsManager = Class.create({
	initialize: function(ul, input, options, tagClass) {
		
		this.ul = $(ul);
		this.input = $(input);
		
		this.options = options || {};
		this.field = this.options.field || 'tags';
		this.source = this.options.source || [];
		this.tagClass = tagClass || Puzzle.Controls.Tag;
		this.tags = [];
		
		this.init();
	},
	
	init: function() {
		
		this.autocomplete = new Element('div', { 'class': 'autocomplete' } );
		this.input.up().insert(this.autocomplete);
		
		if (typeof(this.source) == "object") {
			new Autocompleter.Local(this.input, this.autocomplete, this.source, { ignoreCase: true, afterUpdateElement: this.onSelect.bind(this) } );
		} else {
			new Ajax.Autocompleter(this.input, this.autocomplete, this.source, { paramName: this.field, ignoreCase: true, afterUpdateElement: this.onSelect.bind(this) } );
		}
		this.input.observe('keypress', this.onKey.bindAsEventListener(this));
		this.input.observe('blur', this.onBlur.bindAsEventListener(this));
		
		this.add();
		
		if (typeof(this.options.values) == "object") {
			this.options.values.each(function(value) {
				this.add(value);
			}.bind(this));
		}
	},
	
	onKey: function(e) {
		if (e.keyCode == Event.KEY_RETURN) {
			Event.stop(e);
			this.add();
		} else {
			values = this.extract(this.input.value);
			if (values.length > 1) {
				values.pop();
				this.add(values);
			}
		}
	},
	
	onSelect: function(input, element) {
		this.add(input.value);
	},
	
	onBlur: function() {
		this.input.value = this.input.value.trim();
		setTimeout(function() {
			if (!this.input.value) return;
			if (window.confirm('Добавить тег «' + this.input.value + '»?')) {
				this.add(this.input.value);
			}
			this.input.value = '';
		}.bind(this), 1000);
	},
	
	add: function(values, options) {
		var values = values || this.input.value;
		this.input.value = '';
		
		if (!values) return;
		
		if (typeof(values) == 'string') {
			values = this.extract(values);
		}
		
		values.each(function(value) {
			value = value.trim();
			if (value && !this.find(value)) {
				var tag = new this.tagClass(this, value, options);
				this.tags.push(tag);
				this.ul.insert(tag.getElement());
			}
		}.bind(this));
	},
	
	extract: function(str) {
		return str.split(',').invoke('trim');
	},
	
	find: function(value) {
		var ret = null; 
		this.tags.each(function(tag) {
			if (tag.getValue().toLowerCase() == value.toLowerCase()) {
				ret = tag;
				return;
			}
		});
		return ret;
	},
	
	remove: function(item) {
		this.tags = this.tags.without(item);
	}
});

/**
 * Блок тега
 */
Puzzle.Controls.Tag = Class.create({
	initialize: function(manager, value, options) {
		this.manager = manager;
		this.value = value;
		this.options = options || {};
		
		this.element = this.createElement(this.value);
		
		this.element.down('.remove').observe('click', this.remove.bind(this));		
	},
	
	createElement: function(value) {
		var element = new Element('li');
		element.insert(new Element('input', { 'type': 'hidden', 'name': this.manager.options.field + '[][title]', 'value': value } ));
		element.insert(new Element('div', { 'class': 'remove', 'title': 'Удалить' } ));
		
		var url = this.manager.options.url || '';
		if (url) {		
			element.insert(
					new Element('div', { 'class': 'value' } ).update(
						new Element('a', { 'href': url + value }).update(value)
					)
				);
		} else {
			element.insert(new Element('div', { 'class': 'value' } ).update(value));
		}
		
		return element;
	},
	
	getValue: function() {
		return this.value;
	},
	
	getElement: function() {
		return this.element;
	},
	
	remove: function() {
		this.getElement().remove();
		this.manager.remove(this);
	}
});

/**
 * Rating
 */

Puzzle.Controls.Voter = Class.create({
	initialize: function(element, options) {
		this.element = $(element);
		this.form = $(element).down('form');
		this.select = $(element).down('select');
		this.button = $(element).down('input[type=submit]');
		
		options = options || {};
		this.img = options.img || '/img/icons/rating-stars.png';
		this.width = options.width || 20;
		this.height = options.height || 20;
		this.color = options.color || 'red';
		this.enabled = options.enabled || false;
		this.defaultValue = options.defaultValue || null;
		this.defaultIndex = -1;
		
		this.afterVote = options.afterVote || Prototype.emptyFunction;
		
		$A(this.select.options).each(function(option, i) {
			if ($(option).readAttribute('value') == this.defaultValue) {
				this.defaultIndex = i;
			}
		}.bind(this));
		
		//this.afterVote = this.options.afterVote || Prototype.emptyFunction;
		
		this.steps = $A(this.select.options).length;
		
		this.init();
	},
	init: function() {
		this.element.setStyle({
			'overflow': 'hidden',
			'position': 'relative',
			'width': (this.width * this.steps) + 'px',
			'height': this.height + 'px'
		});
		this.form.hide();
		
		this.bgr = new Element('div', {'style': 'background-color: red'});
		this.bgr.setStyle({
			'position': 'absolute', 
			'zIndex': '0',
			'width': (this.width * this.steps) + 'px',
			'height': this.height + 'px',
			'backgroundColor': this.color,
			'left': '-' + (this.width * this.steps) + 'px'
		});
		this.element.insert(this.bgr);
		
		this.img = new Element('img', {'src': this.img, 'style': 'position: relative; z-index: 1;'});
		this.element.insert(this.img);
		
		this.handler = new Element('div');
		this.handler.setStyle({
			'position': 'absolute',
			'zIndex': '2',
			'width': (this.width * this.steps) + 'px',
			'height': this.height + 'px',
			'left': '0px',
			'top': '0px'
		});
		this.element.insert(this.handler);
		
		this.reset();
		this.enable(this.enabled);
	},
	enable: function(bEnable) {
		this.enabled = bEnable ? true : false;
		if (this.enabled) {
			this.element.observe('mousemove', this.mouseMove.bindAsEventListener(this));
			this.element.observe('mouseout', this.mouseOut.bindAsEventListener(this));
			this.element.observe('click', this.mouseClick.bindAsEventListener(this));
		} else {
			this.element.stopObserving('mousemove');
			this.element.stopObserving('mouseout');
			this.element.stopObserving('click');
		}
		this.handler.setStyle({
			'cursor': this.enabled ? 'pointer' : 'auto'
		});
	},	
	mouseMove: function(e) {
		if (this.enabled) {
			this.updateValue(e);
		}
	},
	mouseOut: function(e) {
		if (this.enabled) {
			this.reset();
		}
	},
	mouseClick: function(e) {
		var offset = Event.pointerX(e) - this.handler.cumulativeOffset().left;
		var index = Math.floor(offset / this.width);		
		this.setValue(index);
		this.submit();
	},
	draw: function(index) {
		this.bgr.setStyle({
			'left': '-' + (this.width * (this.steps - index - 1)) + 'px'
		});
	},
	updateValue: function(e) {
		var offset = Event.pointerX(e) - this.handler.cumulativeOffset().left;
		var index = Math.floor(offset / this.width);
		this.draw(index);
		this.handler.writeAttribute('title', this.select.options[index].text);
	},
	setValue: function(index) {
		this.select.selectedIndex = index;
		this.draw(index);
		this.handler.writeAttribute('title', this.select.options[index].text);
	},
	reset: function() {
		this.select.selectedIndex = this.defaultIndex;
		this.draw(this.defaultIndex);
	},
	submit: function() {
		this.enable(false);
		
		this.form.request({
			method: 'post',
			onComplete: function(){
				this.afterVote.call();
			}.bind(this)
		})
		if (vote_popup) {
			vote_popup.hide();
		}
	}
});

/**
 * Контрол для выбора значений из взаимосвязанных селектов
 */
Puzzle.Controls.MultiSelector = Class.create({
	initialize: function(selects, values) {
		
		this.selects = selects;
		this.values = values;
		
		this.selects.each(function(item, level) {
			if (level < this.selects.length - 1) {
				$(item).observe('change', function(e) {
					this.updateNextSelect(level + 1, $(item).value);
				}.bind(this));
			}
		}.bind(this));
	},
	
	updateNextSelect: function(level, filter) {
		var select = $(this.selects[level]);
		select.childElements().each(function(option) {
			$(option).remove();
		});
		this.values[level].each(function(item) {
			if (filter == null || item[2] == filter) {
				var option = new Element('option', {'value': item[0]}).update(item[1]);
				select.insert(option);
			}
		});
		if (level < this.selects.length - 1) {
			this.updateNextSelect(level + 1, this.values[level][0][0]);
		}
	},
	
	update: function() {
		this.updateNextSelect(0, null);
	},
	
	add: function(level, id, title, parent_id) {
		var value = [id, title, parent_id];
		if (!this.values[level]) {
			this.values[level] = [];
		}
		this.values[level].push(value);
	},
	
	set: function(level, value) {
		var select = $(this.selects[level]);
		select.childElements().each(function(option, index) {
			if (option.value == value) {
				option.selected = true;
				return;
			}
		});
	}
});


