/*
 * wq.app v1.1.2 - @wq/router 1.1.2
 * Respond to URL changes with locally generated pages and custom events
 * (c) 2012-2019, S. Andrew Sheppard
 * https://wq.io/license
 */

define(['./template', 'jquery.mobile.router'], function (tmpl, jqmr) { 'use strict';

tmpl = tmpl && tmpl.hasOwnProperty('default') ? tmpl['default'] : tmpl;
jqmr = jqmr && jqmr.hasOwnProperty('default') ? jqmr['default'] : jqmr;

function _defineProperty(obj, key, value) {
  if (key in obj) {
    Object.defineProperty(obj, key, {
      value: value,
      enumerable: true,
      configurable: true,
      writable: true
    });
  } else {
    obj[key] = value;
  }

  return obj;
}

function _objectSpread(target) {
  for (var i = 1; i < arguments.length; i++) {
    var source = arguments[i] != null ? arguments[i] : {};
    var ownKeys = Object.keys(source);

    if (typeof Object.getOwnPropertySymbols === 'function') {
      ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) {
        return Object.getOwnPropertyDescriptor(source, sym).enumerable;
      }));
    }

    ownKeys.forEach(function (key) {
      _defineProperty(target, key, source[key]);
    });
  }

  return target;
}

var router = {
    config: {
        tmpl404: '404',
        injectOnce: false,
        debug: false
    },
    slug: '([^/?#]+)',
    query: '(?:[?](.*))?(?:[#](.*))?$'
};

var $, jqm, _jqmRouter; // Configuration


router.init = function (config) {
    // Define baseurl (without trailing slash) if it is not /
    if (config && config.base_url) {
        router.info.base_url = config.base_url;
    }

    router.config = _objectSpread({}, router.config, config);
    $ = config.jQuery || window.jQuery;
    jqmr($);
    jqm = $.mobile; // Configuration options:
    // Define `tmpl404` if there is not a template named '404'
    // Set `injectOnce`to true to re-use rendered templates
    // Set `debug` to true to log template & context information

    _jqmRouter = new jqm.Router(undefined, undefined, {
        ajaxApp: true
    });
};

router.jqmInit = function () {
    if (!router.config) {
        throw new Error('Initialize router first!');
    }

    jqm.initializePage();
}; // Register URL patterns to override default JQM behavior and inject router
// Callback fn should call router.go() with desired template


router.register = function (path, fn, obj, prevent) {
    var events = 'bC';

    if (!fn) {
        fn = function (match, ui, params) {
            // Assume there is a template with the same name
            router.go(path, path, params, ui);
        };
    }

    if (prevent === undefined) {
        prevent = function (match, ui, params) {
            /* eslint no-unused-vars: off */
            // By default, prevent default changePage behavior
            // (unless this is a form post and is not being handled by app.js)
            if (ui && ui.options && ui.options.data && ui.options.fromPage) {
                var $form = ui.options.fromPage.find('form');
                var dataJson = $form.data('wq-json');

                if (dataJson !== undefined && !dataJson) {
                    return false;
                }
            }

            return true;
        };
    }

    var callback = function (match, ui, params, hash, evt, $page) {
        var curpath = jqm.activePage && jqm.activePage.jqmData('url'); // Capture URLs only, not completed pages

        if (typeof ui.toPage !== 'string') {
            return;
        } // Don't handle urls that app.js specifically marked for server loading


        if (ui.options && ui.options.wqSkip) {
            return;
        } // Avoid interfering with hash updates when popups open & close


        if ((curpath == match[0] || curpath + '#' + hash == match[0]) && !ui.options.allowSamePageTransition) {
            return;
        } // Prevent default changePage behavior?


        if (typeof prevent === 'function' && prevent(match, ui, params)) {
            evt.preventDefault();
        } else if (typeof prevent !== 'function' && prevent) {
            evt.preventDefault();
        }

        fn = typeof fn == 'string' ? obj[fn] : fn;
        fn(match, ui, params, hash, evt, $page);
    };

    router.addRoute(path, events, callback);
}; // Wrapper for router.add - adds URL base and parameter regex to path


router.addRoute = function (path, events, fn, obj) {
    var rt = {};
    path = path.replace(/<slug>/g, router.slug);
    var url = '^' + router.info.base_url + '/' + path + router.query;

    var callback = function (etype, match, ui, page, evt) {
        var hash = match.pop();
        var params = router.getParams(match.pop());
        fn = typeof fn == 'string' ? obj[fn] : fn;
        fn(match, ui, params, hash, evt, $(page));
    };

    rt[url] = {
        events: events,
        handler: callback,
        step: 'all'
    };

    _jqmRouter.add(rt);
}; // Update router path


router.setPath = _updateInfo; // Inject and display page

router.go = function (path, template, context, ui, once, pageid) {
    _updateInfo(path, context);

    var url = router.info.full_path;

    if (router.config.debug) {
        console.log('Rendering ' + url + " with template '" + template + "' and context:");
        console.log(context);
    }

    var $page, role, options;
    once = once || router.config.injectOnce;

    if (once) {
        // Only render the template once
        $page = tmpl.injectOnce(template, context, url, pageid);
    } else {
        // Default: render the template every time the page is loaded
        $page = tmpl.inject(template, context, url, pageid);
    }

    role = $page.jqmData('role');

    if (role == 'page') {
        options = ui && ui.options || {};
        options._jqmrouter_bC = true;

        if (once) {
            options.allowSamePageTransition = true;
        }

        jqm.changePage($page, options);
    } else if (role == 'popup') {
        options = {};

        if (ui && ui.options) {
            options.transition = ui.options.transition;
            options.positionTo = $page.data('wq-position-to');
            var link = ui.options.link;

            if (link) {
                if (link.jqmData('position-to')) {
                    options.positionTo = link.jqmData('position-to');
                } // 'origin' won't work since we're opening the popup manually


                if (!options.positionTo || options.positionTo == 'origin') {
                    options.positionTo = link[0];
                } // Remove link highlight *after* popup is closed


                $page.bind('popupafterclose.resetlink', function () {
                    link.removeClass('ui-btn-active');
                    $(this).unbind('popupafterclose.resetlink');
                });
            }
        }

        $page.popup('open', options);
    } else if (role == 'panel') {
        $page.panel('open');
    }

    return $page;
}; // Simple 404 page helper


router.notFound = function (url, ui) {
    var context = {
        url: url
    };
    router.go(url, router.config.tmpl404, context, ui);
}; // Mimics Router.getParams()


router.getParams = function (search) {
    return _jqmRouter.getParams(search);
}; // Context variable (accessible in templates via router_info)


router.info = {
    base_url: ''
};

function _updateInfo(path, context) {
    router.info.prev_path = router.info.path;
    router.info.path = path;
    router.info.path_enc = escape(path);
    router.info.full_path = router.info.base_url + '/' + path;
    router.info.full_path_enc = escape(router.info.full_path);
    router.info.params = router.getParams(path.split('?')[1]);

    if (context) {
        router.info.context = context;
    }

    tmpl.setDefault('router_info', router.info);
    tmpl.setDefault('rt', router.info.base_url);
}

return router;

});
