/* --------------------------------------------------------------
 datatable_custom_pagination.js 2016-06-20
 Gambio GmbH
 http://www.gambio.de
 Copyright (c) 2016 Gambio GmbH
 Released under the GNU General Public License (Version 2)
 [http://www.gnu.org/licenses/gpl-2.0.html]
 --------------------------------------------------------------
 */

/**
 * ## Enable Custom DataTable Pagination
 *
 * This method will bind the appropriate event handlers to the HTML markup of the "datatables_page_length.html"
 * and the "datatables_page_navigation.html" templates. This module will also set a page parameter to the URL
 * on page change but will not parse it upon initialization. This must happen from the module that initializes
 * the table.
 *
 * ### Options
 *
 * **Page Navigation Selector | `data-datatable_custom_pagination-page-navigation-selector` | String | Optional**
 *
 * Provide a selector for the page navigation container element. This option defaults to ".page-navigation" which
 * is also the class of the datatable_page_navigation.html template.
 *
 * **Page Length Selector | `data-datatable_custom_pagination-page-length-selector` | String | Optional**
 *
 * Provide a selector for the page length container element. This option defaults to ".page-length" which
 * is also the class of the datatable_page_length.html template.
 *
 * ### Events
 *
 * ```javascript
 * // Add custom callback once the page is changed (DataTable "info" object contains the new page information).
 * $('#datatable-instance').on('datatable_custom_pagination:page_change', function(event, info) { ... });
 *
 * // Add custom callback once the page length is changed (new page length is provided as second argument).
 * $('#datatable-instance').on('datatable_custom_pagination:length_change', function(event, newPageLength) { ... });
 * ```
 *
 * @module Admin/Extensions/datatable_custom_pagination
 */
gx.extensions.module('datatable_custom_pagination', [], function (data) {

    'use strict';

    // ------------------------------------------------------------------------
    // VARIABLES
    // ------------------------------------------------------------------------

    /**
     * Module Selector
     *
     * @type {jQuery}
     */
    const $this = $(this);

    /**
     * Default Options
     *
     * @type {Object}
     */
    const defaults = {
        pageNavigationSelector: '.page-navigation',
        pageLengthSelector: '.page-length'
    };

    /**
     * Final Options
     *
     * @type {Object}
     */
    const options = $.extend(true, {}, defaults, data);

    /**
     * Page Navigation Selector
     *
     * @type {jQuery}
     */
    const $pageNavigation = $this.find(options.pageNavigationSelector);

    /**
     * Page Length Selector
     *
     * @type {jQuery}
     */
    const $pageLength = $this.find(options.pageLengthSelector);

    /**
     * Module Instance
     *
     * @type {Object}
     */
    const module = {};

    // ------------------------------------------------------------------------
    // FUNCTIONS
    // ------------------------------------------------------------------------

    /**
     * Update Page Navigation Elements
     *
     * Update the info text, set the correct button state and make sure the select box is up-to-date
     * with the current page.
     */
    function _onDataTableDraw() {
        const info = $this.DataTable().page.info();
        const text = $this.DataTable().i18n('sInfo')
            .replace('_START_', info.end !== 0 ? ++info.start : info.start)
            .replace('_END_', info.end)
            .replace('_TOTAL_', info.recordsDisplay);
        $pageNavigation.find('label').text(text);

        // Check if one of the buttons is disabled.
        $pageNavigation.find('.next').prop('disabled', (info.page === (info.pages - 1) || info.pages === 0));
        $pageNavigation.find('.previous').prop('disabled', (info.page === 0));

        // Fill in the pagination select box.
        const $select = $pageNavigation.find('select');

        $select.empty();

        for (let i = 1; i <= info.pages; i++) {
            $select.append(new Option(`${i} ${jse.core.lang.translate('from', 'admin_labels')} ${info.pages}`, i));
        }

        $select.val(info.page + 1);

        // Select the initial page length.
        $pageLength.find('select').val($this.DataTable().page.len());
    }

    /**
     * On Page Navigation Select Change Event
     */
    function _onPageNavigationSelectChange() {
        // Change the table page.
        $this.DataTable().page(Number($(this).val()) - 1).draw(false);

        // Trigger Event
        const info = $this.DataTable().page.info();
        $this.trigger('datatable_custom_pagination:page_change', [info]);
    }

    /**
     * On Page Navigation Button Click Event
     */
    function _onPageNavigationButtonClick() {
        // Change the table page.
        const direction = $(this).hasClass('next') ? 'next' : 'previous';
        $this.DataTable().page(direction).draw(false);

        // Trigger Event
        const info = $this.DataTable().page.info();
        $this.trigger('datatable_custom_pagination:page_change', [info]);
    }

    /**
     * On Page Length Select Change Event
     */
    function _onPageLengthSelectChange() {
        const newPageLength = Number($pageLength.find('select').val());
        $this.DataTable().page.len(newPageLength).page(0).draw(false);

        // Trigger Event
        $this.trigger('datatable_custom_pagination:length_change', [newPageLength]);
    }

    // ------------------------------------------------------------------------
    // INITIALIZATION
    // ------------------------------------------------------------------------

    module.init = function (done) {
        $this
            .on('draw.dt', _onDataTableDraw);

        $pageNavigation
            .on('change', 'select', _onPageNavigationSelectChange)
            .on('click', 'button', _onPageNavigationButtonClick);

        $pageLength
            .on('change', 'select', _onPageLengthSelectChange);

        done();
    };

    return module;

});