/*
 * 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, is;

    // constants
    var tableIconTdSize = 33,
        bottomMargin = 200,
        colWidth = 'col-width',
        tableIcon = 'table-icon';

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

    // Functions for creating a fixed header on a table (Angular Directive)

    function setElemWidth(elem, size) {
        elem.style('width', size + 'px')
    }

    function setColWidth(th, td, size) {
        setElemWidth(th, size);
        setElemWidth(td, size);
    }

    // count number of headers of
    //   - assigned width,
    //   - icon width,
    //   - and default width
    // assumes assigned width is not given to icons
    // returns the width of all columns that are not icons have an assigned width
    function getDefaultWidth(headers) {
        var winWidth = fs.windowSize().width,
            iconCols = 0,
            regCols = 0,
            cstmColWidth = 0;

        headers.each(function (d, i) {
            var thElement = d3.select(this),
                cstmWidth = thElement.attr(colWidth);

            if (cstmWidth) {
                cstmColWidth += fs.noPx(cstmWidth);
            } else if (thElement.classed(tableIcon)) {
                iconCols += 1;
            } else {
                regCols += 1;
            }
        });

        return Math.floor((winWidth - cstmColWidth -
                            (iconCols * tableIconTdSize)) / regCols);
    }

    function setTableWidth(t) {
        var tHeaders = t.selectAll('th'),
            defaultColWidth = getDefaultWidth(tHeaders);

        tHeaders.each(function (d, i) {
            var thElement = d3.select(this),
                tdElement = t.select('td:nth-of-type(' + (i + 1) + ')'),
                custWidth = thElement.attr(colWidth);

            if (custWidth) {
                setColWidth(thElement, tdElement, fs.noPx(custWidth));
            } else if (thElement.classed(tableIcon)) {
                setColWidth(thElement, tdElement, tableIconTdSize);
            } else {
                setColWidth(thElement, tdElement, defaultColWidth);
            }
        });
    }

    function setTableHeight(thead, tbody) {
        var winHeight = fs.windowSize().height;

        thead.style('display', 'block');
        tbody.style({'display': 'block',
            'height': ((winHeight - bottomMargin) + 'px'),
            'overflow': 'auto'
        });
    }

    function fixTable(t, th, tb) {
        setTableWidth(t);
        setTableHeight(th, tb);
    }

    // Functions for sorting table rows by header and choosing appropriate icon

    function updateSortingIcons(thElem, api) {
        var div;
        currCol.colId = thElem.attr('colId');

        if (currCol.colId === prevCol.colId) {
            (currCol.icon === 'tableColSortDesc') ?
                currCol.icon = 'tableColSortAsc' :
                currCol.icon = 'tableColSortDesc';
            prevCol.icon = currCol.icon;
        } else {
            currCol.icon = 'tableColSortAsc';
            prevCol.icon = 'tableColSortNone';
        }

        div = thElem.select('div');
        api.sortNone(div);
        div = thElem.append('div');

        if (currCol.icon === 'tableColSortAsc') {
            api.sortAsc(div);
        } else {
            api.sortDesc(div);
        }

        if (prevCol.colId !== undefined &&
            prevCol.icon === 'tableColSortNone') {
            api.sortNone(prevCol.elem.select('div'));
        }

        prevCol.colId = currCol.colId;
        prevCol.elem = thElem;
    }

    function sortRequestParams() {
        return {
            sortCol: currCol.colId,
            sortDir: (currCol.icon === 'tableColSortAsc' ? 'asc' : 'desc')
        };
    }

    angular.module('onosWidget')
        .directive('onosFixedHeader', ['$window', 'FnService',
            function (_$window_, _fs_) {
            return function (scope, element) {
                $window = _$window_;
                fs = _fs_;
                var w = angular.element($window),
                    table = d3.select(element[0]),
                    thead = table.select('thead'),
                    tbody = table.select('tbody'),
                    canAdjust = false;

                scope.$watch(function () {
                    return {
                        h: window.innerHeight,
                        w: window.innerWidth
                    };
                }, function (newVal) {
                    var wsz = fs.windowSize(0, 30);
                    scope.windowHeight = newVal.h;
                    scope.windowWidth = newVal.w;

                    // default table size in case no data elements
                    table.style('width', wsz.width + 'px');

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

                    if (canAdjust) {
                        fixTable(table, thead, tbody);
                    }
                }, 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 table = d3.select(element[0]),
                        sortIconAPI = is.createSortIcon();

                    // when a header is clicked, change its icon tag
                    // and get sorting order to send to the server.
                    table.selectAll('th').on('click', function () {
                        var thElem = d3.select(this);

                        if (thElem.attr('sortable') === '') {
                            updateSortingIcons(thElem, sortIconAPI);
                            scope.ctrlCallback({
                                requestParams: sortRequestParams()
                            });
                        }
                    });
                }
            };
        }]);

}());
