/*
 * 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 -- Button Service
 */
(function () {
    'use strict';

    // injected refs
    var $log, fs, is, tts;

    // configuration
    var btnSize = 25,
        btnPadding = 4;


    // === Helper Functions

    function divExists(div, msg) {
        if (!div) {
            $log.warn('div undefined (' + msg + ')');
        }
        return !!div;
    }

    function createDiv(div, cls, id) {
        return div.append('div')
            .classed(cls, true)
            .attr('id', id);
    }

    function noop() {}

    function buttonWidth() {
        return btnSize + 2 * btnPadding;
    }

    // === BUTTON =================================================

    // div is where to put the button (d3.selection of a DIV element)
    // id should be globally unique
    // gid is glyph ID (from Glyph Service)
    // cb is callback function on click
    // tooltip is text for tooltip
    function button(div, id, gid, cb, tooltip) {
        if (!divExists(div, 'button')) return null;

        var btnDiv = createDiv(div, 'button', id),
            cbFnc = fs.isF(cb) || noop;

        is.loadIcon(btnDiv, gid, btnSize, true);
        if (tooltip) { tts.addTooltip(btnDiv, tooltip); }

        btnDiv.on('click', cbFnc);

        return {
            id: id,
            width: buttonWidth
        }
    }


    // === TOGGLE BUTTON ==========================================

    // div is where to put the button (d3.selection of a DIV element)
    // id should be globally unique
    // gid is glyph ID (from Glyph Service)
    // initState is whether the toggle is on or not to begin
    // cb is callback function on click
    // tooltip is text for tooltip
    function toggle(div, id, gid, initState, cb, tooltip) {
        if (!divExists(div, 'toggle button')) return null;

        var sel = !!initState,
            togDiv = createDiv(div, 'toggleButton', id),
            cbFnc = fs.isF(cb) || noop;

        is.loadIcon(togDiv, gid, btnSize, true);
        togDiv.classed('selected', sel);
        if (tooltip) { tts.addTooltip(togDiv, tooltip); }

        function _toggle(b, nocb) {
            sel = (b === undefined) ? !sel : !!b;
            togDiv.classed('selected', sel);
            nocb || cbFnc(sel);
        }

        // toggle the button state without invoking the callback
        function toggleNoCb() {
            _toggle(undefined, true);
        }

        togDiv.on('click', _toggle);

        return {
            id: id,
            width: buttonWidth,
            selected: function () { return sel; },
            toggle: _toggle,
            toggleNoCb: toggleNoCb
        }
    }


    // === RADIO BUTTON SET =======================================


    // div is where to put the button (d3.selection of a DIV element)
    // id should be globally unique
    // rset is an array of button descriptors of the following form:
    //     {
    //       gid: glyphId,
    //       tooltip: tooltipText,
    //       cb:  callbackFunction
    //     }
    function radioSet(div, id, rset) {
        if (!divExists(div, 'radio button set')) return null;

        if (!fs.isA(rset) || !rset.length) {
            $log.warn('invalid array (radio button set)');
            return null;
        }

        var rDiv = createDiv(div, 'radioSet', id),
            rads = [],
            idxByKey = {},
            currIdx = 0;

        function rsetWidth() {
            return ((btnSize + btnPadding) * rads.length) + btnPadding;
        }

        function rbclick() {
            var id = d3.select(this).attr('id'),
                m = /^.*-(\d+)$/.exec(id),
                idx = Number(m[1]);

            if (idx !== currIdx) {
                rads[currIdx].el.classed('selected', false);
                currIdx = idx;
                rads[currIdx].el.classed('selected', true);
                invokeCurrent();
            }
        }

         // {
         //     gid: gid,
         //     tooltip: ...,       (optional)
         //     key: ...,           (optional)
         //     cb: cb
         //     id: ...             (added by us)
         //     index: ...          (added by us)
         // }

        rset.forEach(function (btn, index) {

            if (!fs.isO(btn)) {
                $log.warn('radio button descriptor at index ' + index +
                            ' not an object');
                return;
            }

            var rid = id + '-' + index,
                initSel = (index === 0),
                rbdiv = createDiv(rDiv, 'radioButton', rid);

            rbdiv.classed('selected', initSel);
            rbdiv.on('click', rbclick);
            is.loadIcon(rbdiv, btn.gid, btnSize, true);
            if (btn.tooltip) { tts.addTooltip(rbdiv, btn.tooltip); }
            angular.extend(btn, {
                el: rbdiv,
                id: rid,
                cb: fs.isF(btn.cb) || noop,
                index: index
            });

            if (btn.key) {
                idxByKey[btn.key] = index;
            }

            rads.push(btn);
        });


        function invokeCurrent() {
            var curr = rads[currIdx];
            curr.cb(curr.index, curr.key);
        }

        function selected(x) {
            var curr = rads[currIdx],
                idx;

            if (x === undefined) {
                return curr.key || curr.index;
            } else {
                idx = idxByKey[x];
                if (idx === undefined) {
                    $log.warn('no radio button with key:', x);
                } else {
                    selectedIndex(idx);
                }
            }
        }

        function selectedIndex(x) {
            if (x === undefined) {
                return currIdx;
            } else {
                if (x >= 0 && x < rads.length) {
                    if (currIdx !== x) {
                        rads[currIdx].el.classed('selected', false);
                        currIdx = x;
                        rads[currIdx].el.classed('selected', true);
                        invokeCurrent();
                    } else {
                        $log.warn('current index already selected:', x);
                    }
                } else {
                    $log.warn('invalid radio button index:', x);
                }
            }
        }

        return {
            width: rsetWidth,
            selected: selected,
            selectedIndex: selectedIndex
        }
    }


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

        function (_$log_, _fs_, _is_, _tts_) {
            $log = _$log_;
            fs = _fs_;
            is = _is_;
            tts = _tts_;

            return {
                button: button,
                toggle: toggle,
                radioSet: radioSet
            };
        }]);

}());
