Ox.load(function() {

    var app = {
        $ui: {},
        animate: function() {
            var home = !app.url.get();
            if (home) {
                app.$ui.logo.attr({
                    src: app.getSRC('logo')
                });
                app.$ui.screen.show();
                app.$ui.label.show();
                app.$ui.menu.options({value: ''}).show();
                app.$ui.panel.find('.OxButtonGroup').css({opacity: 0});
            } else {
                app.$ui.menu.options({value: app.user('url').split('/')[0]});
            }
            [
                'screen', 'logo', 'label', 'menu', 'switch'
            ].forEach(function(element) {
                app.$ui[element].stop().animate(
                    app.getCSS(element),
                    1000,
                    element == 'screen' ? function() {
                        if (!home) {
                            app.$ui.logo.attr({
                                src: app.getSRC('logo')
                            });
                            app.$ui.panel.find('.OxButtonGroup').css({opacity: 1});
                            app.$ui.screen.hide();
                            app.$ui.label.show();
                            app.$ui.menu.hide().options({value: ''});
                        }
                    } : void 0
                );
            });
        },
        data: {},
        getCSS: function(element) {
            var css = {},
                home = !app.url.get(),
                center = Math.floor(window.innerWidth / 2),
                middle = Math.floor(window.innerHeight / 2);
            if (element == 'label') {
                css = home ? {
                    top: middle + 16 + 'px',
                    left: center - 128 + 'px',
                    width: '240px',
                    fontSize: '11px',
                    opacity: 1
                } : {
                    top: '26px',
                    left: '4px',
                    width: '32px',
                    fontSize: '1px',
                    opacity: 0
                }
            } else if (element == 'loading') {
                css.top = middle + 40 + 'px'
            } else if (element == 'logo') {
                css = home || !app.loaded ? {
                    left: center - 128 + 'px',
                    top: middle - 128 + 'px',
                    width: '256px',
                    height: '128px'
                } : {
                    top: '8px',
                    left: '8px',
                    width: '32px',
                    height: '16px'
                };
            } else if (element == 'menu') {
                css = home ? {
                    top: middle + 48 + 'px',
                    left: Math.ceil(center - app.$ui.menu.width() / 2) + 'px'
                } : {
                    top: '8px',
                    left: Math.ceil(center - app.$ui.menu.width() / 2) + 'px'
                };
            } else if (element == 'screen') {
                css.opacity = home ? 1 : 0;
            } else if (element == 'switch') {
                css = home ? {
                    top: middle + 80 + 'px',
                    right: Math.floor(center - app.$ui.switch.width() / 2) + 'px'
                } : {
                    top: '8px',
                    right: '8px'
                };
            }
            return css;
        },
        getSRC: function(element) {
            var src,
                home = !app.url.get(),
                theme = app.user('theme');
            if (element == 'icon') {
                src = 'source/Ox.UI/themes/' + theme
                    + '/png/icon16.png';
            } else if (element == 'loading') {
                src = 'source/Ox.UI/themes/' + theme
                    + '/svg/symbolLoadingAnimated.svg'
            } else if (element == 'logo') {
                src = 'source/Ox.UI/themes/' + theme
                    + '/png/logo' + (home || !app.loaded ? 128 : 16) + '.png'                
            }
            return src;
        },
        init: function() {
            app.loadScreen(function() {
                app.loadData(function() {
                    Ox.load({UI: {theme: app.theme}}, app.load);
                });
            });
        },
        load: function() {
            var url = app.url.get();
            if (url) {
                app.user({url: url})
            } else if (!app.user('url')) {
                app.user({url: 'about'});
            }
            app.$ui.panel = app.ui.panel()
                .select(app.user('url'))
                .appendTo(Ox.$body);
            // jqueryfy
            ['screen', 'logo', 'loading'].forEach(function(element) {
                app.$ui[element] = $('.' + element);
            });
            app.$ui.loading.animate({opacity: 0}, 500, function() {
                app.$ui.loading.remove();
            });
            if (!url) {
                app.$ui.logo
                    .css({cursor: 'pointer'})
                    .bind({
                        click: function() {
                            app.url.set(app.url.get() ? '' : app.user('url'));
                        }
                    });
                ['label', 'menu', 'switch'].forEach(function(element) {
                    app.$ui[element] = app.ui[element]()
                        .css({opacity: 0})
                        .appendTo(Ox.$body);
                    app.$ui[element]
                        .css(app.getCSS(element))
                        .animate({opacity: 1}, 500);
                });
            } else {
                ['label', 'menu', 'switch'].forEach(function(element) {
                    app.$ui[element] = app.ui[element]().appendTo(Ox.$body);
                    app.$ui[element].css(app.getCSS(element));
                });
                app.$ui.menu.hide();
                app.$ui.screen.animate({opacity: 0}, 500, function() {
                    app.$ui.screen.hide();
                });
                app.$ui.logo.animate({opacity: 0}, 500, function() {
                    app.$ui.logo
                        .attr({src: app.getSRC('logo')})
                        .css(app.getCSS('logo'))
                        .animate({opacity: 1}, 500, function() {
                            app.$ui.logo
                                .css({cursor: 'pointer'})
                                .bind({
                                    click: function() {
                                        app.url.set(app.url.get() ? '' : app.user('url'));
                                    }
                                });
                        });
                });
            }
            Ox.$window.bind({
                hashchange: app.urlchange
            });
            app.loaded = true;
        },
        loadData: function(callback) {
            Ox.getJSON('index.json', function(data) {
                app.data = data;
                callback();                
            });
        },
        loaded: false,
        loadScreen: function(callback) {
            app.setTheme(app.user('theme') || 'classic');            
            app.$ui.screen = app.ui.screen();
            app.$ui.loading = app.ui.loading();        
            app.$ui.logo = app.ui.logo()
                .bindOnce({
                    load: function() {
                        Ox.$('body')
                            .append(app.$ui.screen)
                            .append(app.$ui.logo)
                            .append(app.$ui.loading);
                        callback();
                    }
                });
            Ox.$(window).bind({
                resize: app.resize
            });
        },
        previousURL: '',
        re: {
            code: [
                new RegExp(
                    '<span class="OxIdentifier">Ox</span>'
                    + '(<span class="OxOperator">\.</span>'
                    + '<span class="OxIdentifier">UI</span>)?'
                    + '<span class="OxOperator">\.</span>'
                    + '<span class="OxIdentifier">([\\$\\w]+)<\/span>',
                    'g'
                ),
                function (str) {
                    return '<a href="#doc/' + Ox.stripTags(str)
                        + '" class="doclink">' + str + '</a>';
                }
            ],
            comment: [
                /\b(Ox\.\w+)\b/g,
                '<a href="#doc/$1" class="OxMonospace doclink">$1</a>'
            ]
        },
        resize: function() {
            [
                'logo', 'loading', 'label', 'menu', 'switch'
            ].forEach(function(element) {
                app.$ui[element] && app.$ui[element].css(app.getCSS(element));
            });
        },
        sections: [
            {id: 'about', title: 'About'},
            {id: 'readme', title: 'Readme'},
            {id: 'examples', title: 'Examples'},
            {id: 'doc', title: 'Documentation'},
            {id: 'downloads', title: 'Downloads'},
            {id: 'development', title: 'Development'},
            {id: 'contact', title: 'Contact'}
        ],
        setTheme: function(theme) {
            app.user({theme: theme});
            (Ox.$('#icon') || Ox.$('<link>').attr({
                id: 'icon',
                rel: 'shortcut icon',
                type: 'image/png'
            }).appendTo(Ox.$('head'))).attr({
                href: app.getSRC('icon')
            });
            app.$ui.logo && app.$ui.logo.attr({
                src: app.getSRC('logo')
            }).css(app.getCSS('logo'));
            Ox.Theme
                ? Ox.Theme(theme)
                : Ox.$('body').addClass('OxTheme' + Ox.toTitleCase(theme)
            );
        },
        ui: {
            doc: function() {
                return Ox.DocPanel({
                    files: app.data.documentation,
                    getModule: function(item) {
                        var file = item.file.replace(/^dev\//, '');
                        return file.split('/')[0];
                    },
                    getSection: function(item) {
                        var file = item.file.replace(/^dev\//, '');
                        return item.section || file.split('/')[2].split('.')[0];
                    },
                    path: 'dev/',
                    replace: [app.re.code],
                });
            },
            examples: function() {
                return Ox.ExamplePanel({
                        examples: app.data.examples,
                        keywords: /\b(Ox\.[\w]+)\b/g,
                        path: 'examples/',
                        replaceCode: [app.re.code],
                        replaceComment: [app.re.comment],
                        selected: ''
                    })
                    .bindEvent({
                        select: function(data) {
                            app.url.push(
                                'examples' + (data.id ? '/' + data.id : '')
                            )
                        }
                    });
            },
            label: function() {
                return Ox.Label({
                        textAlign: 'center',
                        title: 'A JavaScript Library for Web Applications',
                        width: 256
                    })
                    .addClass('label animate')
                    .bindEvent({
                        anyclick: function() {
                            app.url.set(app.url.get() ? '' : app.user('url'));
                        }
                    });
            },
            loading: function() {
                return Ox.$('<img>')
                    .addClass('loading')
                    .attr({src: app.getSRC('loading')})
                    .css(app.getCSS('loading'));
            },
            logo: function() {
                return Ox.$('<img>')
                    .addClass('logo animate')
                    .attr({src: app.getSRC('logo')})
                    .css(app.getCSS('logo'));
            },
            menu: function() {
                return Ox.ButtonGroup({
                        buttons: app.sections,
                        min: 0,
                        selectable: true,
                    })
                    .addClass('menu animate')
                    .bindEvent({
                        change: function(data) {
                            data.value && app.url.set(data.value);
                        }
                    })
            },
            page: function(page) {
                var $element = Ox.Container();
                Ox.get('readme/html/_' + page + '.html', function(html) {
                    $('<div>')
                        .addClass('OxSerif page')
                        .html(html)
                        .appendTo($element);
                });
                return $element;
            },
            panel: function() {
                return Ox.TabPanel({
                    content: function(id) {
                        return app.ui[id] ? app.ui[id]() : app.ui.page(id);
                    },
                    size: 32,
                    tabs: [
                        {id: 'about', title: 'About'},
                        {id: 'readme', title: 'Readme'},
                        {id: 'examples', title: 'Examples'},
                        {id: 'doc', title: 'Documentation'},
                        {id: 'downloads', title: 'Downloads'},
                        {id: 'dev', title: 'Development'},
                        {id: 'contact', title: 'Contact'}
                    ]
                })
                .bindEvent({
                    change: function(data) {
                        app.url.push(data.selected);
                    }
                });
            },
            readme: function() {
                return Ox.Element();
            },
            screen: function() {
                return Ox.$('<div>').addClass('screen animate');
            },
            switch: function() {
                return Ox.ButtonGroup({
                        buttons: [
                            {id: 'classic', title: 'Light'},
                            {id: 'modern', title: 'Dark'}
                        ],
                        selectable: true,
                        value: app.user('theme')
                    })
                    .addClass('switch animate')
                    .bindEvent({
                        change: function(data) {
                            app.setTheme(data.value);
                        }
                    });
            }
        },
        url: {
            get: function() {
                return window.location.hash.substr(1);
            },
            push: function(url) {
                history.pushState({}, '', '#' + url);
                url && app.user({url: url});
                return app;
            },
            set: function() {
                window.location.hash = '#' + arguments[0];
                return app;
            }
        },
        urlchange: function() {
            var url = app.url.get(),
                section = url.split('/')[0];
            url && app.user({url: url});
            Ox.print(
                'url', url,
                'section', section,
                'prev', app.previousURL,
                'sect', app.previousURL.split('/')[0],
                'user url', app.user('url')
            );
            if (section != app.previousURL.split('/')[0]) {
                app.$ui.panel.select(section);
            }
            app[!url || !app.previousURL ? 'animate' : 'void'](function() {
                app.previousURL = url;
            });
        },
        user: Ox.localStorage('OxJS'),
        void: function(callback) {
            callback();
        }
    };

    app.init();
    window.oxjs = app;

});


/*
Ox.load(function() {
    
    var app = {

        $ui: {},

        data: {},

        hash: '',

        fn: {

            getCSS: function() {
                return app.fn.hash() ? {
                    screen: {
                        opacity: 0
                    },
                    label: {
                        top: '26px',
                        left: '4px',
                        width: '32px',
                        fontSize: '1px',
                        opacity: 0
                    },
                    logo: {
                        top: '8px',
                        left: '8px',
                        width: '32px',
                        height: '16px'
                    },
                    menu: {
                        top: '8px',
                        width: '512px'
                    },
                    switch: {
                        top: '8px',
                        right: '8px'
                    }
                } : {
                    screen: {
                        opacity: 1
                    },
                    label: {
                        top: app.window.middle + 16 + 'px',
                        left: app.window.center - 128 + 'px',
                        width: '240px',
                        fontSize: '11px',
                        opacity: 1
                    },
                    logo: {
                        left: app.window.center - 128 + 'px',
                        top: app.window.middle - 128 + 'px',
                        width: '256px',
                        height: '128px'
                    },
                    menu: {
                        top: app.window.middle + 48 + 'px',
                        left: Math.ceil(app.window.center - app.menuWidth / 2) + 'px',
                    },
                    switch: {
                        top: app.window.middle + 80 + 'px',
                        right: Math.floor(app.window.center - app.switchWidth / 2) + 'px'
                    }
                }
            },

            getIconURL: function() {
                return 'source/Ox.UI/themes/' + app.user('theme')
                    + '/png/icon16.png';
            },

            getLogoURL: function() {
                return 'source/Ox.UI/themes/' + app.user('theme')
                    + '/png/logo' + (app.fn.hash() ? 16 : 128) + '.png'
            },

            getLogoCSS: function() {
                return {
                    boxShadow: '0 0 1px ' + (
                        app.user('theme') == 'classic'
                        ? 'rgb(0, 0, 0)'
                        : 'rgb(255, 255, 255)'
                    )
                };
            },

            hash: function() {
                var len = arguments.length, ret;
                if (len == 0) {
                    ret = window.location.hash.substr(1);
                } else {
                    window.location.hash = '#' + arguments[0];
                    ret = app;
                }
                return ret;
            },

            hashchange: function() {
                return;
                var hash = app.fn.hash(),
                    section = hash.split('/')[0];
                app.fn[!hash || !app.hash ? 'animate' : 'void'](function() {
                    if (section != app.hash.split('/')[0]) {
                        app.fn.setSection(section);
                    }
                    hash && app.user({hash: hash});
                    app.hash = hash;                  
                });
            },

            load: function() {
                app.fn.setTheme(app.user('theme') || 'classic')
                app.window = app.fn.window();
                var theme = app.user('theme') || 'classic',
                    $body = Ox.$('body'),
                    $screen = Ox.$('<div>')
                        .addClass('loading screen');
                    $icon = Ox.$('<img>')
                        .addClass('loading icon')
                        .attr({
                            src: 'build/Ox.UI/themes/'
                                + theme + '/svg/symbolLoadingAnimated.svg'
                        })
                        .css({
                            top: app.window.middle + 40 + 'px'
                        })
                        .appendTo($screen);                    
                    $logo = Ox.$('<img>')
                        .addClass('loading logo')
                        .attr({
                            src: 'build/Ox.UI/themes/'
                                + theme + '/png/logo128.png'
                        })
                        .css({
                            left: app.window.center - 128 + 'px',
                            top: app.window.middle - 128 + 'px'
                        })
                        .bind({
                            load: function() {
                                $screen.appendTo($body);
                                $logo.appendTo($body);
                            }
                        })
                Ox.$(window).bind({
                    hashchange: app.fn.hashchange,
                    resize: app.fn.resize
                });
                setTimeout(function() {
                    Ox.getJSON('index.json', function(data) {
                        app.data = data;
                        Ox.load({UI: {theme: theme}}, function() {
                            app.$ui.panel = app.ui.panel().appendTo(Ox.$body);
                            app.$ui.panel.find('.OxButtonGroup').css({opacity: 0});

                            !app.user('hash') && app.user({hash: 'about'});
                            app.fn.hashchange();
                            app.$ui.screen = $('.screen');
                            app.$ui.logo = $('.logo')
                                .bind({
                                    click: function() {
                                        app.fn.hash(
                                            app.fn.hash() ? '' : app.user('hash')
                                        );
                                        app.fn.animate();
                                    }
                                });
                            $('.icon').animate({opacity: 0}, 1000, function() {
                                $('.icon').remove();
                            });
                            ['label', 'menu', 'switch'].forEach(function(element) {
                                app.$ui[element] = app.ui[element]()
                                    .appendTo(Ox.$body);
                            });
                            app.menuWidth = app.$ui.menu.width();
                            app.switchWidth = app.$ui.switch.width();
                            css = app.fn.getCSS();
                            ['label', 'menu', 'switch'].forEach(function(element) {
                                app.$ui[element]
                                    .css(Ox.extend(css[element], {opacity: 0}))
                                    .animate({opacity: 1}, 1000);
                            });
                        });
                    });
                }, 2500);
            },

            resize: function() {
                app.window = app.fn.window();
                Ox.forEach(app.fn.getCSS(), function(css, element) {
                    app.$ui[element].css(css);
                });
            },

            setSection: function(section) {
                app.$ui.panel.replaceElement(1, app.ui[section]
                    ? app.ui[section]() : app.ui.page(section)
                );
            },

            setTheme: function(theme) {
                app.user({theme: theme});
                (Ox.$('#icon') || Ox.$('<link>').attr({
                    id: 'icon',
                    rel: 'shortcut icon',
                    type: 'image/png'
                }).appendTo(Ox.$('head'))).attr({
                    href: app.fn.getIconURL()
                });
                app.$ui.logo && app.$ui.logo.attr({
                    src: app.fn.getLogoURL()
                }).css(app.fn.getLogoCSS());
                Ox.Theme ? Ox.Theme(theme) : Ox.$('body').addClass(
                    'OxTheme' + Ox.toTitleCase(theme)
                );
            },

            void: function(callback) {
                callback();
            },

            window: function() {
                return {
                    center: Math.floor(window.innerWidth / 2),
                    height: window.innerHeight,
                    middle: Math.floor(window.innerHeight / 2),
                    width: window.innerWidth
                };
            }

        },

        re: {

            code: [
                new RegExp(
                    '<span class="OxIdentifier">Ox</span>'
                    + '(<span class="OxOperator">\.</span>'
                    + '<span class="OxIdentifier">UI</span>)?'
                    + '<span class="OxOperator">\.</span>'
                    + '<span class="OxIdentifier">([\\$\\w]+)<\/span>',
                    'g'
                ),
                function (str) {
                    return '<a href="#doc/' + Ox.stripTags(str)
                        + '" class="doclink">' + str + '</a>';
                }
            ],
            comment: [
                /\b(Ox\.\w+)\b/g,
                '<a href="#doc/$1" class="OxMonospace doclink">$1</a>'
            ]

        },



        user: Ox.localStorage('OxJS')

    };

    app.fn.load();

    window.oxjs = app; // so that you can play with it in the console  

});
*/