/*
 * Copyright 2014 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 -- Base Framework

 @author Simon Hunt
 */

(function ($) {
    'use strict';
    var tsI = new Date().getTime(),         // initialize time stamp
        tsB,                                // build time stamp
        mastHeight = 36,                    // see mast2.css
        defaultVid = 'sample';


    // attach our main function to the jQuery object
    $.onos = function (options) {
        var uiApi,
            viewApi,
            navApi,
            libApi,
            exported = {};

        var defaultOptions = {
            trace: false,
            theme: 'dark',
            startVid: defaultVid
        };

        // compute runtime settings
        var settings = $.extend({}, defaultOptions, options);

        // set the selected theme
        d3.select('body').classed(settings.theme, true);

        // internal state
        var views = {},
            fpanels = {},
            current = {
                view: null,
                ctx: '',
                flags: {},
                theme: settings.theme
            },
            built = false,
            buildErrors = [],
            keyHandler = {
                globalKeys: {},
                maskedKeys: {},
                viewKeys: {},
                viewFn: null
            },
            alerts = {
                open: false,
                count: 0
            };

        // DOM elements etc.
        // TODO: verify existence of following elements...
        var $view = d3.select('#view'),
            $floatPanels = d3.select('#floatPanels'),
            $alerts = d3.select('#alerts'),
            // note, following elements added programmatically...
            $mastRadio;


        function whatKey(code) {
            switch (code) {
                case 13: return 'enter';
                case 16: return 'shift';
                case 17: return 'ctrl';
                case 18: return 'alt';
                case 27: return 'esc';
                case 32: return 'space';
                case 37: return 'leftArrow';
                case 38: return 'upArrow';
                case 39: return 'rightArrow';
                case 40: return 'downArrow';
                case 91: return 'cmdLeft';
                case 93: return 'cmdRight';
                case 187: return 'equals';
                case 189: return 'dash';
                case 191: return 'slash';
                default:
                    if ((code >= 48 && code <= 57) ||
                        (code >= 65 && code <= 90)) {
                        return String.fromCharCode(code);
                    } else if (code >= 112 && code <= 123) {
                        return 'F' + (code - 111);
                    }
                    return '.';
            }
        }


        // ..........................................................
        // Internal functions

        // throw an error
        function throwError(msg) {
            // separate function, as we might add tracing here too, later
            throw new Error(msg);
        }

        function doError(msg) {
            console.error(msg);
            doAlert(msg);
        }

        function trace(msg) {
            if (settings.trace) {
                console.log(msg);
            }
        }

        function traceFn(fn, params) {
            if (settings.trace) {
                console.log('*FN* ' + fn + '(...): ' + params);
            }
        }

        // hash navigation
        function hash() {
            var hash = window.location.hash,
                redo = false,
                view,
                t;

            traceFn('hash', hash);

            if (!hash) {
                hash = settings.startVid;
                redo = true;
            }

            t = parseHash(hash);
            if (!t || !t.vid) {
                doError('Unable to parse target hash: "' + hash + '"');
            }

            view = views[t.vid];
            if (!view) {
                doError('No view defined with id: ' + t.vid);
            }

            if (redo) {
                window.location.hash = makeHash(t);
                // the above will result in a hashchange event, invoking
                // this function again
            } else {
                // hash was not modified... navigate to where we need to be
                navigate(hash, view, t);
            }
        }

        function parseHash(s) {
            // extract navigation coordinates from the supplied string
            // "vid,ctx?flag1,flag2" --> { vid:vid, ctx:ctx, flags:{...} }
            traceFn('parseHash', s);

            // look for use of flags, first
            var vidctx,
                vid,
                ctx,
                flags,
                flagMap,
                m;

            // RE that includes flags ('?flag1,flag2')
            m = /^[#]{0,1}(.+)\?(.+)$/.exec(s);
            if (m) {
                vidctx = m[1];
                flags = m[2];
                flagMap = {};
            } else {
                // no flags
                m = /^[#]{0,1}((.+)(,.+)*)$/.exec(s);
                if (m) {
                    vidctx = m[1];
                } else {
                    // bad hash
                    return null;
                }
            }

            vidctx = vidctx.split(',');
            vid = vidctx[0];
            ctx = vidctx[1];
            if (flags) {
                flags.split(',').forEach(function (f) {
                    flagMap[f.trim()] = true;
                });
            }

            return {
                vid: vid.trim(),
                ctx: ctx ? ctx.trim() : '',
                flags: flagMap
            };

        }

        function makeHash(t, ctx, flags) {
            traceFn('makeHash');
            // make a hash string from the given navigation coordinates,
            // and optional flags map.
            // if t is not an object, then it is a vid
            var h = t,
                c = ctx || '',
                f = $.isPlainObject(flags) ? flags : null;

            if ($.isPlainObject(t)) {
                h = t.vid;
                c = t.ctx || '';
                f = t.flags || null;
            }

            if (c) {
                h += ',' + c;
            }
            if (f) {
                h += '?' + d3.map(f).keys().join(',');
            }
            trace('hash = "' + h + '"');
            return h;
        }

        function navigate(hash, view, t) {
            traceFn('navigate', view.vid);
            // closePanes()     // flyouts etc.
            // updateNav()      // accordion / selected nav item etc.
            createView(view);
            setView(view, hash, t);
        }

        function buildError(msg) {
            buildErrors.push(msg);
        }

        function reportBuildErrors() {
            traceFn('reportBuildErrors');
            var nerr = buildErrors.length,
                errmsg;
            if (!nerr) {
                console.log('(no build errors)');
            } else {
                errmsg = 'Build errors: ' + nerr + ' found...\n\n' +
                    buildErrors.join('\n');
                doAlert(errmsg);
                console.error(errmsg);
            }
        }

        // returns the reference if it is a function, null otherwise
        function isF(f) {
            return $.isFunction(f) ? f : null;
        }

        // returns the reference if it is an array, null otherwise
        function isA(a) {
            return $.isArray(a) ? a : null;
        }

        // ..........................................................
        // View life-cycle functions

        function setViewDimensions(sel) {
            var w = window.innerWidth,
                h = window.innerHeight - mastHeight;
            sel.each(function () {
                $(this)
                    .css('width', w + 'px')
                    .css('height', h + 'px')
            });
        }

        function createView(view) {
            var $d;

            // lazy initialization of the view
            if (view && !view.$div) {
                trace('creating view for ' + view.vid);
                $d = $view.append('div')
                        .attr({
                            id: view.vid,
                            class: 'onosView'
                         });
                setViewDimensions($d);
                view.$div = $d;   // cache a reference to the D3 selection
            }
        }

        function setView(view, hash, t) {
            traceFn('setView', view.vid);
            // set the specified view as current, while invoking the
            // appropriate life-cycle callbacks

            // first, we'll start by closing the alerts pane, if open
            closeAlerts();

            // if there is a current view, and it is not the same as
            // the incoming view, then unload it...
            if (current.view && (current.view.vid !== view.vid)) {
                current.view.unload();

                // detach radio buttons, key handlers, etc.
                $('#mastRadio').children().detach();
                keyHandler.viewKeys = {};
                keyHandler.viewFn = null;
            }

            // cache new view and context
            current.view = view;
            current.ctx = t.ctx || '';
            current.flags = t.flags || {};

            // preload is called only once, after the view is in the DOM
            if (!view.preloaded) {
                view.preload(current.ctx, current.flags);
                view.preloaded = true;
            }

            // clear the view of stale data
            view.reset();

            // load the view
            view.load(current.ctx, current.flags);
        }

        // generate 'unique' id by prefixing view id
        function makeUid(view, id) {
            return view.vid + '-' + id;
        }

        // restore id by removing view id prefix
        function unmakeUid(view, uid) {
            var re = new RegExp('^' + view.vid + '-');
            return uid.replace(re, '');
        }

        function setRadioButtons(vid, btnSet) {
            var view = views[vid],
                btnG,
                api = {};

            // lazily create the buttons...
            if (!(btnG = view.radioButtons)) {
                btnG = d3.select(document.createElement('div'));
                btnG.buttonDef = {};

                btnSet.forEach(function (btn, i) {
                    var bid = btn.id || 'b' + i,
                        txt = btn.text || 'Button #' + i,
                        uid = makeUid(view, bid),
                        button = btnG.append('span')
                        .attr({
                            id: uid,
                            class: 'radio'
                        })
                        .text(txt);

                    btn.id = bid;
                    btnG.buttonDef[uid] = btn;

                    if (i === 0) {
                        button.classed('active', true);
                        btnG.selected = bid;
                    }
                });

                btnG.selectAll('span')
                    .on('click', function (d) {
                        var button = d3.select(this),
                            uid = button.attr('id'),
                            btn = btnG.buttonDef[uid],
                            act = button.classed('active');

                        if (!act) {
                            btnG.selectAll('span').classed('active', false);
                            button.classed('active', true);
                            btnG.selected = btn.id;
                            if (isF(btn.cb)) {
                                btn.cb(view.token(), btn);
                            }
                        }
                    });

                view.radioButtons = btnG;

                api.selected = function () {
                    return btnG.selected;
                }
            }

            // attach the buttons to the masthead
            $mastRadio.node().appendChild(btnG.node());
            // return an api for interacting with the button set
            return api;
        }

        function setupGlobalKeys() {
            keyHandler.globalKeys = {
                slash: [keyMap, 'Show / hide keyboard shortcuts'],
                esc: [escapeKey, 'Dismiss dialog or cancel selections'],
                T: [toggleTheme, "Toggle theme"]
            };
            // Masked keys are global key handlers that always return true.
            // That is, the view will never see the event for that key.
            keyHandler.maskedKeys = {
                slash: true,
                T: true
            };
        }

        function keyMap(view, key, code, ev) {
            libApi.keymap.show(keyHandler);
            return true;
        }

        function escapeKey(view, key, code, ev) {
            if (libApi.keymap.hide()) {
                return true;
            }
            if (alerts.open) {
                closeAlerts();
                return true;
            }
            return false;
        }

        function toggleTheme(view, key, code, ev) {
            var body = d3.select('body');
            current.theme = (current.theme === 'light') ? 'dark' : 'light';
            body.classed('light dark', false);
            body.classed(current.theme, true);
            theme(view);
            return true;
        }

        function setKeyBindings(keyArg) {
            var viewKeys,
                masked = [];

            if ($.isFunction(keyArg)) {
                // set general key handler callback
                keyHandler.viewFn = keyArg;
            } else {
                // set specific key filter map
                viewKeys = d3.map(keyArg).keys();
                viewKeys.forEach(function (key) {
                    if (keyHandler.maskedKeys[key]) {
                        masked.push('  Key "' + key + '" is reserved');
                    }
                });

                if (masked.length) {
                    doAlert('WARNING...\n\nsetKeys():\n' + masked.join('\n'));
                }
                keyHandler.viewKeys = keyArg;
            }
        }

        function keyIn() {
            var event = d3.event,
                keyCode = event.keyCode,
                key = whatKey(keyCode),
                gk = keyHandler.globalKeys[key],
                gcb = isF(gk) || (isA(gk) && isF(gk[0])),
                vk = keyHandler.viewKeys[key],
                vcb = isF(vk) || (isA(vk) && isF(vk[0])) || isF(keyHandler.viewFn);

            // global callback?
            if (gcb && gcb(current.view.token(), key, keyCode, event)) {
                // if the event was 'handled', we are done
                return;
            }
            // otherwise, let the view callback have a shot
            if (vcb) {
                vcb(current.view.token(), key, keyCode, event);
            }
        }

        function createAlerts() {
            $alerts.style('display', 'block');
            $alerts.append('span')
                .attr('class', 'close')
                .text('X')
                .on('click', closeAlerts);
            $alerts.append('pre');
            $alerts.append('p').attr('class', 'footnote')
                .text('Press ESCAPE to close');
            alerts.open = true;
            alerts.count = 0;
        }

        function closeAlerts() {
            $alerts.style('display', 'none')
                .html('');
            alerts.open = false;
        }

        function addAlert(msg) {
            var lines,
                oldContent;

            if (alerts.count) {
                oldContent = $alerts.select('pre').html();
            }

            lines = msg.split('\n');
            lines[0] += '  '; // spacing so we don't crowd 'X'
            lines = lines.join('\n');

            if (oldContent) {
                lines += '\n----\n' + oldContent;
            }

            $alerts.select('pre').html(lines);
            alerts.count++;
        }

        function doAlert(msg) {
            if (!alerts.open) {
                createAlerts();
            }
            addAlert(msg);
        }

        function resize(e) {
            d3.selectAll('.onosView').call(setViewDimensions);
            // allow current view to react to resize event...
            if (current.view) {
                current.view.resize(current.ctx, current.flags);
            }
        }

        function theme() {
            // allow current view to react to theme event...
            if (current.view) {
                current.view.theme(current.ctx, current.flags);
            }
        }

        // ..........................................................
        // View class
        //   Captures state information about a view.

        // Constructor
        //      vid : view id
        //      nid : id of associated nav-item (optional)
        //      cb  : callbacks (preload, reset, load, unload, resize, error)
        function View(vid) {
            var av = 'addView(): ',
                args = Array.prototype.slice.call(arguments),
                nid,
                cb;

            args.shift();   // first arg is always vid
            if (typeof args[0] === 'string') {  // nid specified
                nid = args.shift();
            }
            cb = args.shift();

            this.vid = vid;

            if (validateViewArgs(vid)) {
                this.nid = nid;     // explicit navitem id (can be null)
                this.cb = $.isPlainObject(cb) ? cb : {};    // callbacks
                this.$div = null;               // view not yet added to DOM
                this.radioButtons = null;       // no radio buttons yet
                this.ok = true;                 // valid view
            }
        }

        function validateViewArgs(vid) {
            var av = "ui.addView(...): ",
                ok = false;
            if (typeof vid !== 'string' || !vid) {
                doError(av + 'vid required');
            } else if (views[vid]) {
                doError(av + 'View ID "' + vid + '" already exists');
            } else {
                ok = true;
            }
            return ok;
        }

        var viewInstanceMethods = {
            token: function () {
                return {
                    // attributes
                    vid: this.vid,
                    nid: this.nid,
                    $div: this.$div,

                    // functions
                    width: this.width,
                    height: this.height,
                    uid: this.uid,
                    setRadio: this.setRadio,
                    setKeys: this.setKeys,
                    dataLoadError: this.dataLoadError,
                    alert: this.alert,
                    flash: this.flash,
                    getTheme: this.getTheme
                }
            },

            // == Life-cycle functions
            // TODO: factor common code out of life-cycle
            preload: function (ctx, flags) {
                var c = ctx || '',
                    fn = isF(this.cb.preload);
                traceFn('View.preload', this.vid + ', ' + c);
                if (fn) {
                    trace('PRELOAD cb for ' + this.vid);
                    fn(this.token(), c, flags);
                }
            },

            reset: function (ctx, flags) {
                var c = ctx || '',
                    fn = isF(this.cb.reset);
                traceFn('View.reset', this.vid);
                if (fn) {
                    trace('RESET cb for ' + this.vid);
                    fn(this.token(), c, flags);
                } else if (this.cb.reset === true) {
                    // boolean true signifies "clear view"
                    trace('  [true] cleaing view...');
                    viewApi.empty();
                }
            },

            load: function (ctx, flags) {
                var c = ctx || '',
                    fn = isF(this.cb.load);
                traceFn('View.load', this.vid + ', ' + c);
                this.$div.classed('currentView', true);
                if (fn) {
                    trace('LOAD cb for ' + this.vid);
                    fn(this.token(), c, flags);
                }
            },

            unload: function (ctx, flags) {
                var c = ctx | '',
                    fn = isF(this.cb.unload);
                traceFn('View.unload', this.vid);
                this.$div.classed('currentView', false);
                if (fn) {
                    trace('UNLOAD cb for ' + this.vid);
                    fn(this.token(), c, flags);
                }
            },

            resize: function (ctx, flags) {
                var c = ctx || '',
                    fn = isF(this.cb.resize),
                    w = this.width(),
                    h = this.height();
                traceFn('View.resize', this.vid + '/' + c +
                        ' [' + w + 'x' + h + ']');
                if (fn) {
                    trace('RESIZE cb for ' + this.vid);
                    fn(this.token(), c, flags);
                }
            },

            theme: function (ctx, flags) {
                var c = ctx | '',
                    fn = isF(this.cb.theme);
                traceFn('View.theme', this.vid);
                if (fn) {
                    trace('THEME cb for ' + this.vid);
                    fn(this.token(), c, flags);
                }
            },

            error: function (ctx, flags) {
                var c = ctx || '',
                    fn = isF(this.cb.error);
                traceFn('View.error', this.vid + ', ' + c);
                if (fn) {
                    trace('ERROR cb for ' + this.vid);
                    fn(this.token(), c, flags);
                }
            },

            // == Token API functions
            width: function () {
                return $(this.$div.node()).width();
            },

            height: function () {
                return $(this.$div.node()).height();
            },

            setRadio: function (btnSet) {
                return setRadioButtons(this.vid, btnSet);
            },

            setKeys: function (keyArg) {
                setKeyBindings(keyArg);
            },

            getTheme: function () {
                return current.theme;
            },

            uid: function (id) {
                return makeUid(this, id);
            },

            // TODO : add exportApi and importApi methods
            // TODO : implement custom dialogs

            // Consider enhancing alert mechanism to handle multiples
            // as individually closable.
            alert: function (msg) {
                doAlert(msg);
            },

            flash: function (msg) {
                libApi.feedback.flash(msg);
            },

            dataLoadError: function (err, url) {
                var msg = 'Data Load Error\n\n' +
                    err.status + ' -- ' + err.statusText + '\n\n' +
                    'relative-url: "' + url + '"\n\n' +
                    'complete-url: "' + err.responseURL + '"';
                this.alert(msg);
            }

            // TODO: consider schedule, clearTimer, etc.
        };

        // attach instance methods to the view prototype
        $.extend(View.prototype, viewInstanceMethods);

        // ..........................................................
        // UI API

        var fpConfig = {
            TR: {
                side: 'right'

            },
            TL: {
                side: 'left'
            }
        };

        uiApi = {
            addLib: function (libName, api) {
                // TODO: validation of args
                libApi[libName] = api;
            },

            // TODO: implement floating panel as a class
            // TODO: parameterize position (currently hard-coded to TopRight)
            /*
             * Creates div in floating panels block, with the given id.
             * Returns panel token used to interact with the panel
             */
            addFloatingPanel: function (id, position) {
                var pos = position || 'TR',
                    cfg = fpConfig[pos],
                    el,
                    fp,
                    on = false;

                if (fpanels[id]) {
                    buildError('Float panel with id "' + id + '" already exists.');
                    return null;
                }

                el = $floatPanels.append('div')
                    .attr('id', id)
                    .attr('class', 'fpanel')
                    .style('opacity', 0);

                // has to be called after el is set.
                el.style(cfg.side, pxHide());

                function pxShow() {
                    return '20px';
                }
                function pxHide() {
                    return (-20 - widthVal()) + 'px';
                }
                function noPx(what) {
                    return el.style(what).replace(/px$/, '');
                }
                function widthVal() {
                    return noPx('width');
                }
                function heightVal() {
                    return noPx('height');
                }

                fp = {
                    id: id,
                    el: el,
                    pos: pos,
                    isVisible: function () {
                        return on;
                    },

                    show: function () {
                        console.log('show pane: ' + id);
                        on = true;
                        el.transition().duration(750)
                            .style(cfg.side, pxShow())
                            .style('opacity', 1);
                    },
                    hide: function () {
                        console.log('hide pane: ' + id);
                        on = false;
                        el.transition().duration(750)
                            .style(cfg.side, pxHide())
                            .style('opacity', 0);
                    },
                    empty: function () {
                        return el.html('');
                    },
                    append: function (what) {
                        return el.append(what);
                    },
                    width: function (w) {
                        if (w === undefined) {
                            return widthVal();
                        }
                        el.style('width', w + 'px');
                    },
                    height: function (h) {
                        if (h === undefined) {
                            return heightVal();
                        }
                        el.style('height', h + 'px');
                    }
                };
                fpanels[id] = fp;
                return fp;
            },

            // TODO: it remains to be seen whether we keep this style of docs
            /** @api ui addView( vid, nid, cb )
             * Adds a view to the UI.
             * <p>
             * Views are loaded/unloaded into the view content pane at
             * appropriate times, by the navigation framework. This method
             * adds a view to the UI and returns a token object representing
             * the view. A view's token is always passed as the first
             * argument to each of the view's life-cycle callback functions.
             * <p>
             * Note that if the view is directly referenced by a nav-item,
             * or in a group of views with one of those views referenced by
             * a nav-item, then the <i>nid</i> argument can be omitted as
             * the framework can infer it.
             * <p>
             * <i>cb</i> is a plain object containing callback functions:
             * "preload", "reset", "load", "unload", "resize", "error".
             * <pre>
             *     function myLoad(view, ctx) { ... }
             *     ...
             *     // short form...
             *     onos.ui.addView('viewId', {
             *         load: myLoad
             *     });
             * </pre>
             *
             * @param vid (string) [*] view ID (a unique DOM element id)
             * @param nid (string) nav-item ID (a unique DOM element id)
             * @param cb (object) [*] callbacks object
             * @return the view token
             */
            addView: function (vid, nid, cb) {
                traceFn('addView', vid);
                var view = new View(vid, nid, cb),
                    token;
                if (view.ok) {
                    views[vid] = view;
                    token = view.token();
                } else {
                    token = { vid: view.vid, bad: true };
                }
                return token;
            }
        };

        // ..........................................................
        // View API

        // TODO: deprecated
        viewApi = {
            /** @api view empty( )
             * Empties the current view.
             * <p>
             * More specifically, removes all DOM elements from the
             * current view's display div.
             */
            empty: function () {
                if (!current.view) {
                    return;
                }
                current.view.$div.html('');
            }
        };

        // ..........................................................
        // Nav API
        navApi = {

        };

        // ..........................................................
        // Library API
        libApi = {

        };

        // ..........................................................
        // Exported API

        // function to be called from index.html to build the ONOS UI
        function buildOnosUi() {
            tsB = new Date().getTime();
            tsI = tsB - tsI; // initialization duration

            console.log('ONOS UI initialized in ' + tsI + 'ms');

            if (built) {
                throwError("ONOS UI already built!");
            }
            built = true;

            $mastRadio = d3.select('#mastRadio');

            $(window).on('hashchange', hash);
            $(window).on('resize', resize);

            d3.select('body').on('keydown', keyIn);
            setupGlobalKeys();

            // Invoke hashchange callback to navigate to content
            // indicated by the window location hash.
            hash();

            // If there were any build errors, report them
            reportBuildErrors();
        }

        // export the api and build-UI function
        return {
            ui: uiApi,
            lib: libApi,
            //view: viewApi,
            nav: navApi,
            buildUi: buildOnosUi,
            exported: exported
        };
    };

}(jQuery));
