(function($){

	$.fn.jCustomerEditForm = function(o){
		var defaults = {
			ajaxSubmit			: false,
			baseUrl				: null,
			complexForm			: null,
			onSave				: null,
			deleteDefaultAddress: false,
			loadingStyle		: "default",
			htmlAddress			: {},
			addresses			: {},
			limit				: {b : 2, s : 2},
			msgFillDefault		: _T('Fill default billing'),
			msgBillingLimit		: _T('You riched billings limit'),
			msgShippingLimit	: _T('You riched shippings limit')
		};
		var options = $.extend(defaults, o || {});
		
		var userAddresses = options.addresses;
		
		function _getType($td){
			if ($td.hasClass('js-primary-address')) return 'p';
			if ($td.hasClass('js-billing-addresses')) return 'b';
			if ($td.hasClass('js-shipping-addresses')) return 's';
			return '';
		}
		
		function _getCount($td){
			return $td.find('> .js-address-item').size();
		}
		
		function _getLastID($ul){
			var result = 0;
			$ul.find('> .js-address-item:last [name^="address["]:eq(2)').each(function(){
				var arr = this.name.split('[');
				if (arr && arr.length == 4) result = parseInt(arr[3]);
			});
			return result;
		}
		
		function _isFixedInput(el){
			if ($(el).attr('name').indexOf('[Default]') > 0) return true;
			//if ($(el).attr('name').indexOf('[Same]') > 0) return true;
			return false;
		}
		
		function _initInputs($address, id, data, type){
			if (!data) data = null;
			$address.find(':input[name^="address["]').each(function(){
				if (_isFixedInput(this)) return;
				var name = $(this).attr('name').replace(/[\[\]]/g, '-');
				var $error = $address.find('#'+name+'-error');
				var $empty = $address.find('#'+name+'-empty');
				if ($error.size())
					$error.attr('id', $error.attr('id').replace('-error', '')+'-'+id+'--error');
				if ($empty.size())
					$empty.attr('id', $empty.attr('id').replace('-empty', '')+'-'+id+'--empty');
				$(this).attr('name', $(this).attr('name')+'['+id+']');
			});
			$address.find('input[name$="[Default]"]').val(id);
			if (parseInt(id) == 1 && !data){
				$address.find('input[name$="[Default]"]').attr('checked', true).change();
				$address.find('.js-delete-btn').hide();
			}
			if (data && data.Default){
				$address.find('input[name$="[Default]"]').attr('checked', true).change();
				$address.find('.js-delete-btn').hide();
			}
		}
		
		function _copyComplex($edit, $info, type){
			$edit.find(':input[name^="address["]').each(function(){
				var name = $(this).attr('name').substr(11), value = '';
				name = name.substr(0, name.indexOf(']') );
				if (name == 'CountryCode'){
					name = 'Country';
					value = $(this).find('option:selected').text();
				} else {
					value = $(this).val();
				}
				$info.find('span.js-field-'+name).text(value);
			});
			var phone = '', fax = '';
			$edit.find(':input[name^="address['+type+'][Phone"]').each(function(){
				if (phone != '') phone += '-';
				phone += $(this).val();
			});
			$edit.find(':input[name^="address['+type+'][Fax"]').each(function(){
				if (fax != '') fax += '-';
				fax += $(this).val();
			});
			if (/^\d+\-\-$/.test(phone)) phone = '';
			if (/^\d+\-\-$/.test(fax)) fax = '';
			$info.find('.js-field-Phone').text(phone);
			$info.find('.js-field-Fax').text(fax);
		}
		
		function _getAddressId(el){
			var id = 0;
			$(el).find(':input[name*="[Street]"]:first').each(function(){
				var name = $(this).attr('name').substr("address[a][Street][".length);
				id = name.substr(0, name.length - 1);
				if (/[bps]{1}/.test(id.substr(-1))) id = 0;
			});
			return id;
		}
		
		function _initComplex(el, type){
			if (!options.baseUrl){
				showError('baseUrl is not defined');
				return false;
			}
			
			var $edit = $(el).find('.js-edit'), $info = $(el).find('.js-info');
			
			_copyComplex($edit, $info, type);
			
			$info.find('a[href$="#edit"]').unbind('click').click(function(){
				$info.hide();
				$edit.show();
				return false;
			});
			
			$edit.find('a[href$="#save"]').unbind('click').click(function(){
				var cID = $(el).parents('li:first').attr('value'), id = _getAddressId(el);
				$edit.ketchup({
					validationAttribute : 'rel',
					validateHidden : false,
					onValidate : function(res){
						if (!res) return false;
						$(el).showLoading({style : options.loadingStyle});
						$.post(options.baseUrl+'/address', $edit.getFields({ajax : 1, customer_id : cID, id : id}), function(res){
							$(el).hideLoading();
							if (res.result){
								_copyComplex($edit, $info, type);
								if (res.id && !id){
									$edit.find(':input[name^="address["]').each(function(){
										var arr = $(this).attr('name').split('][');
										if (arr.length == 3){
											$(this).attr('name', arr[0]+']['+arr[1]+']['+parseInt(arr[2], 10)+']');
										}
									});
								}
								$edit.hide();
								$info.show();
							} else {
								if (res.msg) showError(res.msg);
							}
						}, 'json');

					}
				});
				return false;
			});
			
			$(el).find('a[href$="#delete"]').unbind('click').click(function(){
				if ($(this).parents('.js-address-list:first').find('.js-address-item').size() <= 1){
					showError(_T('Cant delete last address'));
					return false;
				}
				askQuestion(_T('Delete address?'), function(res){
					if (!res) return false;
					var id = _getAddressId(el);
					if (!id){
						$edit.parents('.js-address-item:first').remove();
						return false;
					}
					$(el).showLoading({style : options.loadingStyle});
					$.post(options.baseUrl+'/address', {"delete" : 1, ajax : 1, id : _getAddressId(el)}, function(res){
						$(el).hideLoading();
						if (res.result){
							$edit.parents('.js-address-item:first').remove();
						} else {
							if (res.msg) showError(res.msg);
						}
					}, 'json');
				});
				return false;
			});
		}
		
		function _addAddress($ul, data, hideAdd){
			var type = _getType($ul), id = _getLastID($ul) + 1;;
			if (!data){
				data = null;
				id += type;
			} else if (data.id){
				id = data.id;
			}
			if (!hideAdd) hideAdd = false;
			if (type == '') return false;
			if (type != 'p' && _getCount($ul) >= options.limit[type]){
				showError(type == 'b' ? options.msgBillingLimit : options.msgShippingLimit);
				return false;
			}
			var $address = $(options.htmlAddress[type]);
			var complex = $address.find('.js-info').size() == 1 && $address.find('.js-edit').size() == 1;
			if (data){
				$address.find('.js-hint-input').removeClass('js-hint-input ui-hint-input');
				for (var key in data){
					if (key != 'Same')
						$address.find('[name="address['+type+']['+key+']"]').val(data[key]);
					if (key == 'Same' && parseInt(data[key]) > 0){
						$address.find('[name="address['+type+']['+key+']"]').attr('checked', true).change();
					}
				}
			}
			_initInputs($address, id, data, type, complex);
			if (complex){
				_initComplex($address, type);
				if (data){
					$address.find('.js-edit').hide();
					$address.find('.js-info').show();
				} else {
					$address.find('.js-info').hide();
					$address.find('.js-edit').show();
				}
			}
			if (data){
				$address.find('[name="address['+type+'][Default]"]').attr('checked', data['Default'] ? true : false);
			}
			if (hideAdd) $address.find('.js-last-row').hide();
			if (!options.deleteDefaultAddress && data && data['Default'] && data['Default'] == '1') $address.find('a[href$="#delete"]').remove();
			
			$address.appendTo($ul);
			$.jQueryUI($address);
			$.jQueryUI($address.parents('form:first').parent(), 'validate');
			_initAddressActions($address);
			return true;
		}
		
		function _getDefaultAddress(el, type){
			if (!type) type = 's';
			var $form = $(el).parents('form:first');
			if (type == 's')
				return $form.find('.js-billing-addresses:first input[name$="[Default]"]:checked')
					.parents('.js-address-item:first');
			return $form.find('.js-primary-address .js-address-item:first');
		}
		
		function _copyDefaultAddress($li, silent){
			if (!silent) silent = false;
			silent = true; // Silent is always TRUE because of very long loop of validations.			
			var $list = $li.parents('.js-address-list:first'), type = _getType($list),
				$ditem = _getDefaultAddress($li, type), success = true;
			$ditem.find('[rel^="validate("]').each(function(){
				if (!$.fn.ketchup.validateField($(this))){
					success = false;
					return false;
				}
			});
			if (!success){
				showMessage(options.msgFillDefault);
				return false;
			}
			$ditem.find('[name^="address["]').each(function(){
				if (_isFixedInput(this)) return;
				var arr = this.name.split('[');
				if (arr && arr.length == 4){
					var name = arr[2].replace(']','');
					var $inp = $li.find('[name^="address['+type+']['+name+']"]').val($(this).val());
					if (!silent) $inp.click().change();
				}
			});
			return true;
		}
		
		function _updateSame(el, silent){
			if (!silent) silent = false;
			var type = _getType($(el).parents('.js-address-list'));
			$(el).parents('.js-addresses-container').find('input[name^="address['+type+'][Same]"]:checked').each(function(){
				_copyDefaultAddress($(this).parents('.js-address-item'), silent);
			});
		}
		
		function _initForm($form){
			$form.find('a[href$="#pwd"]').unbind('click').click(function(){
				$(this).hide();
				$form.find('.js-reset-password').show();
				$form.find('input[name="password"]').focus();
				return false;
			});
			
			$form.find('input[name="setpwd"]').unbind('click').click(function(){
				if (!options.baseUrl){
					showError('baseUrl is not defined');
					return false;
				}
				var $pwd = $form.find('input[name="password"]');
				if (!$.fn.ketchup.validateField($pwd)){
					if ($.fn.ketchup.messages.password)
						showError($.fn.ketchup.messages.password)
					else
						showError(_T('Incorrect field.password'));
					return false;
				}
				var $li = $form.parents('li:first');
				$form.showLoading({style : options.loadingStyle});
				$.post(options.baseUrl+'/pwd', {ajax : 1, password : $pwd.val(), id : $li.attr('value')}, function(res){
					$pwd.val('');
					$form.hideLoading();
					if (res.result){
						$form.find('.js-reset-password').hide();
						$form.find('a[href$="#pwd"]').show();
					} else {
						if (res.msg) showError(res.msg);
					}
				}, 'json');
				return false;
			});
		}
		
		function _initAddresses($form){
			if (Object.size(userAddresses)){
				var $ul = null;
				for (type in userAddresses){
					var css = '', i = 0;
					if (type == 'p') css = '.js-primary-address';
					if (type == 'b') css = '.js-billing-addresses';
					if (type == 's') css = '.js-shipping-addresses';
					if (css == '') continue;
					$ul = $form.find(css);
					for (pos in userAddresses[type]){
						_addAddress($ul, userAddresses[type][pos], ++i < Object.size(userAddresses[type]));
					}
				}
				$form.find('input[name^="address[s][Same]"], input[name^="address[b][Same]"]').change();
			} else {
				var $ul = $form.find('.js-primary-address');
				if ($ul.size()){
					if (!_getCount($ul)) _addAddress($ul);
				}

				var $ul = $form.find('.js-billing-addresses');
				if (!_getCount($ul)) _addAddress($ul);
				if (!$ul.find('.js-address-item input[name="address[b][Default]"]:checked').size()){
					$ul.find('.js-address-item:first input[name="address[b][Default]"]').attr('checked', true);
				}
				$ul = $form.find('.js-shipping-addresses');
				if (!_getCount($ul)) _addAddress($ul);
				if (!$ul.find('.js-address-item input[name="address[s][Default]"]:checked').size()){
					$ul.find('.js-address-item:first input[name="address[s][Default]"]').attr('checked', true);
				}
				$.jQueryUI($form.parent(), 'validate');
			}
		}
		
		function _initAddressActions($form){
			$form.find('a[href$="#add"]').unbind('click').click(function(){
				var $td = $(this).parents('.js-address-list:first');
				if (_addAddress($td)){
					$(this).parents('.js-last-row').hide();
				}
				return false;
			});
			
			$form.find('.js-delete-btn').unbind('click').click(function(){
				var $list = $(this).parents('.js-address-list:first');
				$(this).parents('.js-address-item:first').remove();
				$list.find('.js-address-item:last .js-last-row').show();
				_initAddressActions($form);
				return false;
			});
			
			$form.find('input[name^="address[b][Same]"], input[name^="address[s][Same]"]').unbind('change').change(function(){
				var $li = $(this).parents('.js-address-item');
				if ($(this).is(':checked')){
					if (_copyDefaultAddress($li)){
						$li.find('input, select, textarea').blur();
						$li.find('input, select, textarea').attr('disabled', true);
						$li.find('input[name$="[Default]"], input[name^="address[b][Same]"], input[name^="address[s][Same]"]').attr('disabled', false);
					} else $(this).attr('checked', false);
				} else {
					$li.find('input, select, textarea').attr('disabled', false);
				}
			});
			
			$form.find('input[name$="[Default]"]').unbind('change').change(function(){
				var $li = $(this).parents('.js-address-item');
				$li.parents('.js-address-list').find('.js-delete-btn').show();
				$li.find('.js-delete-btn').hide();
				_updateSame(this);
			});
			
			function _initCountry(el){
				var $li = $(el).parents('.js-address-item:first');
				var $option = $(el).find('option:selected');
				var $zip = $li.find('input[name*="[Zip]"]');
				var $code = $li.find('input[name*="[Phone_0]"], input[name*="[Fax_0]"]');
				$zip.attr('rel', parseInt($option.attr('zip')) > 0 ? 'validate(required,zip)' : 'validate(zip)');
				if ($option.attr('phone')) $code.val($option.attr('phone').replace('+', ''));
				return $zip;
			}
			
			// Country select box.
			$form.find('select[name*="[CountryCode]"]').each(function(){
				_initCountry(this);
			}).unbind('change').change(function(){
				_initCountry(this).blur();
			});
			
			$form.find('[name^="address[p]"], [name^="address[b]"]').blur(function(){
				var $li = $(this).parents('.js-address-item:first');
				if (!$li.find('input[name*="[Default]"]:checked').size()) return;
				_updateSame(this, true);
			});
		}
		
		return this.each(function(){
			var $form = $(this);
			
			if (this.tagName == 'FORM'){
				$form.submit(function(){
					$form.find('.js-hint-input').trigger('hideHint');
					
					if (options.ajaxSubmit){
						if (typeof $.fn.ketchup == 'function'){
							if (!$.fn.ketchup.isValid($form)) return false;
						}
						$form.showLoading({style : options.loadingStyle});
						$.post($form.attr('action'), $form.getFields({ajax : 1}), function(res){
							$form.hideLoading();
							if (res.result){
							} else {
								if (res.msg) showError(res.msg);
							}
							if (typeof options.onSave == 'function') options.onSave.call($form.get(0), res);
						}, "json")
						return false;
					}
				});
			} else if (typeof options.onSave == 'function') options.onSave.call($form.get(0));
			
			$form.find('input[name="is_complex_discount"]').change(function(){
				var $div = $(this).parent().find('.js-complex-box').toggle();
				if ($(this).attr('checked')) {
					$div.show();
					$form.find('input[name="discount"]').attr('disabled', true);
				} else {
					$div.hide();
					$form.find('input[name="discount"]').attr('disabled', false);
				}
			}).change();
			
			_initForm($form);
			
			_initAddresses($form);
			
			_initAddressActions($form);
			
		});
	}

})(jQuery)

