$=jQuery;

(function( $ ){
	
    /* Add csrf token */
    
    /* options: url: url to post, loading: dom id, success: func, pre_callback, separated_data:boolean */
    
	$.fn.ajaxList = function (name_list, options) 
	{
        if(!options.hasOwnProperty(loading))  {
            
            $(loading).show();
            
        }
        
        table_base='<table class="table_list" id="'+name_list+'"> \
        </table>';
        
        // <tr id="'+name_list+'_row_list" class="row_list" style="display: none;"> \
        //    </tr> 
        
        $(this).html(table_base);
        
        //Connect with ajax. 
        if(!options.hasOwnProperty("url"))  {
            

            list_tr='<tr class="title_list"> \
            <td>No ajax url defined</td> \
            </tr>';

            
            
            $(this).children('#'+name_list).append(list_tr);
            
            $(loading).hide();
            
            return false;
            
        }
        
        if(!$(this).attr('id'))  {
            
            console.log('You need an id for the table');
            
            return false;
            
        }
        
        exclude_list=[];
        
        if(options.hasOwnProperty("exclude_list"))  {
            
            exclude_list=options.exclude_list;
            
        }

        this.order_field=0;
        this.order=0;
        
        arr_icon=['<i class="fa fa-arrow-down asc_icon" aria-hidden="true"></i>', '<i class="fa fa-arrow-up desc_icon" aria-hidden="true"></i>'];
        
        var func=this;
        
        this.updateAjax=function (name_list, options, position) {
        
            // Get ajax, the ajax request need give a json request with name titles and fields value. 
            
            $('#'+name_list).html('');    
            
            $('.pages').remove();
            
            $('.link_pages').off();
            $('.change_order').off();
            
            extra_data={}
            
            if(options.hasOwnProperty("extra_data"))  {
                
                extra_data=options.extra_data;
                
            }
            
            data={position: position, order_field: func.order_field, order: func.order};
            
            for(i in extra_data) {
                
                data[i]=extra_data[i];
                
            }
            
            var block_name=$('#'+name_list).parent();
            
            $.ajax({
                type: 'POST',
                url: options.url,
                data: data,
                success: function (data) {
                    
                    order_field='';
                    
                    list_tr='<tr class="title_list">';
                    
                    for(i in data.fields)
                    {
                        
                        if(data.fields[i][1])
                        {
                        
                            list_tr+='<td><a href="#'+i+'" class="change_order" id="field_list_'+i+'">'+data.fields[i][0]+'</a></td>';
                            
                        }
                        else
                        {

                            list_tr+='<td>'+data.fields[i][0]+'</td>';
                            
                        }
                        
                    }

                    list_tr+='</tr>';
                    
                    $('#'+name_list).append(list_tr);
                    
                    list_tr='';
                    
                    for(i in data.rows)
                    {

                        list_tr+='<tr class="row_list">';

                        for(n in data.rows[i]) {

                            
                            if(exclude_list.indexOf(n)==-1)
                            {
                                
                                list_tr+='<td class="'+n+'_td">'+data.rows[i][n]+'</td>';
                                
                            }
                        }
                        
                        list_tr+='</tr>';                    
                        
                    }
                    $('#'+name_list).append(list_tr);

                    block_name.prepend('<p class="pages">'+data.html_pages+'</p>');                    
                    block_name.append('<p class="pages">'+data.html_pages+'</p>');
                    
                    // Prepare defaults of fields orders
                    

                    $('#field_list_'+func.order_field).append(' '+arr_icon[func.order]);
                    
                    // Prepare button events
                    
                    $('.link_pages').click(function (e) {
                        
                        e.preventDefault();
                    
                        position=parseInt($(this).attr('href').replace('#?begin_page=', ''));                    
                        
                        if(isNaN(position))
                        {
                            
                            position=0;
                            
                        }
                        
                        
                        func.updateAjax(name_list, options, position);       
                        
                        
                        
                    });
                    
                    $('.change_order').click(function (e) {
                    
                        e.preventDefault();
                        
                        func.order_field=$(this).attr('href').replace('#', '');
                        
                        //alert($(this).children('i').attr('class'));

                        if($(this).children('i').hasClass('asc_icon'))
                        {

                            func.order=1;

                        }
                        else
                        {

                            func.order=0;
                            
                        }
                        
                        func.updateAjax(name_list, options, position);       
                    
                    });
                    
                    if(options.hasOwnProperty("after_list"))  {
                
                        after_list=options.after_list;
                        
                        after_list();
                        
                    }
                    
                    
                },
                error: function (data) {
                    console.log('Cannot connect to list source');
                },
                dataType: 'json'
            });
        
        };
        
        this.updateAjax(name_list, options, 0, '');
        
        $(loading).hide();
        
        return this;
    }

})( jQuery );

