/*
 *  Copyright 2016 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 -- Layer -- Dialog Service

 Builds on the panel service to provide dialog functionality.
 */
(function () {
    'use strict';

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

    // configuration
    var defaultSettings = {
            width: 300,
            edge: 'left'
        };

    // internal state
    var pApi, panel, dApi;

    // TODO: ONOS-3741
    // TODO: ESC key invokes Cancel callback
    // TODO: Enter invokes OK callback

    // create the dialog; return its API
    function createDialog(id, opts) {
        var header, body, footer,
            settings = angular.extend({}, defaultSettings, opts),
            p = ps.createPanel(id, settings),
            cls = opts && opts.cssCls;

        p.classed('dialog', true);
        if (cls) {
            p.classed(cls, true);
        }
        panel = p;

        function reset() {
            p.empty();
            p.append('div').classed('header', true);
            p.append('div').classed('body', true);
            p.append('div').classed('footer', true);

            header = p.el().select('.header');
            body = p.el().select('.body');
            footer = p.el().select('.footer');
        }

        function hAppend(x) {
            if (typeof x === 'string') {
                return header.append(x);
            }
            header.node().appendChild(x.node());
            return header;
        }

        function bAppend(x) {
            if (typeof x === 'string') {
                return body.append(x);
            }
            body.node().appendChild(x.node());
            return body;
        }

        function fAppend(x) {
            if (typeof x === 'string') {
                return footer.append(x);
            }
            footer.node().appendChild(x.node());
            return footer;
        }

        function destroy() {
            ps.destroyPanel(id);
        }

        return {
            reset: reset,
            appendHeader: hAppend,
            appendBody: bAppend,
            appendFooter: fAppend,
            destroy: destroy
        };
    }

    function makeButton(text, callback) {
        var cb = fs.isF(callback);

        function invoke() {
            cb && cb();
            panel.hide();
        }
        return createDiv('dialog-button')
            .text(text)
            .on('click', invoke);
    }

    function setTitle(title) {
        if (pApi) {
            pApi.appendHeader('h2').text(title);
        }
        return dApi;
    }

    function addContent(content) {
        if (pApi) {
            pApi.appendBody(content);
        }
        return dApi;
    }

    function addButton(text, cb) {
        if (pApi) {
            pApi.appendFooter(makeButton(text, cb));
        }
        return dApi;
    }

    // opens the dialog (creates if necessary)
    function openDialog(id, opts) {
        $log.debug('Open DIALOG', id, opts);
        if (!pApi) {
            pApi = createDialog(id, opts);
        }
        pApi.reset();
        panel.show();

        // return the dialog object API
        dApi = {
            setTitle: setTitle,
            addContent: addContent,
            addButton: addButton
        };
        return dApi;
    }

    // closes the dialog (destroying panel)
    function closeDialog() {
        $log.debug('Close DIALOG');
        if (pApi) {
            panel.hide();
            pApi.destroy();
            pApi = null;
            dApi = null;
        }
    }

    // creates a detached div, returning D3 selection
    // optional CSS class may be provided
    function createDiv(cls) {
        var div = d3.select(document.createElement('div'));
        if (cls) {
            div.classed(cls, true);
        }
        return div;
    }

    angular.module('onosLayer')
    .factory('DialogService',
        ['$log', '$window', 'FnService', 'PanelService', 'ButtonService',

        // TODO: for now, $window is not used, but we should provide an option
            // to center the dialog on the window.

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

            return {
                openDialog: openDialog,
                closeDialog: closeDialog,
                createDiv: createDiv
            };
        }]);

}());
