/*
 * 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,
                viewGestures: []
            },
            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: [quickHelp, 'Show / hide Quick Help'],
                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 quickHelp(view, key, code, ev) {
            libApi.quickHelp.show(keyHandler);
            return true;
        }

        function escapeKey(view, key, code, ev) {
            if (alerts.open) {
                closeAlerts();
                return true;
            }
            if (libApi.quickHelp.hide()) {
                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 setGestureNotes(g) {
            keyHandler.viewGestures = isA(g) || [];
        }

        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,
                    setGestures: this.setGestures,
                    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);
            },

            setGestures: function (g) {
                setGestureNotes(g);
            },

            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));
