/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 ONOS GUI -- Widget -- Table Service
 */
(function () {
    'use strict';

    // injected refs
    var $log, $window, fs, mast, is;

    // constants
    var tableIconTdSize = 33,
        pdg = 12,
        colWidth = 'col-width',
        tableIcon = 'table-icon',
        asc = 'asc',
        desc = 'desc',
        none = 'none';

    // internal state
    var currCol = {},
        prevCol = {},
        sortIconAPI;

    // Functions for creating a scrolling table body with fixed table header

    function _width(elem, width) {
        elem.style('width', width);
    }

    function defaultSize(table, width) {
        var thead = table.select('.table-header').select('table'),
            tbody = table.select('.table-body').select('table'),
            wpx = width + 'px';
        _width(thead, wpx);
        _width(tbody, wpx);
    }

    function adjustTable(table, width, height) {
        var thead = table.select('.table-header').select('table'),
            tbodyDiv = table.select('.table-body'),
            tbody = tbodyDiv.select('table'),
            cstmWidths = {};

        function findCstmWidths() {
            var headers = thead.selectAll('td');

            headers.each(function (d, i) {
                var h = d3.select(this),
                    index = i.toString();
                if (h.classed(tableIcon)) {
                    cstmWidths[index] = tableIconTdSize + 'px';
                }
                if (h.attr(colWidth)) {
                    cstmWidths[index] = h.attr(colWidth);
                }
            });
            $log.debug('Headers with custom widths: ', cstmWidths);
        }

        function setTdWidths(elem) {
            var tds = elem.selectAll('tr:not(.ignore-width)').selectAll('td');
            _width(elem, width + 'px');

            tds.each(function (d, i) {
                var td = d3.select(this),
                    index = i.toString();
                if (cstmWidths.hasOwnProperty(index)) {
                    _width(td, cstmWidths[index]);
                }
            });
        }

        function setHeight(body) {
            var h = height - (mast.mastHeight() +
                fs.noPxStyle(d3.select('.tabular-header'), 'height') +
                fs.noPxStyle(thead, 'height') + pdg);
            body.style('height', h + 'px');
        }

        findCstmWidths();
        setTdWidths(thead);
        setTdWidths(tbody);
        setHeight(tbodyDiv);

        cstmWidths = {};
    }

    // Functions for sorting table rows by header

    function updateSortDirection(thElem) {
        sortIconAPI.sortNone(thElem.select('div'));
        currCol.div = thElem.append('div');
        currCol.colId = thElem.attr('colId');

        if (currCol.colId === prevCol.colId) {
            (currCol.dir === desc) ? currCol.dir = asc : currCol.dir = desc;
            prevCol.dir = currCol.dir;
        } else {
            currCol.dir = asc;
            prevCol.dir = none;
        }
        (currCol.dir === asc) ?
            sortIconAPI.sortAsc(currCol.div) : sortIconAPI.sortDesc(currCol.div);

        if (prevCol.colId && prevCol.dir === none) {
            sortIconAPI.sortNone(prevCol.div);
        }

        prevCol.colId = currCol.colId;
        prevCol.div = currCol.div;
    }

    function sortRequestParams() {
        return {
            sortCol: currCol.colId,
            sortDir: currCol.dir
        };
    }

    function resetSortIcons() {
        if (currCol.div) {
            sortIconAPI.sortNone(currCol.div);
        }
        if (prevCol.div) {
            sortIconAPI.sortNone(prevCol.div);
        }
        currCol = {};
        prevCol = {};
    }

    angular.module('onosWidget')
        .directive('onosFixedHeader', ['$log','$window',
            'FnService', 'MastService',

            function (_$log_, _$window_, _fs_, _mast_) {
            return function (scope, element) {
                $log = _$log_;
                $window = _$window_;
                fs = _fs_;
                mast = _mast_;

                var w = angular.element($window),
                    table = d3.select(element[0]),
                    canAdjust = false;

                scope.$watch(function () {
                    return {
                        h: $window.innerHeight,
                        w: $window.innerWidth
                    };
                }, function () {
                    var wsz = fs.windowSize(0, 30),
                        wWidth = wsz.width,
                        wHeight = wsz.height;

                    if (!scope.tableData.length) {
                        defaultSize(table, wWidth);
                    }

                    scope.$on('LastElement', function () {
                        // only adjust the table once it's completely loaded
                        adjustTable(table, wWidth, wHeight);
                        canAdjust = true;
                    });

                    if (canAdjust) {
                        adjustTable(table, wWidth, wHeight);
                    }
                }, true);

                w.bind('onos-fixed-header', function () {
                    scope.$apply();
                });
            };
        }])

        .directive('onosSortableHeader', ['$log', 'IconService',
            function (_$log_, _is_) {
            return {
                scope: {
                    ctrlCallback: '&sortCallback'
                },
                link: function (scope, element) {
                    $log = _$log_;
                    is = _is_;
                    var header = d3.select(element[0]);
                        sortIconAPI = is.sortIcons();

                    // when a header is clicked, change its sort direction
                    // and get sorting order to send to the server.
                    header.selectAll('td').on('click', function () {
                        var col = d3.select(this);

                        if (col.attr('sortable') === '') {
                            updateSortDirection(col);
                            scope.ctrlCallback({
                                requestParams: sortRequestParams()
                            });
                        }
                    });
                }
            };
        }])

        .factory('TableService', ['IconService',

            function (is) {
                sortIconAPI = is.sortIcons();

                return {
                    resetSortIcons: resetSortIcons
                };
        }]);

}());