(function( $ ){
	
    /* Add csrf token */
    
    /* options: url: url to get urls, loading: dom id, success: func, pre_callback, separated_data:boolean */
    
	$.fn.ajaxListSimple = function (fields, options) {
        
        
        //console.log($(this).find('tr.row_list').attr('class'));
        
        begin_page=0;
        
        order_field='';
        
        search_all=false;
        
        search_all_text='';
        
        search_fields=[];
        
        activate=0;
        
        num_items_default=20;
        
        //order ASC=0, DESC=1
        
        order=0;
        
        order_by={};
        
        if(options.hasOwnProperty("search_all"))  {
            
            search_all=options.search_all;
            
        }
        
        if(!options.hasOwnProperty("url"))  {
            

            list_tr='<tr class="row_list"> \
            <td colspan="'+fields.length+'" align="center">No ajax url defined</td> \
            </tr>';

            $(this).append(list_tr);
            
            return false;
            
        }
        
        list_tr='<tr class="row_list loading_cells"> \
            <td colspan="'+fields.length+'" align="center"><i class="fa fa-refresh fa-spin fa-3x fa-fw"></i><span class="sr-only">Loading...</span></td> \
            </tr>';
        
        /*$(this).append(list_tr);*/
        
        arr_num_items=[0, 10, 20, 50, 100];
        
        if(!options.hasOwnProperty("num_elements"))  {
            
            options.num_elements=20;
            
        }
        
        if(!options.hasOwnProperty("initial_num_pages"))  {
            
            options.initial_num_pages=20;
            
        }
        
        if(!options.hasOwnProperty("order_fields"))  {
            
            options.order_fields=[];
            
        }
        else {
            
            order_field=options.order_fields[0];
            
        }
        
        this.fields=fields;
        
        this.options=options;
        
        this.css_class='link_pages';
        
        //Prepare search
        
        for(i in options.order_fields) {
            
            field=options.order_fields[i];
            
            
            field_pos=this.fields.indexOf(field);
            
            if(field_pos!=-1) {
            
                 html_ele='<a href="#" class="change_order" data-field="'+field+'">'+$(this).find('tr:first-child').children().eq(field_pos).html()+'</a> &nbsp;<span id="flag_down_'+field+'" class="order_flag fa fa-caret-square-o-down" style="display:none;"></span><span id="flag_up_'+field+'" class="order_flag fa fa-caret-square-o-up" style="display:none;"></span>';
                 
                 $(this).find('tr:first-child').children().eq(field_pos).html(html_ele);
                 
                 if(field==order_field) {
                     
                     $(this).find('tr:first-child').children().eq(field_pos).find('.fa-caret-square-o-down').show();
                     
                 }
                 
                 order_by[field]=1;
                 
            }
                
        }
        
        order_by[order_field]=0;
        
        this.updateAjaxList=function () {
            
            //Stop other updateAjaxList if activate. 
            
            if(activate) {
                
                return false;
                
            }
            
            
            options=this.options;
            
            /*if(options.hasOwnProperty("loading")) {
     
                $(options.loading).show();
                
            }*/
            
            if(options.hasOwnProperty("pre_callback")) {
                
                options.pre_callback(this);
                
            }
            
            $(this).find('tr.row_list').remove();
            
            $(this).append(list_tr);
            
            options.num_elements=$('#'+$(this).attr('id')+'_number_of_items').val();
            
            //In url you can send, begin_page, num_elements for pagination. 
            
            
            $.ajax({
                url: options.url,
                type: 'GET',
                data:  {num_elements: options.num_elements, begin_page: begin_page, order_field: order_field, order: order, search_all_text: search_all_text},
                table: this,
                success: function (data) {
                    
                    $(this.table).find('tr.row_list').remove();

                    //$(this.table).find('.loading_cells').remove();

                    //$(options.loading).hide();
                    
                    //console.log(table.options);

                    if(!data.error) {
                        
                        var z=0;
                        
                        for (const row of data.items) {
                          //console.log(element);
                          
                            tr=this.table.append('<tr class="row_list" id="row_ajaxlist_'+z+'"></tr>');
                            
                            //for (const property in row) {
                            for (const field of this.table.fields) {
                                
                                //console.log(`${property}: ${row[property]}`);
                                
                                var field_name=row[field];
                                
                                $('#row_ajaxlist_'+z).append('<td>'+field_name+'</td>');
                              
                              
                            }
                            
                            z++;
                          
                        }
                        
                        if(data.hasOwnProperty('total_num_items')) {
                            
                            var total_elements=data.total_num_items;
                            
                            var num_elements=options.num_elements;
                            
                            var link=options.url;
                            
                            var initial_num_pages=options.initial_num_pages;
                            
                            var variable='begin_page';
                            
                            var label='';
                            
                            var func_jscript='';
                            
                            var pages=pagination( begin_page, total_elements, num_elements, link ,initial_num_pages, variable, label, func_jscript, this.table.css_class);
                            
                            $('#table_pages').remove();
                            
                            this.table.after('<div id="table_pages"><p>Pages: '+pages+'</p></div>');
                            
                        }

                        if(options.hasOwnProperty("success")) {
                            
                            options.success(data);
                            
                        }
                        

                    }
                    else {

                        if(options.hasOwnProperty("error_data")) {
                            
                            options.error_data(data);
                            
                        }

                    }
                    
                    if(search_all) {
                        
                        //Add input event to search when search is done 
                    
                        //var search_input='#'+$(this.table).attr('id')+'_search_in_table';
                        
                        //$(search_input).on('input', {table: this.table}, update_list_search);
                        
                    }
                    
                    activate=0;
                    

                },
                error: function (data) {

                    //$(options.loading).hide();
                    $(this).find('.loading_cells').remove();
                    
                    alert('Error: '+data.status+' '+data.statusText);
                    
                    activate=0;

                },
                dataType: 'json'
            });
            
            
            
        };
        
        //Pages click method for change page
        
        $(document).on('click', '.'+this.css_class, {table: this}, function (e) {
        
            console.log('Changing page...');
            
            begin_page=$(this).attr('data-begin');
            
            //Update list getting begin_page variable
            
            e.data.table.updateAjaxList();
            
            return false;
        
        });
        
        //Method for change order in page
        
        $(document).on('click', '.change_order',  {table: this}, function (e) {
        
            console.log('Changing order list...');
            
            field=$(this).attr('data-field');
            
            begin_page=0;
            
            //Clean order_flag icons
            
            $('.order_flag').hide();
            
            //Reset other fields not selected
            
            Object.entries(order_by).forEach(([key, value]) => {
                
                if(key!=field) {
                    
                    order_by[key]=1;
                    
                }
                
            });
            
            //Change order and showing flags from selected field
            
            if(order_by[field]==1) {
                
                order_by[field]=0;
                order=order_by[field];
                $('#flag_down_'+field).show();
                
            }
            else {
                
                order_by[field]=1;
                order=order_by[field];
                $('#flag_up_'+field).show();
                
            }
            
            //Set order_field with selected field
            
            order_field=field;
            
            //Update list getting order_field variable
            
            e.data.table.updateAjaxList();
            
            return false;
        
        });
        
        //For search in all fields
        
        if(search_all) {

            console.log('Search all...')
            
            $('<p class=""><label for="'+$(this).attr('id')+'_search_in_table">Search:</label> <input type="search" id="'+$(this).attr('id')+'_search_in_table" placeholder="Search in all fields"/> &nbsp;<label for="'+$(this).attr('id')+'_num_items_in_table">Num. of items:</label> <select name="'+$(this).attr('id')+'_num_elements" id="'+$(this).attr('id')+'_number_of_items"><option value="0">All</option> <option value="10">10</option> <option value="20">20</option> <option value="50">50</option> <option value="100">100</option></select></p>').insertBefore($(this));
            //console.log($(this).attr('id'));
            
            var index=arr_num_items.indexOf(options.num_elements);
        
            if(index!=-1) {
                
                //console.log(index);
                //'+$(this).attr('id')+'_number_of_items
                
                $('#'+$(this).attr('id')+'_number_of_items option:eq('+index+')').prop('selected', true);
                
            }
            
            $('#'+$(this).attr('id')+'_number_of_items').on('change', {table: this}, function (e) {
                
                begin_page=0;
            
                e.data.table.updateAjaxList();
                
                e.preventDefault();
                
                return false;
            
            });
            
            //$(form).find(".input_performance").on('keyup', function (e) {
            
            function update_list_search(e) {
                
                //e.stopPropagation();
                
                //var search_input='#'+$(e.data.table).attr('id')+'_search_in_table';
                
                //$(search_input).off();
                
                search_all_text=$(this).val();
                
                e.data.table.updateAjaxList();
                
                e.preventDefault();
                
                return false;
            }
            
            $('#'+$(this).attr('id')+'_search_in_table').on('input', {table: this}, update_list_search);
        }
        
        //First loading of list
        
        this.updateAjaxList();
        
        return this;
        
    }
    
    

})( jQuery );

