+function ($) {
    'use strict';

    // инициализация функции плагина
    var Ajax = function(element, options) {
    	this.$element = $(element);
        this.options = $.extend({}, Ajax.DEFAULTS, options);
    };

    // параметры по умолчанию
    Ajax.DEFAULTS = {
        method: 'post',
        dataType: 'json',
        cache: false,
        header:{'X-TIJAX':true}
    };

    // прототип функции ajax запроса
    Ajax.prototype._ajax = function ($el, url, data, options) {
        $el.trigger('tiAjax:begin', [$el]);
        var newData = $el.triggerHandler('tiAjax:modify-data', data);
        if (newData) {
            data = newData;
        }

        var options = $.extend({}, Ajax.DEFAULTS, options);

        $.ajax({
            url: url,
            type: options.method,
            dataType: options.dataType,
            data: data,
            headers: options.header,
            cache: options.cache,
            statusCode: {
                200: function (responseData) {
                    if (!responseData) {
                        responseData = {};
                    }
                    $el.trigger('tiAjax:success', [$el, responseData]);
                },
                500: function () {
                    $el.trigger('tiAjax:error', [$el, 500]);
                },
                400: function () {
                    $el.trigger('tiAjax:error', [$el, 400]);
                },
                404: function () {
                    $el.trigger('tiAjax:error', [$el, 404]);
                }
            },
            complete: function (jqXHR, textStatus) {
                $(document).trigger('tiAjax:complete', [$el, jqXHR, textStatus]);
            }
        });
    };

    // прототип функци getData - получение значении data для элемента
    Ajax.prototype._getData = function($el) {
    	var data_str = $el.data('ajax-data'),
    		keyval = null,
    		data = null;
    	if (data_str) {
            data = {};
            data_str.split(',').map(
                function(pair) {
                    keyval = pair.split(':');
                    if (keyval[1].indexOf('#') === 0) {
                        data[keyval[0]] = $(keyval[1]).val();
                    } else {
                        data[keyval[0]] = keyval[1];
                    }
                }
            );
        }

    	return data;
    };

    // прототип функции click
    Ajax.prototype.click = function(e) {
    	e.preventDefault();

    	var $this = $(this),
    		url = $this.attr('href'),
    		data = Ajax.prototype._getData($this);

    	Ajax.prototype._ajax($this, url, data);
    };

    // прототип функции submit
    Ajax.prototype.submit = function(e) {
        var $this = $(this),
            url = $this.attr('action'),
            data = $this.serialize();

        if (!url) {
        	url = $this.data('ajax-url');
        }

        e.preventDefault();

        Ajax.prototype._ajax($this, url, data);

        return false;
    };

    // прототип функции addGroup - добавление Группы характеристик
    Ajax.prototype.addGroup = function(e) {
    	e.preventDefault();

    	var $this=$(this),
    		data = {title:$('#group_title').val(), func:'feature_add_group'},
    		url=$this.data('ajax-url');

    	Ajax.prototype._ajax($this, url, data);
    };

    // прототип функции addGroupAfter - обработка добавления группы характеристики
    Ajax.prototype.addGroupAfter = function(e, $el, response) {
		if (!response.error) {
			$('#group').append('<option value="' + response.data.id + '">'
					+ response.data.title + '</option>');
			$('#group :last').attr('selected', 'selected');
			$('#group').selectpicker('refresh');
			$('#features-add-group').removeClass('hidden');
			$('.group-select').removeClass('hidden');
			$('#group-add').addClass('hidden');
		}
    };

    // прототип функции tabs - поддержка hash навигации в tabs и pills навигации
    Ajax.prototype.tabs = function(e) {
    	var $this = $(this),
		href = $this.attr("href");
		if (href.indexOf("#") != -1) {
			location.hash = href;
		} else {
			window.location.href = $this.data("url");
		}
    };

    // прототип функции bind_all - организации выбора одного значения или всех
    Ajax.prototype.bindAll = function(e) {
   		var $this = $(this),
   			target = $($this.data('ajax-target'));

		if ($this.prop('checked')) {
			target.prop('disabled', true);
		} else {
			target.prop('disabled', false);
		}
    };

    // прототип функции delete - удаление записи в БД
    Ajax.prototype.del = function(e) {
    	e.preventDefault();

    	var $this = $(this),
			url = $this.attr('href'),
			data = Ajax.prototype._getData($this);

		BootstrapDialog.confirm('Удалить <strong>' + data.title
				+ '</strong>, вы уверены?', function(result)
		{
			if (result) {
				window.location.replace(url);
			}
		});
    };

    // прототип функции responseError - отображение ошибки выполнения
    Ajax.prototype.responseError = function(e) {
    	showNotification({
			type : 'error',
			message: LANG.AD_ERROR_OPERATION
		});
    };

    // прототип функции responseError - отображение успешного выполнения
    Ajax.prototype.responseSuccess = function(e, $el, response) {
    	if (response.notify) {
	    	showNotification({
				type:response.notify.type,
				message : response.notify.message
			});
    	}
    };

    // прототип функции changeCategory -  выбор категории материалов
    Ajax.prototype.changeCategory = function(e) {

    	var $this = $(this),
    		url = '/kartinki/ajax',
	        data = {func: $this.data('func'),category_id: $this.val(),item_id: $this.data('item_id')};

    	Ajax.prototype._ajax($this, url, data);
	};

	// прототип функции changeCategory -  обновление блока ответом
	Ajax.prototype.changeCategoryAfter = function(e, $el, response) {
		if (!response.error) {
			var box = $($el.data('update_box'));
			box.fadeOut('slow',function(){
				box.html(response.html);
				$('.selectpicker').selectpicker();
				box.fadeIn('slow');
				$el.trigger('tiAjax:update', [$el, response]);
			});
		}

		$("#cats :disabled").removeClass('disabled').prop('disabled',false);
		$('#cats [value=' + $el.val() + ']').addClass('disabled').prop('disabled','true');
	};


    // секция прототип фукции обработки результатов

    // прототип функции redirect - перенаправление на страницу
    Ajax.prototype.redirect = function(e, $el, response) {

    	var location = $el.data('ajax-redirect');

    	if (!location) {
    		location = response.location;
    	};

    	window.location.href = location;

    	return false;
    };

    // прототип функции replace - замена блока данными
    Ajax.prototype.replace = function(e, $el, response) {
    	var target = $el.data('ajax-replace'),
    		type = $el.data('ajax-type');

    	if (!target) {
    		target = response.target;
    	};

    	switch (type) {
    		case 'closest':
    			var box = $el.closest(target);
    			box.fadeOut('slow',function(){
    				box.replaceWith(response.html).fadeIn('slow');
    			});
    			break;

    		case 'inner':
    			var box = $(target);
    			box.fadeOut('slow', function(){
    				box.html(response.html).fadeIn('slow');
    			});
    			break;

    		case 'closest-inner':
    			var box = $el.closest(target);
    			box.fadeOut('slow', function(){
    				box.html(response.html).fadeIn('slow');
    			});
    			break;

    		default:
    			var box = $(target);
    			box.fadeOut('slow',function(){
    				box.replaceWith(response.html).fadeIn('slow');
    			});
    			break;
    	};
    };

    // прототип функции add -добавления данных в блок
    Ajax.prototype.add = function(e, $el, response) {
    	var target = $el.data('ajax-add'),
			type = $el.data('ajax-type');

    	if (!target) {
    		target = response.target;
    	}

    	switch (type) {
    		case 'append':
    			$(target).append(response.html);
    			break;

    		case 'prepend':
    			$(target).prepend(response.html);
    			break;

    		default:
    			return false;
    			break;
    	};
    };

    // прототип функции clear - очистки блока
    Ajax.prototype.clear = function(e, $el) {
    	var target = $el.data('ajax-clear'),
    		type = $el.data('ajax-type');

    	if (!target) {
    		return false;
    	}

    	switch (type) {
    		case 'closest':
    			$el.closest(target).html();
    		default:
    			$(target).html('');
    			break;
    	}


    };

    // прототип функции remove - удаления блока
    Ajax.prototype.remove = function(e, $el) {
    	var target = $el.data('ajax-remove'),
    		type = $el.data('ajax-type');

    	if (!target) {
    		return false;
    	}

    	switch (type) {
    		case 'closest':
    			$el.closest(target).remove();
    			break;
    		default:
    			$(target).remove();
    			break;
    	};

    };

    // прототип функции toggle - смена состояния
    Ajax.prototype.toggle = function(e, $el) {
    	var target = $el.data('ajax-toggle'),
    		active = $el.data('ajax-class');

    	if (!target) {
    		return false;
    	}

    	if (!active) {
    		active = 'active';
    	}

    	$(target).toggleClass(active);
    };

    // прототип функции debug - отладка
    Ajax.prototype.debug = function() {
    	console.log('work');
    };

    // прототип функции timeOut - выполнение обновление блока
    Ajax.prototype.timeout = function(i, element) {
        var $el = $(element),
            timeout = $el.data('ajax-timeout');

        window.setTimeout(Ajax.prototype.debug, timeout);
    };

    // прототип функции SetInterval - обновление блока через заданный интервал
    Ajax.prototype.interval = function(i, element) {
    	var $el = $(element),
    		interval = $el.data('ajax-interval');

	    window.setInterval(Ajax.prototype.debug, interval);
    };

    // определение функции плагина
    function Plugin(option) {
        return this.each(function() {
        	var $this = $(this);
        	var data = $this.data('ti.ajax');
        	var options = typeof option == 'object' && option;

        	if (!data) $this.data('ti.ajax', (data = new Ajax(this, options)));

        });
    };

    // реализация noConflict
    $.fn.Ajax = Plugin;
    $.fn.Ajax.Constructor = Ajax;

    // инициализация автоматических обновлении данных
    $(function () {
    	$('[data-ajax-interval]').each(Ajax.prototype.interval);
    	$('[data-ajax-timeout]').each(Ajax.prototype.timeout);

    });

    // инициализация событий плагина
    $(document)
    	.on('click.ti.ajax.data-api', '[data-ajax^="click"]', Ajax.prototype.click)
    	.on('click.ti.ajax.data-api', '[data-ajax^="add-group"]', Ajax.prototype.addGroup)
    	.on('submit.ti.ajax.data-api','[data-ajax^="submit"]', Ajax.prototype.submit)
    	.on('click.ti.ajax.data-api', '[data-ajax^="delete"]', Ajax.prototype.del)
    	.on('click.ti.ajax.data-api','.nav-tabs a[data-toggle]', Ajax.prototype.tabs)
    	.on('change.ti.ajax.data-api','[data-ajax^="bind-all"]', Ajax.prototype.bindAll)
    	.on('change.ti.ajax.data-api','[data-ajax^="change-category"]', Ajax.prototype.changeCategory)
    	.on('tiAjax:success','[data-ajax^="change-category"]', Ajax.prototype.changeCategoryAfter)
    	.on('tiAjax:success','[data-ajax-redirect]', Ajax.prototype.redirect)
    	.on('tiAjax:success','[data-ajax-toggle]', Ajax.prototype.toggle)
    	.on('tiAjax:success','[data-ajax-replace]', Ajax.prototype.replace)
    	.on('tiAjax:success','[data-ajax-add]', Ajax.prototype.add)
    	.on('tiAjax:success','[data-ajax-clear]', Ajax.prototype.clear)
    	.on('tiAjax:success','[data-ajax-remove]', Ajax.prototype.remove)
    	.on('tiAjax:success','[data-ajax^="add-group"]', Ajax.prototype.addGroupAfter)
    	.on('tiAjax:error', Ajax.prototype.responseError)
    	.on('tiAjax:success', Ajax.prototype.responseSuccess);;
}(jQuery);
