(function($){
	
	var defaults = {
		prefix: 'auth_',
		authInClass: 'auth_in',
		path: '/auth/',
		status: 'unauthorized',
		targets: {
			waitajax: '.ws_waitajax'
		},
		hideinprocess: {
			registration: true,
			authorization: true,
			modify: true,
			remind: true
		}
	}
	
	$.fn.wsAuth = function (options, callbacks) {
		$.fn.wsAuth.data = {}
		obj = new wsAuth(this, options, callbacks, $.fn.wsAuth.data);	

		return this;
	};
	
	
	
	function wsAuth(el, options, callbacks, global) {
		var $this = this
		
		this.init = function(el, options, callbacks){
			
			
			this.options = $.extend({}, defaults, options);
			this.callbacks = callbacks || {};
			
			if(this.options.status=='authorized')	$('body').addClass($this.options.authInClass)
			global.status = this.options.status;
			
			if (!el.length) {
				if (el.selector === '') {
					try {console.log('Обработчик пустого селектора недоступен')} catch (e) {}
				} else {
					try {console.log('empty')} catch (e) {}
					return
				}
			}
			
			
			this.container = el;
			
			$this.remindForm = this.options.targets.remindForm || el.find('form[name="remindForm"]')
			
			if($this.remindForm.length > 0){
				$this.remindForm.submit($this.remindFormSubmit)
			}
			
			var form = this.options.targets.authForm || el.find('form[name="auth"]')
			if (form.length > 0) {
				this.authForm = form	
				this.authForm.submit(this.authFormSubmit)
				el.find('.ws_enter').click(function(){
					$this.update_form.hide();
					$this.registration_form.hide();
					$this.remindForm.hide();
					$this.authForm.show();
					return false;
				})
				el.find('.ws_remind').click(function(){
					$this.update_form.hide();
					$this.registration_form.hide();
					$this.authForm.hide();
					$this.remindForm.show();
					return false;
				})
			}

			var update_form = this.options.targets.updateForm || el.find('form[name="update"]')
			this.update_form = $('');
			if (update_form.length > 0) {
				this.update_form = update_form	
				this.update_form.submit(this.updateFormSubmit)
			}
			
			var registration_form = this.options.targets.registrationForm || el.find('form[name=registration]')
			if(registration_form.length > 0){


				this.registration_form = registration_form

				this.registration_form.submit($this.registrationSubmit)

				el.find('.ws_registration').click(function(){
					$this.update_form.hide();
					$this.authForm.hide();
					$this.remindForm.hide();
					$this.registration_form.show();
				})
				
			}


			
			var log_in = this.options.targets.authBlock || el.find('#log_in')
			if (log_in.length > 0) {this.log_in = log_in}

			var authorized = this.options.targets.authorizedBlock || el.find('#authorized')
			if (authorized.length > 0) {
				this.authorized = authorized
				authorized.find('a.ws_exit').click(function(){$this.logout();return false;})
				authorized.find('a.ws_login').click(function(){$this.updateFormInit();})
			}
		
			if(this.options.data) global.info = $this.data = this.options.data 
		
			var waitajax = $(this.options.targets.waitajax, el).hide()
			if (waitajax.length > 0) {
				this.waitajax = waitajax;
			}
			
			if(this.options.status=='authorized'){
				this.authInAction(data);
			}

			$($this.container).trigger('init')
		
		}
		
		this.authFormSubmit = function(){
			var error = {};
			
			if ($this.options.hideinprocess.authorization) {
				$this.authForm.hide();
				$this.waitajax.show();
			}
			
			if($(this).find('input[name="'+$this.options.prefix+'login"]').val()=='') error.login = 'empty'
			if($(this).find('input[name="'+$this.options.prefix+'password"]').val()=='') error.password = 'empty'

			if (error.login || error.password) {
				if ($this.options.hideinprocess.authorization) {
					$this.waitajax.hide();
					$this.authForm.show();
				}
				$($this.container).trigger('validateError', error)
				return false;
			}

			var data = $(this).serialize();
			
			$($this.container).trigger('authStart')
			$.ajax({
				url: $this.options.path,
				cache: false,
				dataType: 'json',
				data: data,
				success: function(data){
					$($this.container).trigger('authEnd');
			  		if(data['_status']=='need_authorization'){
						if ($this.options.hideinprocess.authorization)$this.waitajax.hide();
						$($this.container).trigger('authError', data.error_type)
					}else if(data['id']){
						global.status = 'authorized';
						global.info = $this.data = data
						$this.authInAction(data)
					}
					if ($this.options.hideinprocess.authorization) $this.waitajax.hide();
					
				},
				error: function(XMLHttpRequest, textStatus, errorThrown){
					$($this.container).trigger('authRequestFail', [XMLHttpRequest, textStatus, errorThrown]);
					if ($this.options.hideinprocess.authorization) {
						$this.authForm.show();
						$this.waitajax.hide();
					}
				}
			});

			return false;
		}
		
		this.authInAction = function(data){
			$('body').addClass($this.options.authInClass);
			$($this.log_in).hide();
			$($this.authorized).show().find('a.ws_login').text(data['login']);
			$($this.authForm).hide();
			$($this.container).trigger('authSuccess', data);
		}

		this.updateFormInit = function(){
			$($this.update_form).show()
			for(param in $this.data){
				var param_el = $('input[name='+param+'],' + ' textarea[name='+param+']',$this.update_form);
				if(param_el.length>0){
					param_el.val($this.data[param])
				}
				$('input[name=password],input[name=password2]',$this.update_form).val('******')
			}
		}
		
		this.updateFormSubmit = function(){

			if ($this.options.hideinprocess.modify) {
				$this.update_form.hide();
				$this.waitajax.show();
			}

			if ($this.callbacks.validateUpdateForm && !$this.callbacks.validateUpdateForm($this.update_form)) {
				if ($this.options.hideinprocess.modify) {
					$this.update_form.show();
					$this.waitajax.hide();
				}
				return false
			}

			
			var data = $(this).serialize();
			$($this.container).trigger('updateStart');
			$.ajax({
				url: $this.options.path,
				cache: false,
				dataType: 'json',
				data: data,
				type: 'post',
				success: function(data){
					$($this.container).trigger('updateEnd');
			  		if(data['_status']=='success'){
						$.ajax({
							url: $this.options.path,
							cache: false,
							dataType: 'json',
							success: function(data){
								$this.update_form.hide()
								global.info = $this.data = data
								if ($this.options.hideinprocess.modify) {
									$this.update_form.hide();
									$this.waitajax.hide();
								}
								$($this.container).trigger('updateSuccess')
							}
						})
					}else {
						$($this.container).trigger('updateError', data.error_type);
					}
				},
				error: function(XMLHttpRequest, textStatus, errorThrown){
					if ($this.options.hideinprocess.modify) {
						$this.update_form.show();
						$this.waitajax.hide();
					}
					$($this.container).trigger('updateRequestFail', [XMLHttpRequest, textStatus, errorThrown]);
				}
			});

			return false;
			
		}
		
		this.registrationSubmit = function(){

			if ($this.options.hideinprocess.registration) {
				$this.registration_form.hide();
				$this.waitajax.show();
			}

			if ($this.callbacks.validateRegistrationForm && !$this.callbacks.validateRegistrationForm($this.registration_form)) {
				if ($this.options.hideinprocess.registration) {
					$this.registration_form.show();
					$this.waitajax.hide();
				}
				return false;
			}
			
			var data = $(this).serialize();
			$($this.container).trigger('registrationStart');
			
			
			var data = $(this).serialize();
			$($this.container).trigger('updateStart');
			$.ajax({
				url: $this.options.path,
				cache: false,
				dataType: 'json',
				data: data,
				type: 'post',
				success: function(data){
					$($this.container).trigger('registrationEnd');

					if (data['_status'] == 'success') {
						global.status = 'authorized';
						global.info = $this.data = data;
						$this.registration_form.hide();
						if ($this.options.hideinprocess.registration) {
							$this.registration_form.hide();
							$this.waitajax.hide();
						}
						$($this.container).trigger('registrationSuccess');
//						$this.authInAction(data);
					} else if (data['_status'] == 'error') {
						var _errors = [];
						for(var i = 0;i < data.errors.length;i++){
							if(data.errors[i]['login_empty']) _errors.push('Логин пустой');
							if(data.errors[i]['login_error']) _errors.push('Логин уже занят или невалиден');
							if(data.errors[i]['password_empty']) _errors.push('Пароль пустой');
							if(data.errors[i]['password_error']) _errors.push('Пароли не совпадают');
						}
						if ($this.options.hideinprocess.registration) {
							$this.registration_form.show();
							$this.waitajax.hide();
						}
						$($this.container).trigger('registrationError', [_errors]);
					} else if (data['_status'] == 'wrong_captcha'){
						var _errors = [];
						_errors.push('Символы с картинки введены не верно')
						if ($this.options.hideinprocess.registration) {
							$this.registration_form.show();
							$this.waitajax.hide();
						}
						$($this.container).trigger('registrationError', [_errors]);
					}

				},
				error: function(XMLHttpRequest, textStatus, errorThrown){
					if ($this.options.hideinprocess.registration) {
						$this.registration_form.show();
						$this.waitajax.hide();
					}
					$($this.container).trigger('registrationRequestFail', [XMLHttpRequest, textStatus, errorThrown]);
				}
			});

			return false;



		}
		
		this.logout = function(){
			$.ajax({
				url: $this.options.path,
				cache: false,
				dataType: 'json',
				data: 'action=' + $this.options.prefix + 'logout',
				type: 'post',
				success: function(data){
			  		if(data['_status']=='need_authorization'){
						global.status = 'unauthorized';
						global.info = {};
						$($this.log_in).show();
						$($this.authorized).hide();
						$($this.update_form).hide();
						$('body').removeClass($this.options.authInClass);
						$($this.container).trigger('logOut');
					}else {
						try {console.log('logout fail')} catch (e) {}
					}
				},
				error: function(XMLHttpRequest, textStatus, errorThrown){
					try {console.log('logout request fail')} catch (e) {}
				}
			});
			
			return false;
		}

		this.remindFormSubmit = function(){
			if(!$this.remindForm.find('input[name=login]').val() && !$this.remindForm.find('input[name=email]').val()){
				alert('Необходимо ввести логин или E-mail.');
				return false;
			}

			if ($this.options.hideinprocess.remind) {
				$this.remindForm.hide();
				$this.waitajax.show();
			}

			
			var data = $(this).serialize();
			$($this.container).trigger('remindStart');
			$.ajax({
				url: $this.options.path,
				cache: false,
				dataType: 'json',
				data: data,
				type: 'post',
				success: function(data){
		
					$($this.container).trigger('remindEnd');

					if (data['_status'] == 'success') {
						alert('Пароль выслан вам на почту.');
						$($this.container).trigger('remindSuccess');
					} else if (data['_status'] == 'not_found') {
						alert('Пользователь не найден.');
						if ($this.options.hideinprocess.remind) {
							$this.remindForm.show();
							$this.waitajax.hide();
						}
					} else if (data['_status'] == 'form') {
						alert('Произошла ошибка, обратитесь к системному администратору.');
					}
					if ($this.options.hideinprocess.modify) {
						$this.update_form.hide();
						$this.waitajax.hide();
					}

				},
				error: function(XMLHttpRequest, textStatus, errorThrown){
					alert('Произошла ошибка, попробуйте позднее.');
					if ($this.options.hideinprocess.remind) {
						$this.remindForm.show();
						$this.waitajax.hide();
					}
					$($this.container).trigger('remindRequestFail', [XMLHttpRequest, textStatus, errorThrown]);
				}
			});
			
			
			return false;
		}

		this.init(el, options, callbacks);
	} 


	
}(jQuery))






