/*global window, navigator, document, onReady*/

function onReady(f) {
    // Attach the listeners
    onReady.bindReady();

    // If the DOM is already ready
    if (onReady.isReady) {
        // Execute the function immediately
        f.call(window);
        // Otherwise, remember the function for later
    } else {
        // Add the function to the wait list
        onReady.readyList.push(function () {
            return f.call(window);
        });

        return this;
    }
}

onReady.isReady = false;
onReady.readyList = [];
onReady.ready = function () { // Handle when the DOM is ready
    // Make sure that the DOM is not already loaded
    if (!onReady.isReady) {
        // Remember that the DOM is ready
        onReady.isReady = true;

        // If there are functions bound, to execute
        if (onReady.readyList) {
            // Execute all of them
            var numCalls = onReady.readyList.length,
                i = 0;

            for (; i < numCalls; i += 1) {
                onReady.readyList[i].call(window);
            }

            // Reset the list of functions
            onReady.readyList = null;
        }
    }
};

onReady.readyBound = false;

onReady.bindReady = function () {
    if (onReady.readyBound) {
        return;
    }
    onReady.readyBound = true;

    // Most browsers support this
    if (document.addEventListener) {
        // Use the handy event callback
        document.addEventListener("DOMContentLoaded", onReady.ready, false);
    }

    // A fallback to window.onload, that will always work
    if (window.addEventListener) {
        window.addEventListener('load', onReady.ready, false);
    } else if (window.attachEvent) {
        window.attachEvent("onload", onReady.ready);
    } else {
        var oldonload = window.onload;
        window.onload = function () {
            if (oldonload) {
                oldonload.call(window);
            }
            onReady.ready();
        };
    }
};

onReady.addEventHandler = function (element, event, fn, scope) {
    scope = scope || window;

    if (element.addEventListener) {
        element.addEventListener(event, function () {
            fn.apply(scope, arguments);
        }, false);
    } else if (element.attachEvent) {
        element.attachEvent('on' + event, function () {
            fn.apply(scope, arguments);
        });
    }
};


var UrlRewriter = function () {
    var userAgent = navigator.userAgent.toLowerCase(),
        isMobile = userAgent.indexOf('mobile') !== -1 ||
            userAgent.indexOf('iphone') !== -1 ||
            userAgent.indexOf('blackberry') !== -1 ||
            (document.cookie.match(/is_mobile=true/) &&
            !document.cookie.match(/is_mobile=false/)),
        instance;

    instance = (function () {
        var urlRewriter = this,
            frame = document.getElementById('mainFrame'),
            hashCurrent = window.location.hash,
            domain,
            blogLocation,
            frameSrc;

        return {
            init: function () {
                var srcOriginal = frame.src,
                    matches = srcOriginal.match(/iloapp.([^\/]+)\/blog\/([^\?\#]+)/);

                if (matches) {
                    domain = matches[1];
                    blogLocation = matches[2];
                    frameSrc = 'http://iloapp.' + domain + '/blog/' + blogLocation + '?';

                    if (isMobile) {
                        // Show mobile version without frame
                        window.location = 'http://iloapp.' + domain + '/blog/' + blogLocation + '?Mobile';
                    } else {
                        if (hashCurrent === '') {
                            this.updateHash('home');
                        } else {
                            this.updateFrame();
                        }

                        if (window.history) {
                            onReady.addEventHandler(window, 'popstate', function (e) {
                                if (hashCurrent !== window.location.hash) {
                                    this.updateFrame();
                                }
                            }, this);
                        } else if ('onhashchange' in window) {
                            onReady.addEventHandler(window, 'hashchange', function (e) {
                                if (hashCurrent !== window.location.hash) {
                                    this.updateFrame();
                                }
                            }, this);
                        }

                        if (window.postMessage) {
                            onReady.addEventHandler(window, 'message', function (e) {
                                this.updateHash(e.data);
                            }, this);
                        }
                    }
                }
            },

            updateFrame: function () {
                hashCurrent = window.location.hash;

                var src = this.hashToSrc(hashCurrent);

                if (frame.src !== src) {
                    frame.src = src;
                }
            },

            updateHash: function (message) {
                var hash = '#' + message;
                // Set hash according to message
                if (hashCurrent !== hash) {
                    hashCurrent = hash;
                    if (window.history && window.history.replaceState) {
                        window.history.replaceState({message: message}, '', hash);
                    } else {
                        window.location.hash = hash;
                    }
                }
            },

            hashToSrc: function (hash) {
                var matches = hash.match(/^#home(\.(\d+))?$/),
                    src = frameSrc,
                    field, id, page;

                if (matches) {
                    // Requesting home page
                    if (matches[2] !== undefined) {
                        //Include page number
                        src += 'Home&page=' + matches[2];
                    } else {
                        src += 'Home';
                    }
                } else {
                    matches = hash.match(/^#(post|comments|category|user)?(\d+)(?:\.(\d+))?/);

                    if (matches) {
                        field = matches[1];
                        id = matches[2];
                        page = matches[3];

                        // Set frame src
                        if (field === 'comments') {
                            src += 'NewComment&post=' + id;
                        } else if (field === 'post' || field === 'category' || field === 'user') {
                            src += 'Home&' + field + '=' + id;
                        }

                        // Add page if included
                        if (page !== undefined) {
                            src += '&page=' + page;
                        }
                    }
                }

                return src;
            }
        };
    }());

    UrlRewriter = function () {
        instance.init();
        return instance;
    };

    return UrlRewriter();
};

onReady(function () {
    var urlRewriter = new UrlRewriter();
});

