<commit_before>//Tool functions
//Todo copy it into library
function sort_unique(arr) {
    arr = arr.sort(function (a, b) { return a*1 - b*1; });
    var ret = [arr[0]];
    for (var i = 1; i < arr.length; i++) { 
        if (arr[i-1] !== arr[i]) {
            ret.push(arr[i]);
        }
    }
    return ret;
}



function generatePagesLinks(identifier, currentPage, currentSelection, nbPages){
    var pages = Array();
    // TODO put this constant in a javascript config file
    var threshold = 5;
    var result = '';
    
    // If nb pages to display > 25 we show only first pages, current selection page, and last pages links
    if( nbPages > 25 ){
        // TODO put the + 2 in a javascript config file
        for( var i = 1; i < Math.ceil(threshold) + 2; ++i) {
            if( i > 0 && i <= nbPages ){
                pages.push(i);
            }
        }
    } else { 
            for( var i=1; i<=nbPages ;++i){
                pages.push(i);
            }
    }
    
    // If we want to add focus on another variable we juste to add an entry in this array
    focusElements = Array();
    focusElements[0] = currentPage;
    //Just uncomment the next line to show 3 pages links around slider selection page
    // focusElements[1] = currentSelection;
    pages.push(currentSelection);
    // Hide too far pages algorithm
    for( var k = 0; k < focusElements.length; ++k){
        var currentCount = Math.ceil(threshold/2);
        for( var i = focusElements[k] - Math.ceil(threshold/2)  ; i < focusElements[k] ; ++i ){
            if( i > 0 && i <= nbPages ){
                currentCount--;
                pages.push(i);
            }
        }
        
        pages.push(focusElements[k]);
        var currentCount2 = Math.ceil(threshold/2);
        for( var i = focusElements[k] + 1 ; i < focusElements[k] + Math.ceil(threshold/2) +1 ; ++i ){
            if( i > 0 && i <= nbPages ){
                currentCount2--;
                pages.push(i);
            }
        }
        
        // Add missed before pages at the end of the array
        if( currentCount > 0 ){
            for(var i = focusElements[k] + Math.ceil(threshold/2); i < focusElements[k] + Math.ceil(threshold); ++i){
                if( i > 0 && i <= nbPages )
                    pages.push(i);
            }
        } else if( currentCount2 > 0){
            for(var i = focusElements[k] - Math.ceil(threshold); i < focusElements[k] + Math.ceil(threshold/2); ++i){
                if( i > 0 && i <= nbPages)
                    pages.push(i);
            }
        } 
    }
    
    for(var i = nbPages - Math.ceil(threshold) ; i <= nbPages; ++i){
        if( i > 0 && i <= nbPages){
            pages.push(i);
        }
    }
    pages=sort_unique(pages);
    var lastdisplayedValue = null;
    for(var i=0; i < pages.length; ++i){
        
        if( lastdisplayedValue != null && lastdisplayedValue != pages[i] - 1){
            result+= ".....";
        }
        result += "<a href='javascript:void(0)' onclick=\"javascript:tabs.getTabFromUniqueId( '" + identifier + "').goToPage(" + pages[i] + ");\" class='";
        
        if( pages[i] == currentPage ){
            result += "slider_link_current_page" ;
        } else if( pages[i] == currentSelection ){
            result += "slider_link_current_selection" ;
        } else {
            result += "slider_link" ;
        }
        result +=  "'>" + pages[i] +"</a> ";
        lastdisplayedValue = pages[i];
    }
    
    return result;
}

