Element.addMethods(['input', 'select', 'textarea', 'button', 'a'], {
	my_disable: function(el_) {
		var el = $(el_);
		try {
			el.addClassName('disabled');
			el.setAttribute('disabled', 'disabled');
			el.old_onclick = el.onclick;
			el.onclick = function() { return false; }
		} catch(e_) {}
		return el;
	},
	my_enable: function(el_) {
		var el = $(el_);
		try {
			el.removeClassName('disabled');
			el.removeAttribute('disabled');
			el.onclick= el.old_onclick;
		} catch(e_) {}
		return el;
	}
} );

Element.addMethods(['input', 'textarea'], {
	my_focus: function(el_) {
		var el = $(el_);
		setTimeout( function() {
			try {
				el.focus();
			} catch(e_) {}
		}, 100);
	}
} );

Element.addMethods('form', {
	my_serialize: function(el_) {
		var el = $(el_);
		el.select('input').concat(el.select('textarea')).each( function(input_) {
			input_.setAttribute('oldvalue', input_.value);
			if (
				typeof(input_.getAttribute('title')) == 'string' &&
				input_.getAttribute('title') == $F(input_)
			) input_.setValue('');
		} );
		var result = el.serialize();
		el.select('input').concat(el.select('textarea')).each( function(input_) {
			if (typeof(input_.getAttribute('oldvalue')) == 'string') {
				input_.value = input_.getAttribute('oldvalue');
			}
		} );
		return result;
	},
	my_extend: function(el_) {
		var el = $(el_);

		if (typeof(el.events) != 'undefined') return;
		if (typeof(Form.dirtyflags) == 'undefined') Form.dirtyflags = new Hash();

		el.events = new Hash();
		el.events.set('onfocus', function() {
			try {
				this.removeClassName('default');
				if (this.getAttribute('title') == $F(this)) this.setValue('');
			} catch(e_) {}
		} );
		el.events.set('onblur', function() {
			try {
				if ($F(this) == '') {
					this.addClassName('default');
					this.setValue(this.getAttribute('title'));
				}
			} catch(e_) {}
		} );
		el.events.set('onchange', function() {
			var self = this;
			Form.dirtyflags.set(this.parentform.getAttribute('id'), true);
			this.linked.each( function(field_) {
				try {
					if (
						$F(self.parentform[field_]) == '' ||
						$F(self.parentform[field_]) == $(self.parentform[field_]).getAttribute('title') ||
						$F(self.parentform[field_]) == $(self.parentform[field_]).getAttribute('force_title')
					) {
						$(self.parentform[field_]).setValue($F(self));
						$(self.parentform[field_]).removeClassName('default');
					}
					$(self.parentform[field_]).setAttribute('force_title', $F(self));
				} catch(e_) {}
			} );
		} );

		el.selects = el.select('select').each( function(select_) {
			var classNames = $w(select_.className);

			select_.addClassName('offscreen');
			select_.setAttribute('tabindex', '-1');
			var input = new Element('input', { 'class':'select', 'title':select_.getAttribute('title'), 'readonly':'readonly', 'value':select_.options[select_.selectedIndex].text } );
			

			classNames.each( function(class_) {
				input.addClassName(class_);
			} );


			var keypress = function(e_) {
				switch(e_.keyCode) {
					case Event.KEY_ESC:
					case Event.KEY_TAB:
						this.ul.hide();
						input.style.backgroundPosition = 'right top';
						break;
				}
				return false;
			}
			var outclick = function(e_) {
				if (e_.element() != this.ul) {
					this.ul.hide();
					input.style.backgroundPosition = 'right top';
				}
			}

			var input_focus = function(event_) {
				var element = Event.element(event_);
				var offset = Element.positionedOffset(element);

				var width = this.getWidth() - 2;
				if (typeof(this.select.getAttribute('width')) == 'string') width = this.select.getAttribute('width');

				this.ul.setStyle( {
					left:offset.left + 'px',
					top:(offset.top + this.getHeight()) + 'px',
					width:width + 'px'
				} ).show();

				this.ul.scrollTop = this.ul.selected_li.positionedOffset().top - (this.ul.getHeight() / 2) + (this.ul.selected_li.getHeight() / 2);
				this.ul.selected_li.addClassName('hover');

				input.style.backgroundPosition = 'right bottom';

				if (typeof(this.done) != 'boolean') {
					this.done = true;
					Event.observe(document, 'keydown', keypress.bindAsEventListener(this));
					Event.observe(document, 'mouseup', outclick.bindAsEventListener(this));
				}
			}

			Event.observe(input, 'focus', input_focus.bindAsEventListener(input));
			Event.observe(input, 'click', input_focus.bindAsEventListener(input));

			var li_select = function() {
				this.select.value = this.data.get('value');
				this.ul.selected_li = this;
				this.ul.hide();
				this.input.value = this.data.get('text');
				input.style.backgroundPosition = 'right top';
				try {
					this.select.onchange();
				} catch(e_) {}
			}
			var li_mouseover = function() {
				this.ul.selected_li.removeClassName('hover');
				this.addClassName('hover');
			}
			var li_mouseout = function() {
				this.removeClassName('hover');
			}

			var ul = new Element('ul', { 'class':'select' } ).hide();
			var li;
			for (var i = 0; i < select_.options.length; i++) {
				li = new Element('li').update(select_.options[i].text);
				li.data = new Hash();

				li.data.set('text', select_.options[i].text);
				li.data.set('value', select_.options[i].value);
				if (i == select_.selectedIndex) ul.selected_li = li;

				li.select = select_;
				li.ul = ul;
				li.input = input;

				Event.observe(li, 'click', li_select.bindAsEventListener(li));
				Event.observe(li, 'mouseover', li_mouseover.bindAsEventListener(li));
				Event.observe(li, 'mouseout', li_mouseout.bindAsEventListener(li));

				ul.appendChild(li);
			}

			input.ul = ul;
			input.select = select_;
			ul.input = input;

			select_.parentNode.insertBefore(input, select_);
			select_.parentNode.appendChild(ul);
		} );

		el.getElements().each( function(input_) {
			var def = input_.getAttribute('title');
			if (typeof(def) == 'string') {
				if ($F(input_) == '') input_.setValue(def);
				if ($F(input_) == def) input_.addClassName('default');
				Event.observe(input_, 'focus', el.events.get('onfocus').bindAsEventListener(input_));
				Event.observe(input_, 'blur', el.events.get('onblur').bindAsEventListener(input_));
			}
			var linked = input_.getAttribute('linked');
			if (typeof(linked) == 'string') {
				input_.linked = $A(linked.split(','));
			} else input_.linked = new Array();
			input_.parentform = el;
			Event.observe(input_, 'change', el.events.get('onchange').bindAsEventListener(input_));
		} );

		el.events.set('onmouseover', function() {
			this.span.style.backgroundPosition = this.x_offset + ' ' + (this.checked ? '-75px' : '-25px');
		} );
		el.events.set('onmouseout', function() {
			this.span.style.backgroundPosition = this.x_offset + ' ' + (this.checked ? '-50px' : '0px');
		} );


		el.events.set('onmouseclick', function() {
			if (this.getAttribute('type') == 'radio') {
				this.checked = true;
			} else this.checked = ! this.checked;
			this.the_form.radios.each( function(input_) {
				if (input_.disabled) return;
				input_.span.style.backgroundPosition = input_.x_offset + ' ' + (input_.checked ? '-50px' : '0px');
			} );
			this.span.style.backgroundPosition = this.x_offset + ' ' + (this.checked ? '-75px' : '-25px');


			try {
				this.onclick();
			} catch(e_) {}
			try {
				this.onchange();
			} catch(e_) {}
		} );


		el.events.set('radioclick', function() {
			this.the_form.radios.each( function(input_) {
				if (input_.disabled) return;
				input_.span.style.backgroundPosition = input_.x_offset + ' ' + (input_.checked ? '-50px' : '0px');
			} );
		} );

		el.radios = el.select('input[type="radio"]', 'input[type="checkbox"]').each( function(input_) {
			var type = input_.getAttribute('type');
			input_.x_offset = type == 'radio' ? '-24px' : '0px';
			input_.addClassName('offscreen');
			input_.setAttribute('tabindex', '-1');

			var span = new Element('span', { 'class':'my_' + type } );
			if (
				typeof(window.__ie) == 'number' &&
				window.__ie < 7
			) span.addClassName('my_' + type + '_ie6');

			if (! input_.disabled) {
				span.style.cursor = 'pointer';
				span.style.backgroundPosition = input_.x_offset + ' ' + (input_.checked ? '-50px' : '0px');
				Event.observe(span, 'mouseover', el.events.get('onmouseover').bindAsEventListener(input_));
				Event.observe(span, 'mouseout', el.events.get('onmouseout').bindAsEventListener(input_));

				Event.observe(span, 'click', el.events.get('onmouseclick').bindAsEventListener(input_));

				Event.observe(input_, 'click', el.events.get('radioclick').bindAsEventListener(input_));			
			} else {
				span.style.cursor = 'not-allowed';
				span.style.backgroundPosition = input_.x_offset + ' ' + (input_.checked ? '-125px' : '-100px');
			}

			input_.span = span;
			input_.the_form = el;
			input_.parentNode.insertBefore(span, input_);
		} );
		return el;
	},
	set_dirty:function(el_) { Form.dirtyflags.set(el_.getAttribute('id'), true); },
	is_dirty:function(el_) { return typeof(Form.dirtyflags.get($(el_).getAttribute('id'))) == 'boolean' && Form.dirtyflags.get($(el_).getAttribute('id')); },
	is_clean:function(el_) { return ! $(el_).is_dirty(); },
	ignore:function(el_) { Form.dirtyflags.set($(el_).getAttribute('id'), false); },
	my_submit:function(el_, options_) {
		var el = $(el_);
		if (typeof(Form.dirtyflags) == 'undefined') Form.dirtyflags = new Hash();

		var options = $H( {
			modal:true,
			button:false,
			buttons:'Close',
			button_default:false,
			button_cancel:false,
			action:'untitled.html'
		} );
		options.update($H(options_));

		var dlg;
		if (
			options.get('modal') &&
			typeof(dialog) != 'undefined' &&
			typeof(dlg = dialog.onTop()) != 'boolean'
		) return false;

		if (typeof(options.get('button')) !== 'boolean') {
			if (typeof(options.get('button')) == 'string') {
				options.set('button', $A(options.get('button').split(',')));
			} else {
				var buttons = new Array(options.get('button'));
				options.set('button', $A(buttons));
			}



			options.get('button').each( function(button_) {
				$(button_).my_disable();
			} );
		}

		el.select('.field_error').each( function(field_) {
			field_.removeClassName('field_error');
		} );

		var marker = el.appendChild(new Element('input', {
			'type':'hidden',
			'name':'__ajaxcall',
			'value':'1'
		} ));

		new Ajax.Request(
			options.get('action'), {
				method:'post',
				parameters:el.my_serialize(),
				onComplete:function(req_) {
					el.removeChild(marker);

					var results = req_.responseText.toQueryParams();
					if (typeof(results['result']) != 'string') {
						alert(req_.responseText);
						if (typeof(options.get('button')) !== 'boolean') {
							$(options.get('button')).each( function(button_) {
								$(button_).my_enable();
							} );
						}
						if (typeof(options.get('onError')) == 'function') options.get('onError')(results);
					} else {
						switch(results['result']) {
							case 'OK':
								Form.dirtyflags.set(el.getAttribute('id'), false);
								if (typeof(options.get('onSuccess')) == 'function') options.get('onSuccess')(results);
								break;
							case 'NOTICE':
								Form.dirtyflags.set(el.getAttribute('id'), false);
								dialog.open( {
									content:'<p>' + results['content'] + '</p>',
									title:results['title'],
									buttons:options.get('buttons'),
									button_default:options.get('button_default'),
									button_cancel:options.get('button_cancel'),
									width:420,
									duration:0,
									callback:function(action_, dialog_) {
										try {
											dialog_.close( function() {
												if (typeof(options.get('button')) !== 'boolean') {
													$(options.get('button')).each( function(button_) {
														$(button_).my_enable();
													} );
												}
												if (typeof(el[errors[0]]) != 'undefined') el[errors[0]].my_focus();
											} );
										} catch(e_) {}
										if (typeof(options.get('onSuccess')) == 'function') options.get('onSuccess')(results);
									}
								} );
								break;
							default:
								var errors;
								try {
									(errors = $A(results['fields'].split(';'))).each( function(field_) {
										if (typeof(el[field_]) != 'undefined') {
											Element.addClassName(el[field_], 'field_error');
										}
									} );
								} catch(e_) {}
								dialog.open( {
									content:'<p>' + results['content'] + '</p>',
									title:results['title'],
									buttons:options.get('buttons'),
									button_default:options.get('button_default'),
									button_cancel:options.get('button_cancel'),
									width:420,
									duration:0,
									callback:function(action_, dialog_) {
										try {
											dialog_.close( function() {
												if (typeof(options.get('button')) !== 'boolean') {
													$(options.get('button')).each( function(button_) {
														$(button_).my_enable();
													} );
												}

												if (typeof(el[errors[0]]) != 'undefined') el[errors[0]].my_focus();
											} );
										} catch(e_) {}
										if (typeof(options.get('onError')) == 'function') options.get('onError')(action_, results);
									}
								} );
								break;
						}
					}
				}
			}
		);
		return el;
	}
} );
