/*
 * 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;
    }

    function addTooltip(elem, tooltip) {
        elem.on('mouseover', function () { tts.showTooltip(this, tooltip); });
        elem.on('mouseout', function () { tts.cancelTooltip(this); });
    }


    // === 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) { 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) { 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) { 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) {
                        currIdx = x;
                        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
            };
        }]);

}());
