'use strict';

(function(global) {

    global.Ox = {

        load: function() {

            var args = arguments,
                callback = args[args.length - 1],
                path = getPath(),
                time = +new Date();

            if (args[0] === true) {
                path = path.replace(/dev\/$/, 'build/');
                loadScript('Ox.js', function() {
                    Ox.PATH = path;
                    Ox.load.apply(null, Ox.slice(args, 1));
                });
            } else {
                loadJSON(function(data) {
                    var previousOx = global.Ox;
                    loadScriptsSerial(data.files, function() {
                        Ox.VERSION = data.version;
                        Ox.forEach(previousOx, function(value, key) {
                            if (Ox.isUndefined(Ox[key])) {
                                Ox[key] = value;
                            }
                        });
                        Ox.load.apply(null, args);
                    });
                });
            }

            function getPath() {
                var i, path, scripts = document.getElementsByTagName('script');
                for (i = 0; i < scripts.length; i++) {
                    if (/Ox\.js$/.test(scripts[i].src)) {
                        path = scripts[i].src.replace(/Ox\.js$/, '');
                    }
                }
                return path;
            }

            function loadJSON(callback) {
                var request = new XMLHttpRequest(); 
                request.open('GET', path + 'Ox/json/Ox.json?' + time, true);
                request.onreadystatechange = function() {
                    if (request.readyState == 4) {
                        if (request.status == 200) {
                            callback(JSON.parse(request.responseText));
                        }
                    }
                };
                request.send();
            }

            function loadScriptsSerial(scripts, callback) {
                loadScriptsParallel(scripts.shift(), function() {
                    if (scripts.length) {
                        loadScriptsSerial(scripts, callback);
                    } else {
                        callback();
                    }
                });
            }

            function loadScriptsParallel(scripts, callback) {
                var counter = 0, length = scripts.length;
                while (scripts.length) {
                    loadScript(scripts.shift(), function() {
                        ++counter == length && callback();
                    });
                }
            }

            function loadScript(script, callback) {
                var element = document.createElement('script'),
                    head = document.head
                        || document.getElementsByTagName('head')[0]
                        || document.documentElement;
                if (/MSIE/.test(navigator.userAgent)) {
                    // FIXME: find a way to check if css/js have loaded in MSIE
                    setTimeout(callback, 2500);
                } else {
                    element.onload = callback;
                }
                element.src = path + script + '?' + time;
                element.type = 'text/javascript';
                head.appendChild(element);
            }

        }

    };

}(this));
