/*
 * 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,
        mastPdg = 8,
        h2Pdg = 40,
        thPdg = 12,
        tbodyPdg = 5,
        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
    // or 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);
            }
        });
    }

    // get the size of the window and then subtract the extra space at the top
    // to get the height of the table
    function setTableHeight(thead, tbody) {
        var titleHeight = h2Pdg + fs.noPxStyle(d3.select('h2'), 'height'),
            thHeight = thPdg + fs.noPxStyle(thead, 'height'),
            totalHeight = titleHeight + thHeight + mastPdg - tbodyPdg,
            tableHeight = fs.windowSize(mast.mastHeight() + totalHeight).height;

        thead.style('display', 'block');
        tbody.style({'display': 'block',
            'height': (tableHeight + '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', 'MastService',
            function (_$window_, _fs_, _mast_) {
            return function (scope, element) {
                $window = _$window_;
                fs = _fs_;
                mast = _mast_;

                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()
                            });
                        }
                    });
                }
            };
        }]);

}());