//begin_page, int: number of first element showed in table


function pagination( begin_page, total_elements, num_elements, link ,initial_num_pages, variable, label, func_jscript, css_class) {
    
    
        pages='';

        if(begin_page>total_elements) {
            
            begin_page=0;
        }

        // Calculamos el total de todas las páginas

        total_page=Math.ceil(total_elements/num_elements);
        
        // Calculamos en que página nos encontramos

        actual_page=Math.ceil(begin_page/num_elements);

        // Calculamos el total de intervalos

        total_interval=Math.ceil(total_page/initial_num_pages);

        // Calculamos el intervalo en el que estamos

        actual_interval=Math.floor(actual_page/initial_num_pages);

        //Calculamos el elemento de inicio del intervalo

        initial_page=Math.ceil(actual_interval*initial_num_pages*num_elements);

        last_page=Math.ceil(actual_interval*initial_num_pages*num_elements)+Math.ceil(initial_num_pages*num_elements);

        if (last_page>total_elements) {
                
            last_page=total_elements;
                
        }
        
        //url_base=new URL(link);
    
        if(initial_page>0) {
            
            //initial_link=add_get_parameters(link, **{variable: '0'});
            
            initial_url=new URL(link);
            initial_url.searchParams.append(variable, '0');
            
            initial_link=initial_url.href;
            
            //middle_link=add_get_parameters(link, **{variable: str((initial_page-num_elements)) } );
            middle_url=new URL(link);
            
            begin_page=(initial_page-num_elements);
            
            middle_url.searchParams.append(variable, begin_page);
            
            middle_link=middle_url.href;
            
            pages += "<a class=\""+css_class+"\" href=\""+initial_link+"\" onclick=\"${func_jscript}\" data-begin=\"0\">1</a> <a class=\""+css_class+"\" href=\""+middle_link+"\" data-begin=\""+begin_page+"\">&lt;&lt;</a> "
            
        }
        
        arr_pages={};

        for(x=initial_page;x<last_page;x+=num_elements) {

            var middle_url=new URL(link);
            
            middle_url.searchParams.append(variable, x);
            
            middle_link=middle_url.href;
            

            num_page=Math.ceil(x/num_elements)+1;
            arr_pages[x]="<a class=\""+css_class+"\" href=\""+middle_link+"\" data-begin=\""+x+"\">"+num_page+"</a> ";
            arr_pages[begin_page]='<span class="selected_page">'+num_page+'</span> ';
            pages+=arr_pages[x];
        }
        
        if (last_page<total_elements) {

            middle_url=new URL(link);
            middle_url.searchParams.append(variable, (initial_page-num_elements));
            
            middle_link=middle_url.href;
            
            //last_link=add_get_parameters(link, **{variable: str( ( ( total_page*num_elements ) - num_elements) ) } )
            
            last_url=new URL(link);
            last_url.searchParams.append(variable, ( ( total_page*num_elements ) - num_elements) );
            
            last_link=last_url.href;

            pages += "<a class=\""+css_class+"\" href=\""+middle_link+"\" onclick=\"\">&gt;&gt;</a> <a class=\"link_pages\" href=\""+last_link+"\" onclick=\"\">Last</a>";

        }
        
        
        return pages;
    
}
