/*  Form Advanced Controls, version 0.02
 *  Prototype JS Library required - see http://www.prototypejs.org for details 
 *  (c) 2007 Lukáš Zaplatílek 
 * ---------------------------------------------------------------------------*/


/* FormKeeper
 * ---------------------------------------------------------------------------
 * Keeps information about selected form's elements changes - useful, when
 * there exists another way to leave the page with form unsubmitted.
 * Fires alert window, when any of the form (with alert-change className)
 * has been changed and user leaves the page another way (by activating
 * link element or submitting another form).
 * ---------------------------------------------------------------------------*/
FormKeeper = Class.create();
FormKeeper.prototype = {
	alertChange : function(e) {
		var clicked = Event.element(e);
		var changedOtherForm = false;
		this.changed.each(function (elm) {
			if (elm.form != clicked) {
				changedOtherForm = true;
			}
		});
		if ((this.changed.size() > 0) && changedOtherForm) {
			var changedString = 'Byla změněna tato pole:';
			this.changed.each(function (elm) {
				changedString = changedString + ' ' + elm.label + ',';
			});
			changedString = changedString + ' chcete zapomenout tyto změny?';
			if (!confirm(changedString)) {
				Event.stop(e);
				return false;
			} 
		} 
		return true;
	},
	
	setAlert: function(e) {
		var elm = Event.element(e);
		var div = Event.findElement(e, 'div');
		var label = div.down('label');
		elm.label = label ? label.innerHTML : elm.name;
		this.changed.push(elm);
	},
	
	initialize : function() {
		this.forms = $A(document.getElementsByTagName('form'));
		
		if (this.forms.size() > 0) {
			this.keep = false;
			this.forms.each(function(form) {
				Element.extend(form);
				if (form.hasClassName('alert-change')) {
					this.keep = true;
					form.getElements().each(function(elm, form) {
						Event.observe(elm, 'change', this.setAlert.bindAsEventListener(this));
					}.bind(this));
				}
				Event.observe(form, 'submit', this.alertChange.bindAsEventListener(this));
			}.bind(this));
			
			if (this.keep) {
				this.links = $A(document.getElementsByTagName('a'));
				this.changed = [];
				this.links.each(function (link) {
					Event.observe(link, 'DOMActivate', this.alertChange.bindAsEventListener(this));
				}.bind(this));
			}
		}
	}
}

/* SearchCheckbox
 * ---------------------------------------------------------------------------
 * Visual conversion of a set of radio buttons. Marks active element with CSS
 * class. 
 * ---------------------------------------------------------------------------*/
activeSearchLI = null;
SearchCheckbox = Class.create();
SearchCheckbox.prototype = {
	change: function() {
		Element.removeClassName(activeSearchLI.li, 'active');
		Element.addClassName(this.li, 'active');
		activeSearchLI.radio.checked = false;
		this.radio.checked = true;
		activeSearchLI = this;
	},

	initialize: function(li) {
		this.li = li;
		this.radio = this.li.getElementsByTagName('INPUT')[0];
		this.label = this.li.getElementsByTagName('LABEL')[0];
		this.radio.style.display = 'none';
		if (this.radio.checked) {
			activeSearchLI = this;
			this.change();
		}
		Event.observe(this.label, 'click', this.change.bindAsEventListener(this));
	}
}

/* RadiosGroup
 * ---------------------------------------------------------------------------
 * Data structure to hold a set of radio buttons.
 * ---------------------------------------------------------------------------*/
RadiosGroup = Class.create();
RadiosGroup.prototype = {

	toString: function() {
		var itemsString = '[';
		this.items.each(function(item, index) {
			if (index > 0) {
				itemsString = itemsString + ', ';	
			}
			itemsString = itemsString + '\'' + item.value + '\': \'' + item.label.innerHTML + '\'';
		});
		return '{name: \'' + this.name + '\', items: ' + itemsString + ']}';
	},
	
	initialize: function(name) {
		this.name = name;
		this.items = [];
	}
};

/* RadioChooser
 * ---------------------------------------------------------------------------
 * Visual and functional conversion of a set of radio buttons to a set of
 * hyperlinks. Useful when auto-submitting the form containing only one set of
 * radio buttons is needed.
 * ---------------------------------------------------------------------------*/
RadioChooser = Class.create();
RadioChooser.prototype = {

	chooseAndSubmit: function(e) {
		var label = Event.findElement(e, 'label');
		label.input.checked = 'checked';
		this.parent.up('form').submit();
	},

	initialize: function(parent) {
		this.parent = parent;
		var inputs = this.parent.getElementsByTagName('input');
		
		this.radiosGroups = [];
		this.radiosGroups.push(new RadiosGroup(inputs[0].name));
		
		for (var i = 0; i < inputs.length; i++) {
			switch (inputs[i].type.toLowerCase()) {
				case 'radio':
					if (inputs[i].name != this.radiosGroups.last().name) {
						this.radiosGroups.push(new RadiosGroup(inputs[i].name));
					}
					var input = Element.extend(inputs[i]);
					
					var label = input.next('label');
					label.addClassName('button');
					label.addClassName(input.value);
					if (input.checked) {
						label.addClassName('active');
					}

					label.input = input;
					input.label = label;
					
					this.radiosGroups.last().items.push(input);
					
					input.style.display = 'none';
					Event.observe(label, 'click', this.chooseAndSubmit.bindAsEventListener(this));
					
					break;
					
				case 'submit':
				case 'image':
					inputs[i].style.display = 'none';
					break;
					
				default:
					break;
			}
		}
	}
};

/* OptionsHighlighter
 * ---------------------------------------------------------------------------
 * Highlights selected pair (radio button + its label) with CSS class.
 * Hides/displays aditional information about choosable options.
 * 
 * TODO: Connect with a class to control possible combinations of two or more
 * sets of radio buttons.
 * ---------------------------------------------------------------------------*/
OptionsHighlighter = Class.create();
OptionsHighlighter.prototype = {

	change: function(e) {
		var data = $A(arguments);
		if (e.type == 'click' && this.active != data[1]) {
			this.active.label.removeClassName('checked');
			if (this.active.info) {
				this.active.info.style.display = 'none';
			}
			this.active = data[1];
			this.active.label.addClassName('checked');
			if (this.active.info) {
				this.active.info.style.display = 'block';
				if(typeof Effect != 'undefined' && !this.animating) {
					new Effect.Highlight(this.active.info, {duration: 0.5});
				}
			}
		}
	},
	
	initialize: function(optionContainers, moreDetailsContainer) {
		this.divs = optionContainers;
		this.moreDetails = moreDetailsContainer;

		this.animating = false;
		
		this.divs.each(function(div) {
			div.options = div.getElementsBySelector('input');
			if (div.options) {
				div.options.each(function(input, div) {
					input.label = input.next('label');
					input.info = $(input.id + '_info');
					if (input.info) {
						input.info.style.display = 'none';
					}
					if (input.checked) {
						this.active = input;
						this.active.label.addClassName('checked');
						if (this.active.info) {
							this.active.info.style.display = 'block';
						}
					}
					input.observer = this.change.bindAsEventListener(this, input);
					Event.observe(input, 'change', input.observer);
					Event.observe(input, 'click', input.observer);
					Event.observe(input.label, 'click', input.observer);
				}.bind(this));
			}
		}.bind(this));
	}
};