var SearchTab = Class.create(Tab, {
    initialize : function( server_results ){
        // Search parameters 
        this.identifier = server_results.identifier;
        this.updateNewSearchInformations(server_results);
    },

    updateNewSearchInformations : function( server_results ){
        // tab name 
        if( server_results.search_value == ''){
            this.name = "Library";
        } else if ( server_results.search_comparison == 'equal' && server_results.search_field == 'artist'){
            this.name = server_results.search_value;
        } else if ( server_results.search_comparison == 'equal' && server_results.search_field == 'album'){
            // TODO get the artist name not from the first result but with 
            if( server_results.results.length > 0 ) {
                // Caution it could generate errors
                this.name =  server_results.results[0].artist + " - " + server_results.search_value;
            } else {
                this.name = server_results.search_value;
            }
        } else {
            this.name =  server_results.search_value;
        }

        this.select_fields = server_results.select_fields;
        this.search_value = server_results.search_value;
        this.search_comparison = server_results.search_comparison ;
        this.search_field = server_results.search_field ;
        this.first_result = server_results.first_result;
        this.result_count = server_results.result_count;
        this.order_by = server_results.order_by;
        this.order_by_way = server_results.order_by_way;
        this.total_results = server_results.total_results;
        this.server_results = server_results.results;
    },
    
    // This function is used to add all pages search results in the playqueue
    // TODO add playqueue identifier to parameters
    addSearchToPlayQueue : function( play_queue_position ) {
        // Create the JSon request
        var action = new Object();
        action.name = "add_search_to_play_queue";
        action.play_queue_position = play_queue_position;
        action.select_fields = "mid" ;
        action.search_value = this.search_value ;
        action.search_comparison = this.search_comparison
        action.search_field = this.search_field ;
        action.order_by = this.order_by ;
        action.order_by_way = this.order_by_way;

        if( "like" == action.search_comparison ) {
            action.first_result = this.first_result;
            action.result_count = this.result_count;
        } else {
            action.first_result = 0;
            action.result_count = null;
        }
        
        // Send the query to the server
        query.action = action;
        updateJukebox();
    },

    goToPage : function (page) {
        doSearch((page - 1) * this.result_count,
                 this.identifier,
                 this.select_fields,
                 this.search_value, 
                 this.search_comparison, 
                 this.search_field, 
                 this.order_by,
                 this.order_by_way,
                 this.result_count);
    },

    updateContent : function( ){
        var search_page = '';

        /* Save in the current instance the targeted tags and needed informations */        
        $$('collection_pagelist_' + this.identifier).each(function(s) {
	        s.remove();
        });

        if( null != $('collection_content_' + this.identifier) ){
            $('collection_content_' + this.identifier).remove();
        }
        /* pre-init html structure */
        search_page += '<br/>';
        search_page += '<div class="collection_pagelist"';
        search_page += ' name="collection_pagelist_' + this.identifier + '"></div>';
        search_page += '<div id="collection_content_' + this.identifier + '"></div>';
        search_page += '<div class="collection_pagelist"';
        search_page += ' name="collection_pagelist_' + this.identifier + '"></div>';
        $('tabContent_' + this.identifier).update(search_page);

        // Display sliders and links and init sliders behvior
        this.initAndDisplaySearchControllers();

        // Display search results and init dragabble items
        this.initAndDisplaySearchResults();
    },

    /* Update sliders and pages*/
    initAndDisplaySearchControllers : function(){
        var pagelist_html = '';
        var pages = new Array();
        var resultsSlider = null;

        /* Sliders */
        var sliders = new Array();
        var locked = new Array();
        var pages = new Array();

        var page_count = 0;
        var current_page = 0;
        
        /* Gets the number of pages */
        page_count = Math.ceil((this.total_results / this.result_count));

        /* Gets the current page number */
        current_page = Math.ceil(this.first_result / this.result_count);
        if( current_page > page_count ) {
            current_page = 1;
        }

        /* Only display slider and pages results links if nb pages > 1 */
        if( this.total_results > 0 ){
            pagelist_html += '<p>'<commit_msg>Bug fix search results pages, the previous correction missed one case<commit_after>//Tool functions
//Todo copy it into library
function sort_unique(arr) {
    arr = arr.sort(function (a, b) { return a*1 - b*1; });
    var ret = [arr[0]];
    for (var i = 1; i < arr.length; i++) { 
        if (arr[i-1] !== arr[i]) {
            ret.push(arr[i]);
        }
    }
    return ret;
}



function generatePagesLinks(identifier, currentPage, currentSelection, nbPages){
    var pages = Array();
    // TODO put this constant in a javascript config file
    var threshold = 5;
    var result = '';
    
    // If nb pages to display > 25 we show only first pages, current selection page, and last pages links
    if( nbPages > 25 ){
        // TODO put the + 2 in a javascript config file
        for( var i = 1; i < Math.ceil(threshold) + 2; ++i) {
            if( i > 0 && i <= nbPages ){
                pages.push(i);
            }
        }
    } else { 
            for( var i=1; i<=nbPages ;++i){
                pages.push(i);
            }
    }
    
    // If we want to add focus on another variable we juste to add an entry in this array
    focusElements = Array();
    focusElements[0] = currentPage;
    //Just uncomment the next line to show 3 pages links around slider selection page
    // focusElements[1] = currentSelection;
    pages.push(currentSelection);
    // Hide too far pages algorithm
    for( var k = 0; k < focusElements.length; ++k){
        var currentCount = Math.ceil(threshold/2);
        for( var i = focusElements[k] - Math.ceil(threshold/2)  ; i < focusElements[k] ; ++i ){
            if( i > 0 && i <= nbPages ){
                currentCount--;
                pages.push(i);
            }
        }
        
        pages.push(focusElements[k]);
        var currentCount2 = Math.ceil(threshold/2);
        for( var i = focusElements[k] + 1 ; i < focusElements[k] + Math.ceil(threshold/2) +1 ; ++i ){
            if( i > 0 && i <= nbPages ){
                currentCount2--;
                pages.push(i);
            }
        }
        
        // Add missed before pages at the end of the array
        if( currentCount > 0 ){
            for(var i = focusElements[k] + Math.ceil(threshold/2); i < focusElements[k] + Math.ceil(threshold); ++i){
                if( i > 0 && i <= nbPages )
                    pages.push(i);
            }
        } else if( currentCount2 > 0){
            for(var i = focusElements[k] - Math.ceil(threshold); i < focusElements[k] + Math.ceil(threshold/2); ++i){
                if( i > 0 && i <= nbPages)
                    pages.push(i);
            }
        } 
    }
    
    for(var i = nbPages - Math.ceil(threshold) ; i <= nbPages; ++i){
        if( i > 0 && i <= nbPages){
            pages.push(i);
        }
    }
    pages=sort_unique(pages);
    var lastdisplayedValue = null;
    for(var i=0; i < pages.length; ++i){
        
        if( lastdisplayedValue != null && lastdisplayedValue != pages[i] - 1){
            result+= ".....";
        }
        result += "<a href='javascript:void(0)' onclick=\"javascript:tabs.getTabFromUniqueId( '" + identifier + "').goToPage(" + pages[i] + ");\" class='";
        
        if( pages[i] == currentPage ){
            result += "slider_link_current_page" ;
        } else if( pages[i] == currentSelection ){
            result += "slider_link_current_selection" ;
        } else {
            result += "slider_link" ;
        }
        result +=  "'>" + pages[i] +"</a> ";
        lastdisplayedValue = pages[i];
    }
    
    return result;
}

var SearchTab = Class.create(Tab, {
    initialize : function( server_results ){
        // Search parameters 
        this.identifier = server_results.identifier;
        this.updateNewSearchInformations(server_results);
    },

    updateNewSearchInformations : function( server_results ){
        // tab name 
        if( server_results.search_value == ''){
            this.name = "Library";
        } else if ( server_results.search_comparison == 'equal' && server_results.search_field == 'artist'){
            this.name = server_results.search_value;
        } else if ( server_results.search_comparison == 'equal' && server_results.search_field == 'album'){
            // TODO get the artist name not from the first result but with 
            if( server_results.results.length > 0 ) {
                // Caution it could generate errors
                this.name =  server_results.results[0].artist + " - " + server_results.search_value;
            } else {
                this.name = server_results.search_value;
            }
        } else {
            this.name =  server_results.search_value;
        }

        this.select_fields = server_results.select_fields;
        this.search_value = server_results.search_value;
        this.search_comparison = server_results.search_comparison ;
        this.search_field = server_results.search_field ;
        this.first_result = server_results.first_result;
        this.result_count = server_results.result_count;
        this.order_by = server_results.order_by;
        this.order_by_way = server_results.order_by_way;
        this.total_results = server_results.total_results;
        this.server_results = server_results.results;
    },
    
    // This function is used to add all pages search results in the playqueue
    // TODO add playqueue identifier to parameters
    addSearchToPlayQueue : function( play_queue_position ) {
        // Create the JSon request
        var action = new Object();
        action.name = "add_search_to_play_queue";
        action.play_queue_position = play_queue_position;
        action.select_fields = "mid" ;
        action.search_value = this.search_value ;
        action.search_comparison = this.search_comparison
        action.search_field = this.search_field ;
        action.order_by = this.order_by ;
        action.order_by_way = this.order_by_way;

        if( "like" == action.search_comparison ) {
            action.first_result = this.first_result;
            action.result_count = this.result_count;
        } else {
            action.first_result = 0;
            action.result_count = null;
        }
        
        // Send the query to the server
        query.action = action;
        updateJukebox();
    },

    goToPage : function (page) {
        doSearch((page - 1) * this.result_count,
                 this.identifier,
                 this.select_fields,
                 this.search_value, 
                 this.search_comparison, 
                 this.search_field, 
                 this.order_by,
                 this.order_by_way,
                 this.result_count);
    },

    updateContent : function( ){
        var search_page = '';

        /* Save in the current instance the targeted tags and needed informations */        
        $$('collection_pagelist_' + this.identifier).each(function(s) {
	        s.remove();
        });

        if( null != $('collection_content_' + this.identifier) ){
            $('collection_content_' + this.identifier).remove();
        }
        /* pre-init html structure */
        search_page += '<br/>';
        search_page += '<div class="collection_pagelist"';
        search_page += ' name="collection_pagelist_' + this.identifier + '"></div>';
        search_page += '<div id="collection_content_' + this.identifier + '"></div>';
        search_page += '<div class="collection_pagelist"';
        search_page += ' name="collection_pagelist_' + this.identifier + '"></div>';
        $('tabContent_' + this.identifier).update(search_page);

        // Display sliders and links and init sliders behvior
        this.initAndDisplaySearchControllers();

        // Display search results and init dragabble items
        this.initAndDisplaySearchResults();
    },

    /* Update sliders and pages*/
    initAndDisplaySearchControllers : function(){
        var pagelist_html = '';
        var pages = new Array();
        var resultsSlider = null;

        /* Sliders */
        var sliders = new Array();
        var locked = new Array();
        var pages = new Array();

        var page_count = 0;
        var current_page = 0;
        
        /* Gets the number of pages */
        page_count = Math.floor((this.total_results / this.result_count));
        if( this.total_results % this.result_count > 0  )
            page_count = page_count + 1;

        /* Gets the current page number */
        current_page = Math.floor(this.first_result / this.result_count)+1;
        if( current_page > page_count ) {
            current_page = 1;
        }

        /* Only display slider and pages results links if nb pages > 1 */
        if( this.total_results > 0 ){
            pagelist_html += '<p>'
{'fraction_non_alphanumeric': 0.11798883967094287, 'fraction_numerical': 0.005810274406028879, 'mean_word_length': 1.9484396200814111, 'pattern_counts': {'":': 0, '<': 55, '<?xml version=': 0, '>': 52, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5957932', 'n_tokens_mistral': 5038, 'n_tokens_neox': 4848, 'n_words': 1216}