/**
 * (C) Copyright Collin Doering 2013
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * File:. default.js
 * Author: Collin J. Doering
 * Date: Sep  6, 2013
 * Description: Client-side logic for blog-rekahsoft-ca
 */

//------------------------
/*jslint browser: true*/
/*global jQuery, MathJax*/
//------------------------

// Global array for processing piwik analytics commands
var _paq = _paq || [];
_paq.push(["setDoNotTrack", true]);
_paq.push(['enableLinkTracking']);

// Asynchronously load piwik.js
(function() {
  var u="//analytics.rekahsoft.ca/";
  _paq.push(['setTrackerUrl', u+'piwik.php']);
  _paq.push(['setSiteId', 1]);
  var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
  g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
})();

(function ($, mj) {
    "use strict";

    var router = (function () {
        var routes = [
            { // Post pages handler
                acceptUrls: /posts\/.*\.html/,
                ajaxCallbacks: {
                    beforeSend: function () {
                        $('#nav-menu li.active').removeClass('active');
                        $('#nav-menu li a[href="/blog.html"]').parent('li').addClass('active');
                    }
                }
            },
            { // Tag pages handler
                acceptUrls: /tags\/.*(\d*)\.html/,
                ajaxCallbacks: {
                    beforeSend: function () {
                        $('#nav-menu li.active').removeClass('active');
                        $('#nav-menu li a[href="/blog.html"]').parent('li').addClass('active');
                    }
                }
            },
            { // Blog pages handler
                acceptUrls: /blog\d*\.html/,
                ajaxCallbacks: {
                    beforeSend: function () {
                        // Set the blog menuitem as active
                        $('a.menuitem[href="/blog.html"]').closest('ul').find('li.active').removeClass('active');
                        $('a.menuitem[href="/blog.html"]').closest('li').addClass('active');
                    }
                }
            },
            { // Default page handler
                acceptUrls: /.*/,
                ajaxCallbacks: {
                    beforeSend: function (url) {
                        if (url === "/") {
                            url = "/index.html";
                        }

                        // Initially set the active menuitem in the nav
                        $('a.menuitem[href="' + url + '"]').closest('ul').find('li.active').removeClass('active');
                        $('a.menuitem[href="' + url + '"]').closest('li').addClass('active');
                    }
                }
            }],
            callback = function () { return null; },

            spec = {
                runRouter: function runRouter(url) {
                    var i;
                    for (i = 0; i < routes.length; i += 1) {
                        if (routes[i].acceptUrls.test(url)) {
                            if (url === "/index.html") {
                                history.pushState(null, "Home", "/");
                            } else {
                                // TODO: strip url into title
                                history.pushState(null, "Title", url);
                            }
                            callback(url, routes[i].ajaxCallbacks);
                            break;
                        }
                    }
                },
                setCallback: function setCallback(cb) {
                    if (typeof cb === 'function') {
                        callback = cb;
                    }
                }
            };

        return spec;
    }()),

    page = (function () {
        // var pageId = '#page-content', navId = '#nav';

        function loadPageContent(page_href, handlerCallback) {
            // Track page view with piwik
            _paq.push(['setDocumentTitle', document.domain + page_href]);
            _paq.push(['trackPageView']);

            $.ajax({
                url: page_href,
                type: 'GET',
                dataType: 'html',
                beforeSend: function (xhr, settings) {
                    // Add .loading to #page-content and #nav to facilitate a loading animation
                    $('#page-content, #nav').removeClass('loading-done').addClass('loading');

                    // Run current handlers onSuccess callback (if it exists)
                    if (handlerCallback.hasOwnProperty('beforeSend') && typeof handlerCallback.beforeSend === 'function') {
                        handlerCallback.beforeSend(page_href);
                    }

                    console.log('beforeSend a.menuitem');
                },
                success: function (dta) {
                    // Remove any status message errors or successes
                    $('#status').slideUp('normal', function () {
                        $('#status').removeClass('error').removeClass('success').children('p.message').remove();
                    });

                    // Stop animations in the nav and page-content and scroll to the top of the page in a set amount of time
                    setTimeout(function () {
                        // Replace old page-content with new page-content
                        dta = $($.parseHTML(dta)).filter('#page-content').html();
                        $('#page-content').html(dta);

                        // Stop page loading
                        $('#page-content, #nav').removeClass('loading');

                        // Reload any new maths using MathJax
                        $('#page-content .math').each(function (math_elem) {
                            mj.Hub.Queue(["Typeset", mj.Hub, math_elem[0]]);
                        });

                        // Add anchor click handlers for internal links in new content loaded into #page-content
                        jsUrls('#page-content a');

                        // Add fullscreen functionality to inline-images and figures
                        $('article.post p > img').click(function () {
                            $(this).get(0).toggleFullScreen();
                        });
                        $('figure').click(function () {
                            $(this).children('img').get(0).toggleFullScreen();
                        });

                        // Run current handles onSuccess callback (if it exists)
                        if (handlerCallback.hasOwnProperty('onSuccess') && typeof handlerCallback.onSuccess === 'function') {
                            handlerCallback.onSuccess();
                        }

                        // Scroll to top of the page
                        if ($('body').scrollTop() > $('#nav').offset().top - 15) {
                            $('html, body').animate({
                                scrollTop: $('#nav').offset().top - 15
                            }, 'fast');
                        }
                    }, 250);
                },
                error: function (xhr, status) {
                    /* Remove .loading from #page-content and #nav to stop the loading
                     * animation. Finally, display an error message in #status.
                     */
                    $('#page-content, #nav').removeClass('loading');

                    // TODO: instead of immediately displaying error, check if the content is stored in local storage
                    $('#status').prepend('<p class="message">Error retrieving page ' + page_href + '</p>');
                    $('#status').addClass('error').slideDown();

                    // Run current handles onError callback (if it exists)
                    if (handlerCallback.hasOwnProperty('onError') && typeof handlerCallback.onError === 'function') {
                        handlerCallback.onError();
                    }
                }
            });
        }

        function jsUrls(sel) {
            $(sel).each(function (i) {
                var href = $(this).attr('href'),
                    external_url_regexp = /https?:\/\/.*/,
                    mailto_regexp = /mailto:.*/,
                    files_regexp = /files\/.*/,
                    images_regexp = /images\/.*/;

                if (!(external_url_regexp.test(href) || mailto_regexp.test(href) || files_regexp.test(href) || images_regexp.test(href))) {
                    $(this).click(function (e) {
                        e.preventDefault();
                        router.runRouter(href);
                    });
                }
            });
        }

        function init(router) {
            router.setCallback(loadPageContent);

            window.addEventListener("popstate", function (e) {
                router.runRouter(location.pathname);
            });

            $(document).ready(function () {
                $('#nav-menu a.menuitem').click(function () {
                    $(this).closest('ul').find('li.active').removeClass('active');
                    $(this).closest('li').addClass('active');
                    //$('.navbar-collapse').collapse('hide');
                });

                $('#status a.close-button').click(function () {
                    $(this).parent().slideUp(function () {
                        $(this).removeClass('error').removeClass('success');
                        $(this).children('p.message').remove();
                    });
                });

                // Add anchor click handlers for internal links
                jsUrls('#page-content a, #nav-menu a.menuitem');
            });
        }

        var spec = {
            init: init
        };
        return spec;
    }());

    page.init(router);
}(jQuery, MathJax));

// Modified from: https://developer.mozilla.org/en-US/docs/Web/Guide/API/DOM/Using_full_screen_mode
function toggleFullScreen() {
    if (!document.fullscreenElement &&    // alternative standard method
        !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement ) {  // current working methods
        if (document.documentElement.requestFullscreen) {
            this.requestFullscreen();
        } else if (document.documentElement.msRequestFullscreen) {
            this.msRequestFullscreen();
        } else if (document.documentElement.mozRequestFullScreen) {
            this.mozRequestFullScreen();
        } else if (document.documentElement.webkitRequestFullscreen) {
            this.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
        }
    } else {
        if (document.exitFullscreen) {
            document.exitFullscreen();
        } else if (document.msExitFullscreen) {
            document.msExitFullscreen();
        } else if (document.mozCancelFullScreen) {
            document.mozCancelFullScreen();
        } else if (document.webkitExitFullscreen) {
            document.webkitExitFullscreen();
        }
    }
}

Element.prototype.toggleFullScreen = toggleFullScreen;
