/* StartUp */

var pfStartUp = Class.create({
	initialize: function(runnable)
	{
	  document.observe('dom:loaded', runnable.run.bindAsEventListener(runnable));
	}
});

/* Ajax */

var pfAjax =
{
	showLoading: function(id)
	{
		pfAjax.setVisibility(id, 'visible');
  },

	hideLoading: function(id, visibility)
	{
		pfAjax.setVisibility(id, 'hidden');
  },

	setVisibility: function(id, visibility)
	{
		var loading = $$('#' + id + ' .proforma_loading').first();
		if (!loading) return;
		loading.style.visibility = visibility;
	}
}

/* Calendar */

var pfCalendar =
{
	run: function()
	{
	  var inputs = $$('form input.date');
	  for (var i = 0; i < inputs.length; i++) {
			var input = inputs[i];
			if (!input.readOnly) {
		  	input.button = pfCalendar.createButton(input.id);
		  	input.parentNode.appendChild(input.button);
		  	pfCalendar.initCalendar(input, input.button, input.hasClassName('reload'));
		  }
		}
	},

	createButton: function(id)
	{
		var button = document.createElement('button');
		button.setAttribute('type', 'button');
		Element.addClassName(button, 'button');
		button.id = id + '_button';
		button.innerHTML = pfSettings['calendar_button_text'];
		return button;
	},

	initCalendar: function(input, button, reload)
	{
		Calendar.setup({
			inputField : input,
			ifFormat   : "%d.%m.%Y",
			button     : button,
			onUpdate   : (reload && pfAjaxReload) ? pfAjaxReload.reloadForm.bindAsEventListener(input) : null
		});
  }
};

/* Reload */

var pfReload =
{
	run: function()
	{
	  var tags = $$('form.proforma .reload');
	  for (var i = 0; i < tags.length; i++) {
			var tag = tags[i];
			Event.observe(tag, 'change', pfReload.submitForm.bindAsEventListener(tag));
		}
		pfReload.removeButtons();
	},

	removeButtons: function()
	{
	  var buttons = $$('form.proforma .reload_button');
	  for (var i = 0; i < buttons.length; i++) {
			buttons[i].remove();
		}
	},

	createHidden: function(field)
	{
		var form = field.form
		var hidden = document.createElement('input');
		hidden.type = 'hidden';
		hidden.name = 'pf_reload';
		hidden.value = field.name;
		form.appendChild(hidden);
	},

	submitForm: function()
	{
		pfReload.createHidden(this);
	  this.form.submit();
	}
};

/* AjaxReload */

var pfAjaxReload =
{
	run: function()
	{
	  var tags = $$('form.proforma .reload');
	  for (var i = 0; i < tags.length; i++) {
			var tag = tags[i];
			Event.observe(tag, 'change', pfAjaxReload.reloadForm.bindAsEventListener(tag));
		}
		pfReload.removeButtons();
	},

	reloadForm: function()
	{
		pfAjax.showLoading(this.form.getAttribute('id'));
		var params = Form.serialize(this.form, true);
		params['pf_ajax_reload'] = this.form.getAttribute('id');
		params['pf_reload'] = this.name;
		new Ajax.Request(location.href, {
			parameters: params,
			onSuccess: pfAjaxReload.processReload.bindAsEventListener(this.form)
		});
	},
	
	processReload: function(transport)
	{
		var data = transport.responseJSON;
		pfAjaxReload.updateFields(data);
		pfAjax.hideLoading(this.getAttribute('id'));
  },
	
	updateFields: function(data)
	{
		for (var id in data) {
			pfAjaxReload.updateField(id, data[id]);
		}
  },

	updateField: function(id, data)
	{
		var field = $(id);
		if (data['value'] != null && data['value'] != undefined) {
			field.value = data['value'];
		}
		if (data['options']) {
			var options = data['options'];
			field.innerHTML = '';
			for (var item in options) {
		  	var option = new Option(options[item], item);
		  	field.options[field.options.length] = option;
	  	}
		}
  }
};

/* AjaxValidation */

var pfAjaxValidation =
{
	run: function()
	{
	  var forms = $$('form.proforma.validate');
	  for (var i = 0; i < forms.length; i++) {
			var form = forms[i];
			form.isValid = false;
			Event.observe(form, 'submit', pfAjaxValidation.validateForm.bindAsEventListener(form));
		}
	  var buttons = $$('form.proforma.validate input');
	  for (var i = 0; i < buttons.length; i++) {
			var button = buttons[i];
			Event.observe(button, 'click', pfAjaxValidation.buttonClicked.bindAsEventListener(button));
		}
	},

	validateForm: function(e)
	{
		if (this.isValid) return;
		pfAjax.showLoading(this.getAttribute('id'));

		var params = this.getElements();
		for (var i = 0; i < params.length; i++) {
			var param = params[i];
			if (param['type'] == 'submit') {
				params[i] = new Object;
			}
		}
		if (this.clickedButton) {
			params[i++] = this.clickedButton;
		}
		params = Form.serializeElements(params, true);
		params['pf_ajax_validation'] = this.getAttribute('id');

		new Ajax.Request(this.action, {
			parameters: params,
			onSuccess: pfAjaxValidation.processValidation.bindAsEventListener(this)
		});
		Event.stop(e);
  },

	processValidation: function(transport)
	{
		pfAjaxValidation.displayErrors(this, transport.responseJSON);
		pfAjax.hideLoading(this.getAttribute('id'));
		if (this.isValid) {
			if (this.clickedButton) {
				this.clickedButton.click();
		  } else {
		  	this.submit();
		  }
		}
	},
	
	displayErrors: function(form, errors)
	{
		var valid = true;
		for (var item in errors) {
			valid = pfAjaxValidation.displayError(item, errors[item]) && valid;
		}
		form.isValid = valid;
	},
	
	displayError: function(id, error)
	{
		var is_valid = error == null;
		if (!$(id) || $(id).type == 'hidden') return is_valid;
		var label = $(id).previous('label');
		if (!label) var label = $(id).next('label');
		if (!label) var label = $(id).down('legend');
		if (!label) return is_valid;
		if (label.originalHTML) {
			var label_html = label.originalHTML;
		} else {
			var label_html = label.innerHTML;
			label.originalHTML = label_html;
		}
		if (is_valid) {
			error_html = '';
			label.up().removeClassName('error');
		} else {
			label.up().addClassName('error');
			if (pfSettings['error_html']) {
				var error_html = pfSettings['error_html'].replace('[error_message]', error);
			} else {
				var error_html =
					' <strong><img src="' + pfSettings['error_image_path'] + '" alt="' +
					pfSettings['error_image_text'] + '" /> ' + error + '</strong>';
			}
		}
		label.innerHTML = label_html + error_html;
		return is_valid;
	},

	buttonClicked: function(e)
	{
		this.form.clickedButton = this;
		if (this.hasClassName('no_validation')) this.form.isValid = true;
  }
}

/* Initialize */
new pfStartUp(pfCalendar);
//new pfStartUp(pfReload);
new pfStartUp(pfAjaxReload);
new pfStartUp(pfAjaxValidation);
