Rtp.AjaxForm = function(config) {
	Ext.apply(this, config);
	this.form = Ext.get('ajax-form-'+this.id);
	Ext.EventManager.addListener(this.form.dom, 'submit', this.submit, this);
	if (this.focus_field) {
  	var field = this.getField(this.focus_field);
		field.focus();
  }
	if (this.field_listeners instanceof Array) {
		Ext.each(this.field_listeners, function(l) {
			var field = this.getField(l.field_name, false);
			Ext.EventManager.addListener(field, l.event, l.handler, this);
		}, this);
	}
	if (this.state_fields instanceof Array) {
		Ext.each(this.state_fields, function(s) {
			this.registerStateField(s.state_field, s.country_field);
		} ,this);
	}
	this.fireEvent('init');
}
Rtp.AjaxForm.prototype = {
	fireEvent: function(event) {
		Ext.each(this.listeners, function(l) {
			if (l.event == event) {
				l.handler.apply(this);
			}
		}, this);
	},
	getField: function(name, returnEl) {
		var fn = returnEl !== false ? 'get' : 'getDom';
		return Ext[fn]('ajax-form-field-'+this.id+'-'+name);
	},
	getFieldContainer: function(name) {
		var field = this.getField(name);
		if (!field) return null;
		var ct = field.findParent('.ajax-form-field-wrap', 10, true);
		return ct;
	},
	getFieldInvalidMsgEl: function(name) {
		var ct = this.getFieldContainer(name);
		if (!ct) return null;
		var el = ct.child('.ajax-form-field-invalid-msg');
		return el;
	},
	fieldSetDisplayed: function(name, displayed) {
		var ct = this.getFieldContainer(name);
		if (ct) ct.setDisplayed(displayed);
	},
	registerStateField: function(stateFieldName, countryFieldName) {
		this.onCountryChange(stateFieldName, countryFieldName);
		var value = this.state_initial_values[stateFieldName];
		var stateField = this.getField(stateFieldName);
		stateField.dom.value = value;
		var countryField = this.getField(countryFieldName);
		Ext.EventManager.addListener(countryField.dom, 'change', function() {
			this.onCountryChange(stateFieldName, countryFieldName);
		}, this);
	},
	onCountryChange: function(stateFieldName, countryFieldName) {
		var countryField = this.getField(countryFieldName);
		var stateCt = this.getFieldContainer(stateFieldName);
		var country_id = countryField.dom.value;
		var hasStates = typeof this.country_states[country_id] != 'undefined';
		stateCt.setDisplayed(hasStates);
		var stateField = this.getField(stateFieldName);
		while (stateField.dom.options.length > 0) {
			stateField.dom.remove(0);
		}
		if (hasStates) {
			this.addSelectOption(stateField.dom, '', t('Select state'));
			var states = this.country_states[country_id];
			for (var state_id in states) {
				this.addSelectOption(stateField.dom, state_id, states[state_id]);
			}
		}
	},
	addSelectOption: function(select, value, text) {
		var option = document.createElement('option');
		option.value = value;
		option.text = text;
		try {
			select.add(option, null);
		} catch (e) {
			select.add(option);
		}
	},
	mask: function(msg) {
		if (!this.maskEl) {
			this.maskEl = this.form.createChild({tag: 'div', cls: 'ajax-form-mask'});
			this.maskMsgEl = this.form.createChild({tag: 'div', cls: 'ajax-form-mask-msg'});
		}
		this.maskEl.show();
		this.maskMsgEl.update(msg);
		this.maskMsgEl.show();
		this.maskMsgEl.setLeft((this.maskEl.getWidth() - this.maskMsgEl.getWidth()) / 2);
		this.maskMsgEl.setTop((this.maskEl.getHeight() - this.maskMsgEl.getHeight()) / 2);
	},
	unmask: function() {
		this.maskEl.hide();
		this.maskMsgEl.hide();
	},
	getValues: function() {
		var params = {}, item, key, value;
		for (var i = 0; i < this.form.dom.elements.length; i++) {
			item = this.form.dom.elements[i];
			key = item.name;
			if (!key) continue;
			if (item.tagName == 'INPUT' && item.type == 'checkbox') {
				if (key.match(/\[\]$/)) {
					if (item.checked) {
						if (!params[key]) params[key] = [];
						params[key].push(item.value);
					}
				} else {
					params[key] = item.checked ? '1' : '';
				}
			} else if (item.tagName == 'INPUT' && item.type == 'radio') {
				if (item.checked) {
					params[key] = item.value;
				}
			} else {
				params[key] = item.value;
			}
		}
		return params;
	},
	submit: function(e) {
	    e.stopEvent();
	    this.fireEvent('submit');
        this.hideMsg();
		this.clearInvalid();
		this.mask(this.submit_wait_msg);
		var params = this.getValues();
		if (typeof this.submit_params == 'object') Ext.apply(params, this.submit_params);
		Rtp.request({
			url: this.submit_url,
			params: params,
			failure: this.submitFailure,
			success: this.submitSuccess,
			scope: this
		});
	},
	submitFailure: function(result) {
	    this.unmask();
		if (result.msg) {
			this.showMsg(result.msg, true);
		}
		if (result.errors instanceof Array) {
			Ext.each(result.errors, function(error) {
				this.markInvalid(error.id, error.msg);
			}, this);
			if (!result.msg && this.disable_invalid_msg !== true) {
				this.showMsg(t('Some of the fields were not valid. Please correct them.'), true);
			}
		}
		this.fireEvent('submitfailure');
	},
	submitSuccess: function(result) {
	    if (this.reset_on_success) {
			this.reset();
		}
		if (this.hide_on_success) {
			this.hideForm();
		}
		if (this.success_msg) {
			this.showMsg(this.success_msg);
			this.unmask();
		} else if (this.success_url) {
			document.location.href = this.success_url;
		} else if (this.success_js) {
			this.unmask();
			eval(this.success_js);
		} else if (result.success_url) {
			document.location.href = result.success_url;
		} else if (result.success_msg) {
			this.showMsg(result.success_msg);
			this.unmask();
		} else {
			document.location.href = document.location.href;
		}
		this.fireEvent('submitsuccess');
	},
	markInvalid: function(name, msg) {
		var el = this.getFieldInvalidMsgEl(name);
		if (!el) return;
		el.update(msg);
		el.show();
	},
	clearInvalid: function(name) {
		var els = this.form.select('.ajax-form-field-invalid-msg');
		els.each(function(el) {
			el.setDisplayed(false);
		}, this);
	},
	showMsg: function(msg, error) {
		if (!this.msgEl) this.msgEl = Ext.get('ajax-form-msg-'+this.id);
		if (error) this.msgEl.addClass('ajax-form-msg-error');
		else this.msgEl.removeClass('ajax-form-msg-error');
		this.msgEl.update(msg);
		this.msgEl.show();
		this.msgEl.scrollIntoView();
	},
	hideMsg: function() {
		if (!this.msgEl) return;
		this.msgEl.setDisplayed(false);
	},
	hideForm: function() {
		this.form.setDisplayed(false);
	},
	reset: function() {
		this.form.dom.reset();
	},
	getRadioGroupValue: function(name) {
		var value = null;
		Ext.each(this.form.dom[name], function(el) {
			if (el.checked) {
				value = el.value;
				return false;
			}
		});
		return value;
	}
};
