    jQuery(document).ready(function($){

        var parentSidebarID =  $('.nfp-woocommerce-widget:first').data('parent-sidebar-id'),
            parentDiv = $('.nfp-woocommerce-widget:first').parents('.nfp-sidebar-menu').length > 0 ? $('.nfp-woocommerce-widget:first').parents('.nfp-sidebar-menu') : $('.nfp-woocommerce-widget:first').parent();
        parentDiv.addClass('nfp-sidebar-menu').attr('data-sidebar-id',parentSidebarID),
        productsClass = typeof nfpVars.products_class != 'undefined' && nfpVars.products_class ? '.'+nfpVars.products_class : '.products' ,
        PaginationClass = typeof nfpVars.paginatioin_class != 'undefined' && nfpVars.paginatioin_class ? nfpVars.paginatioin_class : 'woocommerce-pagination' ;



        function nfpfilter_get_currbase(Href){
            if(typeof Href === "undefined" || Href == null){
                var Href = window.location.href;
            }

            var $currUrlBase = Href.split('?'),
                $Base = $currUrlBase[0]
            return $Base;
        }

        $(document).on('change','.nfp_price_input',function(){
            var $newVal = {},
                $goBtn = $(this).siblings('.nfp-price-go'),
                $currUrl = $goBtn.attr('href'),
                $currUrlBase = $currUrl.split('?'),
                $Base = $currUrlBase[0],
                $Params = {};

            $Params['nfpmin_price'] = $('.nfp_min_price').val();
            $Params['nfpmax_price'] = $('.nfp_max_price').val();

            var newUrl = nfp_update_url($Params);
            $goBtn.attr('href',$Base+'?'+newUrl);
        });


        function nfp_update_url($params,$currUrlParams){
            /*
             * queryParameters -> handles the query string parameters
             * queryString -> the query string without the fist '?' character
             * re -> the regular expression
             * m -> holds the string matching the regular expression
             */
            var queryParameters = {},
                queryString = location.search.substring(1),
                re = /([^&=]+)=([^&]*)/g, m;
            // Creates a map with the query string parameters
            while (m = re.exec(queryString)) {
                queryParameters[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
            }



            jQuery.each( $params, function( key, value ) {

    // Add new parameters or update existing ones
                //  queryParameters['newParameter'] = 'new parameter';
                //  queryParameters['existingParameter'] = 'new value';
                if(value == ''){
                    delete queryParameters[key];
                }else{
                    queryParameters[key] = value;
                }

            });

            /*
             * Replace the query portion of the URL.
             * jQuery.param() -> create a serialized representation of an array or
             *     object, suitable for use in a URL query string or Ajax request.
             */
          // location.search = $.param(queryParameters); // Causes page to reload

          var BaseUrl = nfpfilter_get_currbase();

          if( $.param(queryParameters).indexOf(BaseUrl) < 0) {
            return BaseUrl+'?'+$.param(queryParameters);
          }else{
            return $.param(queryParameters);
          }


        }

        $(document).on('click','.nfp-toogle-sidebar',function(e){
            $('div.nfp-sidebar-menu').slideToggle();
            e.preventDefault();
        });

        // search key press
        $(document).on('keydown','.nfpfilter-search-input', function(e) {
            if (e.which == 13) {
                e.preventDefault();
                var $newVal = {},
                    $currUrl = window.location.href,
                    $currUrlBase = $currUrl.split('?'),
                    $Base = $currUrlBase[0],
                    $ext = $currUrlBase[0].replace(nfpVars.base,''),
                    $Params = {};

                $Params['nfp_s'] = encodeURI($(".nfpfilter-search-input").val());

                var newUrl = nfp_update_url($Params),
                title = $('title').html();
                if(nfpVars.ajax == 'true'){
                    History.pushState(null,title,newUrl);

                    e.preventDefault();
                }else{
                    window.location = $currUrlBase[0]+'?'+newUrl;
                }
            }
        });



        // function to process per page dropdown
        function nfpFilterPerPage(This){
            var $currUrl = location.href,
                $currUrlBase = $currUrl.split('?'),
                $ext = $currUrlBase[0].replace(nfpVars.base,''),
                $Params = {};
            $Params['paged'] = 1;
            $Params['nfpper_page'] = This.val();
            var newUrl = nfp_update_url($Params),
            title = $('title').html();

            if(nfpVars.ajax == 'true'){
                History.pushState(null,title,newUrl);
            }else{
                window.location = $currUrlBase[0]+'?'+newUrl;
            }
        }
        $(document).on('change','#nfp-product-per-page',function(e){
            nfpFilterPerPage($(this));
            return false;
        });

        // function to process the orderby dropdown
        function nfpFilterOrderby(This,Param){
            var $currUrl = location.href,
                $currUrlBase = $currUrl.split('?'),
                $ext = $currUrlBase[0].replace(nfpVars.base,''),
                $Params = {};
            $Params[Param] = This.val();
            var newUrl = nfp_update_url($Params),
            title = $('title').html();

            History.pushState(null,title,newUrl);
            e.preventDefault();
        }



        if(nfpVars.ajax == 'true'){
            $('.woocommerce-ordering').attr('class','nfp-woocommerce-ordering');
            $(document).on('change','.woocommerce-ordering .orderby',function(e){
                nfpFilterOrderby($(this),'orderby');
                return false;
            });

            $(document).on('click','.woocommerce-pagination a',function(e){
                var url = $(this).attr('href'),
                    title = $('title').html(),
                    data = '';
                url = nfpFilterUrlExt(url);
                History.pushState(data,title,url);
                e.preventDefault();
            });
        }

        $(document).on('change','.nfp-woocommerce-ordering .orderby',function(e){
            nfpFilterOrderby($(this),'nfporderby');
            return false;
        });


        function nfpfilterGetParameterByName(name, url) {
            if (!url) {
                url = window.location.href;
            }
            name = name.replace(/[\[\]]/g, "\\$&");
            var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
                results = regex.exec(url);
            if (!results) return null;
            if (!results[2]) return '';
            return decodeURIComponent(results[2].replace(/\+/g, " "));
        }



        //ajax

        // get extension url
        function nfpFilterUrlExt(url){
            var $UrlExt = url.split('?');
            if(typeof $UrlExt[1] !== 'undefined' || $UrlExt[1] !== "^\\s+$" ){
                return '?' + $UrlExt[1];
            }
            return false;
        }

        $(document).on('click','.nfp-ajax-widget a,.nfp-ajax-widget .nfp-price-go',function(e){
            var url = $(this).attr('href'),
                title = $('title').html(),
                data = '';
            url = nfpFilterUrlExt(url);
            History.pushState(data,title,url);
            e.preventDefault();
        });

        History.Adapter.bind(window,'statechange',function(){
            var State = History.getState();
            nfpProceedAjax(State.url);
        });


        var $initialUrl = window.location.href;
        function nfpProceedAjax($link){
            $('.nfp-spinner-overlay').show();

           var NFPfilterproducts = $('#nfp-woocommerce-wrap.nfp-woocommerce-products');

            var $settings_per_page_dropdown = NFPfilterproducts.data('per_page_dropdown'),
                $settings_per_page = NFPfilterproducts.data('per_page'),
                $settings_orderby = NFPfilterproducts.data('orderby'),
                $settings_order = NFPfilterproducts.data('order'),
                $settings_columns = NFPfilterproducts.data('columns'),
                $settings_sorting = NFPfilterproducts.data('sorting'),
                $settings_result_count = NFPfilterproducts.data('result_count'),
                $exclude_out_of_stock = NFPfilterproducts.data('exclude-stockout'),
                $taxonomy_name = $('#nfpfilter-queried-object').length > 0 ? $('#nfpfilter-queried-object').data('taxonomy'): '',
                $taxonomy_slug = $('#nfpfilter-queried-object').length > 0 ? $('#nfpfilter-queried-object').data('slug'): '' ;
                $isArchive = $('#nfp-woocommerce-wrap .nfp-woocommerce-products').length > 0 ? "" : "archive";

            var data = {
                'action': 'nfpfilter_ajax',
                'link': $link,
                'initial_url' : $initialUrl,
                'settings_per_page_dropdown' : $settings_per_page_dropdown,
                'settings_per_page' : $settings_per_page,
                'settings_orderby' : $settings_orderby,
                'settings_order' : $settings_order,
                'settings_columns' : $settings_columns,
                'settings_sorting' : $settings_sorting,
                'settings_result_count' : $settings_result_count,
                'exclude_out_of_stock' : $exclude_out_of_stock,
                'sidebar_id' : $('.nfp-sidebar-menu').length > 0 ? $('.nfp-sidebar-menu').data('sidebar-id') : '',
                'sidebar_style' : $('.nfp-sidebar-menu').length > 0 ? $('.nfp-sidebar-menu').data('sidebar_style') : '',
                'is_archive' : $isArchive,
                'taxonomyName': $taxonomy_name,
                'taxonomySlug': $taxonomy_slug
            };



         jQuery.post(nfpVars.ajax_url, data, function(response) {
                var Products = $('<div>'+response+'</div>').find('#nfp-woocommerce-wrap');
                Products.find('.type-product').addClass('product');


                /*
                 * Insert products
                 * */

                var ProductsHTML = Products.find(productsClass).length > 0 ? Products.find(productsClass).html() : '';

                if( $('#nfp-woocommerce-wrap').length > 0){
                    $('#nfp-woocommerce-wrap ' + productsClass).html(ProductsHTML);
                }else{
                    $(productsClass+':last').html(ProductsHTML);
                }

                /*
                 * Insert result count
                 * */

                var resultCount = Products.find('.woocommerce-result-count').length < 1 ? '' : Products.find('.woocommerce-result-count').html();
                $('.woocommerce-result-count').html(resultCount);

                /*
                 * Insert pagination
                 * */

                if($('.'+PaginationClass).length < 1 ){  $('<nav class="'+PaginationClass+'"></nav>').insertAfter(productsClass);   }

                var $paginationHTML = Products.find('.'+PaginationClass).length < 1 ? '' :  Products.find('.'+PaginationClass).html();

                $('.'+PaginationClass).html($paginationHTML);

                $('.'+PaginationClass+' a').each(function(){
                    var Paged = nfpfilterGetParameterByName('paged',$(this).attr('href'));
                   var $Params = {};
                    $Params['paged'] = Paged;
                    var newUrl = nfp_update_url($Params);
                    $(this).attr('href',newUrl);
                });

                /*
                * Insert widgets
                * */

               if( $('.nfp-sidebar-menu').length > 0){
                   var Sidebar = $('<div>'+response+'</div>').find('.nfp-sidebar-menu');
                   $('.nfp-woocommerce-widget').hide(); // all filter plus widgets
                   Sidebar.find('.nfpfilter-inside-widget').each(function(){
                       var thisWidget = $(this).attr('data-id');

                       if($('.'+thisWidget).length > 0){

                           $('.nfp-sidebar-menu').find('.'+thisWidget).html($(this).html());

                           $('.nfp-sidebar-menu').find('.'+thisWidget).parents('.nfp-woocommerce-widget:first').show();
                       }else{
                           $('.nfp-woocommerce-widget:last').after('<div class="'+$('.nfp-woocommerce-widget:last').attr('class')+'" data-parent-sidebar-id="'+$('.nfp-woocommerce-widget:last').attr('data-parent-sidebar-id')+'">'+$(this).parents('.nfp-woocommerce-widget').html()+'</div>');
                           $('.nfp-woocommerce-widget:last').show();
                       }
                   });
               }

                if(Products.find('.nfpfilter-stockout-products').length > 0){
                    $('.nfpfilter-stockout-products').html(Products.find('.nfpfilter-stockout-products').html());
                }

                // reload ajax file
                 if(typeof nfpVars.ajax_refresh != "undefined"){
                       $.getScript(nfpVars.ajax_refresh);
                    }
                nfpfilter_stockout_update();
               $('.nfp-spinner-overlay').hide();
           });



             /* // second type ajax based on full url, can be used later
            $.ajax({
                url: $link,
                dataType: "html",
                method: "get",
                cache: false,
                success: function (data) {
                    var Content = $('<div>' + data + '</div>');
                    if($('.nfp-sidebar-header').length < 1){
                        var $widgets = $('<div>' + data + '</div>').find('.nfp-ajax-widget');
                        var $sidebar = $('.nfp-ajax-widget:first').parent();
                        $('.nfp-ajax-widget').remove();
                        $sidebar.append($widgets);
                    }else if($('.nfp-sidebar-header').length > 0){
                        $('.nfp-sidebar-header').html(Content.find('.nfp-sidebar-header').html());
                    }

                    Content.find('.nfp-sidebar-menu').attr('class',$('.nfp-sidebar-menu').attr('class'));
                    if($('.nfp-sidebar-header').is(':visible')){
                        Content.find('.nfp-sidebar-header').show();
                    }else{
                        Content.find('.nfp-sidebar-header').hide();
                    }

                    if(typeof nfpVars.customSelector != "undefined"){
                        $(nfpVars.customSelector).html(Content.find(nfpVars.customSelector).html());
                    }else{
                        $('.products').parent().html(Content.find('.products').parent().html());
                    }

                    if(typeof nfpVars.ajax_refresh != "undefined"){
                       $.getScript(nfpVars.ajax_refresh);
                    }

                    $('.nfp-spinner-overlay').hide();
                },
                error: function(xhr, textStatus, errorThrown){
                    //something went wrong
                    $('.nfp-spinner-overlay').hide();
                }
            });
        */

        }


        // stockout products
        nfpfilter_stockout_update();
        function nfpfilter_stockout_update(){
            $('.nfpfilter-stockout-products-input').each(function(){
                $('.post-'+$(this).val()).addClass('stockout').append('<div class="stockout-text">'+$(this).attr('data-text')+'</div>');
            });
        }


        // widget resize
        function nfpfilterResizeWidget(){
            if($('.nfp-sidebar-header').length > 0){
                $('.nfp-sidebar-header .nfp-sidebar-menu').attr('class','nfp-sidebar-menu'); // reset class
                $('.nfp-sidebar-header .nfp-sidebar-menu').each(function(){
                    var ThisWidth = $(this).parent().width();
                    if(ThisWidth >= 980){
                        $(this).addClass('column-4');
                    }else if(ThisWidth >= 480){
                        $(this).addClass('column-2');
                    }else if(ThisWidth < 480){
                        $(this).addClass('column-1');
                    }
                });
            }
        }

        nfpfilterResizeWidget();
        var rtime;
        var timeout = false;
        var delta = 200;
        $(window).resize(function() {
            rtime = new Date();
            if (timeout === false) {
                timeout = true;
                setTimeout(resizeend, delta);
            }
        });

        function resizeend() {
            if (new Date() - rtime < delta) {
                setTimeout(resizeend, delta);
            } else {
                timeout = false;
                nfpfilterResizeWidget();
            }
        }

        // show more popup
        $(document).on('click','.nfpfilter-show-more-toggle',function(){
             $(this).toggleClass('open').next('.nfpfilter-option-fold').toggleClass('nfpfilter-popup-open');
        });

    });