function FormManager($elt) {
	var self = this;
	self.$elt = $elt;

	self.Init = function () {
	    self.$elt.bind("FormSubmit", self.HandleFormSubmit);
	    self.$elt.submit(function (e) { return false; });
	    self.RegisterValidators();
	};

	self.HandleFormSubmit = function (e, url) {
	    e.stopImmediatePropagation();

	    if (self.request) {
	        self.PostAjax($(e.target));
	        return;
	    }

	    if (!self.Validator.form()) {
	        self.PostAjax($(e.target));
            self.Validator.showErrors();
	        return;
	    }
	    var controls = $elt.find('.js-control');
	    var packagedData = {};
	    controls.each(function (i, ele) {
	        var propName = $(ele).data('object').Name;
	        var value = $(ele).data('object').GetValue();
	        packagedData[propName] = value;
	    });

	    self.request = $.ajax({
	        url: url,
	        type: "post",
	        dataType: "json",
	        traditional: true,
	        data: packagedData,
	        success: function (data) { self.HandleSuccess(data, $(e.target)); },
	        error: function (data) { self.PostAjax($(e.target)); }
	    });

	};

	self.HandleSuccess = function (data, $trigger) {
	    self.request = undefined;
	    
	    if (data.RedirectUrl != null)
	        window.location = data.RedirectUrl;
	    else {
	        self.PostAjax($trigger);
            self.$elt.find('.js-message').remove();
	        self.$elt.prepend('<div class="js-message ui-message">' + data.Message + '</div>');
	    }
	};

	self.PostAjax = function ($elt) {
	    $elt.trigger('post-success');
    };

    self.Invalid = function (form, validator) {
        $('.js-control.error', form).trigger('invalid', validator)
    };

    self.RegisterValidators = function () {
        $.validator.addMethod("date", function (value, element) {
            return this.optional(element) || /^(?:\d{2}\.\d{2}\.\d{4}|\d{2}\/\d{2}\/\d{4}|\d{2}-\d{2}-\d{4})$/.test(value);
        }, "mm/dd/yyyy");

        $.validator.addMethod("tel", function (value, element) {
            return this.optional(element) || /^(?:\([2-9]\d{2}\)\ ?|[2-9]\d{2}(?:\-?|\ ?))[2-9]\d{2}[- ]?\d{4}$/.test(value);
        }, "(999)999-9999");

        self.Validator = self.$elt.validate({
            debug: true,
            highlight: function (element, errorClass) {
                $(element).trigger('invalid');
            },
            unhighlight: function (element, errorClass) {
                $(element).trigger('valid');
            }
        });
    };
};

$.fn.FormManager = function(elt) {
	$(this).each(function(i, ele) {
		var $elt = $(ele);
		if($elt.data('object')) return;
		$elt.data('object', new FormManager($elt));
		$elt.data('object').Init();
	});
	
	return this;
};

$(document).ready(function () {
    var index = 1;
    $('input,textarea,select').each(function (i, ele) {
        $(this).attr('tabindex', index);
        index++;
    });
});
