/*
 * Copyright 2015-present 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 -- Toolbar Service
 */
// TODO: Augment service to allow toolbars to exist on right edge of screen
// TODO: also - make toolbar more object aware (rows etc.)


(function () {
    'use strict';

    // injected refs
    var $log, fs, ps, bns, is;

    // configuration
    var arrowSize = 10,
        sepWidth = 6,
        defaultSettings = {
            edge: 'left',
            width: 20,
            margin: 0,
            hideMargin: -20,
            top: 'auto',
            bottom: '10px',
            fade: false,
            shown: false
        };

    // internal state
    var tbars = {};


    // === Helper functions --------------------------------------

    // translate uses 50 because the svg viewbox is 50
    function rotateArrowLeft(adiv) {
        adiv.select('g')
            .attr('transform', 'translate(0 50) rotate(-90)');
    }
    function rotateArrowRight(adiv) {
        adiv.select('g')
            .attr('transform', 'translate(50 0) rotate(90)');
    }

    function createArrow(panel) {
        var arrowDiv = panel.append('div')
            .classed('tbar-arrow', true);
        is.loadIcon(arrowDiv, 'triangleUp', arrowSize, true);
        return arrowDiv;
    }

    function warn(msg, id) {
        $log.warn('createToolbar: ' + msg + ': [' + id + ']');
        return null;
    }

    // ==================================

    function createToolbar(id, opts) {
        if (!id) return warn('no ID given');
        if (tbars[id]) return warn('duplicate ID given', id);

        var settings = angular.extend({}, defaultSettings, fs.isO(opts)),
            items = {},
            tbid = 'toolbar-' + id,
            panel = ps.createPanel(tbid, settings),
            arrowDiv = createArrow(panel),
            currentRow = panel.append('div').classed('tbar-row', true),
            rowButtonIds = [],          // for removable buttons
            tbWidth = arrowSize + 2,    // empty toolbar width
            maxWidth = panel.width();

        arrowDiv.on('click', toggle);

        // add a descriptor for this toolbar
        tbars[id] = {
            settings: settings,
            items: items,
            panel: panel,
            panelId: tbid
        };

        panel.classed('toolbar', true)
            .style('top', settings.top)
            .style('bottom', settings.bottom);

        // Helper functions

        function dupId(id, caller) {
            if (items[id]) {
                $log.warn(caller + ': duplicate ID:', id);
                return true;
            }
            return false;
        }

        function adjustWidth(btnWidth) {
            if (fs.noPxStyle(currentRow, 'width') >= maxWidth) {
                tbWidth += btnWidth;
                maxWidth = tbWidth;
            }
            panel.width(tbWidth);
        }

        // API functions

        function addButton(id, gid, cb, tooltip) {
            if (dupId(id, 'addButton')) return null;

            var bid = tbid + '-' + id,
                btn = bns.button(currentRow, bid, gid, cb, tooltip);

            items[id] = btn;
            adjustWidth(btn.width());
            return btn;
        }

        function addToggle(id, gid, initState, cb, tooltip) {
            if (dupId(id, 'addToggle')) return null;

            var tid = tbid + '-' + id,
                tog = bns.toggle(currentRow, tid, gid, initState, cb, tooltip);

            items[id] = tog;
            adjustWidth(tog.width());
            return tog;
        }

        function addRadioSet(id, rset) {
            if (dupId(id, 'addRadioSet')) return null;

            var rid = tbid + '-' + id,
                rad = bns.radioSet(currentRow, rid, rset);

            items[id] = rad;
            adjustWidth(rad.width());
            return rad;
        }

        function addSeparator() {
            currentRow.append('div')
                .classed('separator', true);
            tbWidth += sepWidth;
        }

        function addRow() {
            if (currentRow.select('div').empty()) {
                return null;
            } else {
                panel.append('br');
                currentRow = panel.append('div').classed('tbar-row', true);

                // return API to allow caller more access to the row
                return {
                    clear: rowClear,
                    setText: rowSetText,
                    addButton: rowAddButton,
                    classed: rowClassed
                };
            }
        }

        function rowClear() {
            currentRow.selectAll('*').remove();
            rowButtonIds.forEach(function (bid) {
                delete items[bid];
            });
            rowButtonIds = [];
        }

        // installs a div with text into the button row
        function rowSetText(text) {
            rowClear();
            currentRow.append('div').classed('tbar-row-text', true)
                .html(text);
        }

        function rowAddButton(id, gid, cb, tooltip) {
            var b = addButton(id, gid, cb, tooltip);
            if (b) {
                rowButtonIds.push(id);
            }
        }

        function rowClassed(classes, bool) {
            currentRow.classed(classes, bool);
        }

        function show(cb) {
            rotateArrowLeft(arrowDiv);
            panel.show(cb);
        }

        function hide(cb) {
            rotateArrowRight(arrowDiv);
            panel.hide(cb);
        }

        function toggle(cb) {
            if (panel.isVisible()) {
                hide(cb);
            } else {
                show(cb);
            }
        }

        function isVisible() {
            return panel.isVisible();
        }

        return {
            addButton: addButton,
            addToggle: addToggle,
            addRadioSet: addRadioSet,
            addSeparator: addSeparator,
            addRow: addRow,

            show: show,
            hide: hide,
            toggle: toggle,
            isVisible: isVisible
        };
    }

    function destroyToolbar(id) {
        var tb = tbars[id];
        delete tbars[id];

        if (tb) {
            ps.destroyPanel(tb.panelId);
        }
    }

    // === Module Definition ===

    angular.module('onosWidget')
    .factory('ToolbarService',
        ['$log', 'FnService', 'PanelService', 'ButtonService', 'IconService',

        function (_$log_, _fs_, _ps_, _bns_, _is_) {
            $log = _$log_;
            fs = _fs_;
            ps = _ps_;
            bns = _bns_;
            is = _is_;

            // this function is only used in testing
            function init() {
                tbars = {};
            }

            return {
                init: init,
                createToolbar: createToolbar,
                destroyToolbar: destroyToolbar
            };
        }]);
}());
