/*
 * Geschreven door Pauwels edo <edo.pauwels@gmail.com>
 * Laatst bewerkt op 2010-11-28 (zondag 28 November)
 * 
 * Maakt gebruik van volgende scripts:
 * - jQuery version 1.4.2 http://jquery.com/
 * - jQuery Address plugin version 1.3 http://www.asual.com/jquery/address/ 
 * - jQuery SWFObject plugin version 1.1.1 http://jquery.thewikies.com/swfobject/
 * - jQuery Unselectable plugin http://plugins.jquery.com/project/Unselectable
 *
 * Getest op volgende browsers/systemen:
 * - msie 7+        windows
 * - firefox        windows, osx
 * - safari         windows, osx
 * - google chrome  windows, osx
 * - opera          windows
 */

////////////////////////////////////////////////////////////////////////////////
//
//  TODO:
//  - de 'standaard' deeplink een willekeurig project toewijzen.
//  - video speler aanpassen en installeren.
//
////////////////////////////////////////////////////////////////////////////////

(function($) {
    
    $.EDOCODE = function() { // Namespace
        
        // Globale variabelen
        
        var Variabelen = {
            xml: null,
            talen: ['en','nl','fr'],
            taal: 'en',
            tekstMoetWordenGetoont: true,
            tekstWordtGetoont: false,
            deeplinks: [
                'projects/brasserie-van-loock',
                'projects/fortis-brussels',
                'projects/hippodroom-antwerp',
                'projects/hotel-bristol-paris/1',
                'projects/kvs-brussels/1',
                'projects/royal-museum-brussels',
                'projects/villers-college/1',
                'projects/wzi-eindhoven/1'
            ],
            deeplink: null
        };
        
        // Helper functies (alphabetisch geordend)
        
        var Helper = function() {
            // Prive
            
            var preloadAfbeelding;
            
            return {
                // Publiek
                
                /**
                 * Zorgt ervoor dat de afbeelding het volledige scherm vult en
                 * de verhoudingen behouden worden. De afmetingen worden uit het
                 * data object van het doelwit gehaald.
                 * @returns {void}
                 */
                
                afbeeldingVulScherm: function() {
                    var afbeelding = $('#AchtergrondAfbeelding');
                    var afmetingen = afbeelding.data('afmetingen');
                    if (afmetingen) {
                        var verhouding = afmetingen.breedte / afmetingen.hoogte;
                        var breedte = $(window).width();
                        var hoogte = $(window).height();
                        
                        if (verhouding < breedte / hoogte) {
                            afbeelding.width(Math.ceil(breedte));
                            afbeelding.height(Math.ceil(breedte / verhouding));
                        } else {
                            afbeelding.width(Math.round(hoogte * verhouding));
                            afbeelding.height(Math.round(hoogte));
                        }
                        afbeelding.css({
                           'left': Math.round((breedte - afbeelding.width()) / 2) + 'px',
                           'top': Math.round((hoogte - afbeelding.height()) / 2) + 'px'
                        });
                    }
                },
                
                /**
                 * Maakt een tekst klaar voor gebruik als url.
                 * @param waarde {string}
                 * @returns {string}
                 *
                 * Gebaseerd op:
                 * http://renownedmedia.com/codevault/Clean_URL_Generator
                 */
                
                alsUrl: function(waarde) {
                    if (waarde === null) {
                        return null;
                    }
                    var url = waarde
                        .toLowerCase()
                        .replace(/^\s+|\s+$/g, '')
                        .replace(/[\-|\s]+/g, '-')
                        .replace(/[^a-z0-9\-]+/g, '')
                        .substring(0,40)
                        .replace(/[\-]+/g, '-')
                        .replace(/^\-+|\-+$/g, '')
                    ; 
                    return url;
                },
                
                /**
                 * Loopt door alle paginas en vergelijkt deze met de url,
                 * indien er geen gelijke wordt gevonden wordt er -1 terug gegeven.
                 * @param paginaUrl {string}
                 * @returns {int}
                 */
                
                bepaalPaginaIndex: function(paginaUrl) {
                    var paginaIndex = -1;
                    if (paginaUrl) {
                        $('#Navigatie > li > a').each(function(i) {
                            if (Helper.alsUrl($(this).text()) === paginaUrl) {
                                paginaIndex = i;
                                return;
                            }
                        });
                    }
                    return paginaIndex;
                },
                
                /**
                 * Loopt door alle items en vergelijkt deze met de url,
                 * indien er geen gelijke wordt gevonden wordt er -1 terug gegeven.
                 * @param paginaXml {xml}
                 * @param itemUrl {string}
                 * @returns {int}
                 */
                
                bepaalItemIndex: function(paginaXml, itemUrl) {
                    var itemIndex = -1;
                    if (itemUrl) {
                        paginaXml.find('item').each(function(i) {
                            if (Helper.alsUrl($(this).attr('label')) === itemUrl) {
                                itemIndex = i;
                                return;
                            }
                        });
                    }
                    return itemIndex;
                },
                
                /**
                 * Toont een afbeelding.
                 * @param src {string}
                 * @returns {void}
                 */
                
                toonAfbeelding: function(src) {
                    preloadAfbeelding = new Image();
                    preloadAfbeelding.src = src;
                    
                    function bijAfbeeldingGeladen() {
                        $('#Swf').html('');
                        $('#Preloader').css('display','none');
                        $('#AchtergrondAfbeelding').attr('src', src);
                        Helper.afbeeldingVulScherm();
                    }
                    
                    if (preloadAfbeelding.complete) {
                        bijAfbeeldingGeladen();
                    } else {
                        preloadAfbeelding.onload = bijAfbeeldingGeladen;
                    }
                },
                
                /**
                 * Toont een film, maakt gebruik van het film.swf bestand.
                 * @param src {string}
                 * @returns {void}
                 */
                
                toonFilm: function(src) {
                    $('#Swf').html('').flash({
                        swf : 'bibliotheek/flash/speler.swf?cacheThis='+Math.floor(Math.random() * 9999999),
                        width : '100%',
                        height : '100%',
                        wmode : 'transparent',
                        flashvars : { path : 'film/' + src }
                    });
                },
                
                /**
                 * Toont een flash bestand
                 * @opmerking preloader moet verwijdert worden van binnen in
                 * het swf bestand via ExternalInterface.call("$(#Preloader).css('display','none');");
                 * @param src {string}
                 * @returns {void}
                 */
                
                toonFlash: function(src) {
                    $('#Swf').html('').flash({
                        swf : 'bibliotheek/flash/' + src + '?cacheThis='+Math.floor(Math.random() * 9999999),
                        width : '100%',
                        height : '100%',
                        wmode : 'transparent'
                    });
                },
                
                /**
                 * Verandert de deeplink zonder geschiedenis bij te houden.
                 * @param deeplinks {array}
                 * @returns {void}
                 */
                
                redirect: function(deeplinks) {
                    var deeplink;
                    if (deeplinks) {
                        deeplink = deeplinks.join('/');
                    } else {
                        deeplink = Variabelen.deeplink;
                    }
                    $.address.history(false);
                    $.address.value(deeplink);
                    $.address.history(true);
                }
            };
        }(); // Helper einde
        
        // Alle functies die nodig zijn voor het instellen van de site.
        // alphabetisch geordend
        
        var Setup = function() {
            // Privˇ
            
            /**
             * Maakt alle hover-effecten voor de site.
             * @returns {void}
             */
            
            function hoverEffecten() {
                
                // De pagina navigatie, pas opacity & rand aan
                
                $('.paginaItem')
                .css({
                    'padding': '1px 0',
                    'opacity': '.5', /* Standard: FF gt 1.5, Opera, Safari */
                    'filter': 'alpha(opacity=50)', /* IE lt 8 */
                    '-ms-filter': '"alpha(opacity=50)"', /* IE 8 */
                    '-khtml-opacity': '.5', /* Safari 1.x */
                    '-moz-opacity': '.5' /* FF lt 1.5, Netscape */
                })
                .hover(function() {
                    $(this).css({
                        'padding-top' : '0',
                        'border-top' : '1px solid #fff',
                        'opacity': '1',
                        'filter': 'alpha(opacity=100)',
                        '-ms-filter': '"alpha(opacity=100)"',
                        '-khtml-opacity': '1',
                        '-moz-opacity': '1'
                    });
                }, function() {
                    var $this = $(this);
                    if (!$this.hasClass('geselecteerd')) {
                        $this.css({
                            'padding-top' : '1px',
                            'border-top' : 'none',
                            'opacity': '.5',
                            'filter': 'alpha(opacity=50)',
                            '-ms-filter': '"alpha(opacity=50)"',
                            '-khtml-opacity': '.5',
                            '-moz-opacity': '.5'
                        });
                    }
                });
                
                // dropdown, highlight eerste media-navigatie-link indien deze aanwezig
                // en toon juiste preview-afbeelding
                
                $('.dropdownLink').hover(function() {
                    var $thisParent = $(this).parent();
                    if ($thisParent.hasClass('heeftMedias') && !$thisParent.hasClass('geselecteerd')) {
                        $thisParent.find('.mediaNavigatieLink').eq(0).css('color','#d00');
                        $thisParent.find('img').eq(0).css('display','block');
                    } else if (!$thisParent.hasClass('geselecteerd')){
                        $thisParent.find('img').css('display','block');
                    }
                }, function() {
                    var $thisParent = $(this).parent();
                    if ($thisParent.hasClass('heeftMedias')) {
                        $thisParent.find('.mediaNavigatieLink').eq(0).css('color','');
                        $thisParent.find('img').eq(0).css('display','none');
                    } else {
                        $thisParent.find('img').css('display','none');
                    }
                });
                
                // media-navigatie, het laten verschijnen van de preview-afbeelding
                
                $('.mediaNavigatieItem').hover(function() {
                    var $this = $(this);
                    //$this.parents('.dropdownItem').find('img').css('display','none');
                    if (!$this.hasClass('geselecteerd')) {
                        $this.find('img').css('display','block');
                    }
                }, function() {
                    $(this).find('img').css('display','none');
                });
                
                // Enkele fixes voor msie 6
                if ($.browser.msie && $.browser.version < 7) {
                    $('.dropdownItem').hover(function() {
                        $(this).css({'width':'200px','background-color':'#fff'});
                    }, function() {
                        $(this).css('background-color','');
                    });
                }
            }
            
            /**
             * Maakt de volledige navigatie en voegt deze toe aan het body.
             * @returns {string}
             */
            
            function maakNavigatie() {
                var xhtml = '<ul id="Navigatie">';
                    
                Variabelen.xml.find('pagina').each(function() {
                    
                    var paginaXml = $(this);
                    var paginaLabel = paginaXml.attr('label');
                    var paginaUrl = Helper.alsUrl(paginaLabel);
                    var heeftItems = paginaXml.find('item').length;
                    var paginaClass = paginaUrl + (heeftItems ? ' paginaItem heeftItems' : ' paginaItem');
                    var href = '/' + paginaUrl;
                    
                    xhtml += '<li class="' + paginaClass + '">';
                    xhtml += '<a rel="deeplink" class="paginaLink" href="' + href + '">' + paginaLabel + '</a>';
                    
                    if (heeftItems) {
                        xhtml += '<ul class="dropdown">';
                        
                        paginaXml.find('item').each(function() {
                            var itemXml = $(this);
                            var itemLabel = itemXml.attr('label');
                            var itemUrl = Helper.alsUrl(itemLabel);
                            var heeftMedias = itemXml.find('media').size() > 1;
                            var itemClass = (heeftMedias ? 'dropdownItem heeftMedias' : 'dropdownItem');
                            href = '/' + paginaUrl + (paginaUrl !==  'about' ? '/' + itemUrl : '');
                            
                            xhtml += '<li class="' + itemClass + '">';
                            xhtml += '<a rel="deeplink" class="dropdownLink" href="' + href + (heeftMedias ? '/1' : '') + '">' + itemLabel + '</a>';
                            
                            if (heeftMedias) {
                                xhtml += '<ul class="mediaNavigatie">';
                                
                                itemXml.find('media').each(function(i) {
                                    var mediaXml = $(this);
                                    xhtml += '<li class="mediaNavigatieItem">';
                                    xhtml += '<a rel="deeplink" class="mediaNavigatieLink" href="' + href + '/' +( i +1)+ '">' + (i+1) + '</a>';
                                    xhtml += '<img alt="" src="' + paginaXml.attr('locatie') + mediaXml.attr('preview') + '" />';
                                    xhtml += '</li>';
                                });
                                xhtml += '</ul>';
                            } else {
                                xhtml += '<img alt="" src="' + paginaXml.attr('locatie') + itemXml.find('media').attr('preview') + '" />';
                            }
                            xhtml += '</li>';
                        });
                        xhtml += '</ul>';
                    }
                    xhtml += '</li>';
                });
                xhtml += '</ul>';
                return xhtml;
            }
            
            /**
             * Verwijdert de geen javascript tekst en voegt nodige
             * elementen en stijlen toe.
             * @returns {void}
             */
            
            function voorbereiding() {
                
                // Wijzig elementen die reeds aanwezig zijn
                $('#GeenJavascript').remove();
                $('#Tekst').hide();
                $('#AchtergrondAfbeelding').attr('src','').attr('alt','').attr('style','');
                
                // Voeg nieuwe elementen toe aan het body
                var info = '<div id="Info" style="display: none;"></div>';
                var copyright = '<div id="Copyright" style="display: none;"></div>';
                var preloader = '<img id="Preloader" alt="preloader" src="css/afbeeldingen/preloader.gif" style="display: none;" />';
                var arrows = '<a id="VorigItem" class="itemPijl" rel="deeplink" style="display: none;">&nbsp;</a>';
                arrows += '<a id="VorigMedia" class="mediaPijl" rel="deeplink" style="display: none;">&nbsp;</a>';
                arrows += '<a id="VolgendItem" class="itemPijl" rel="deeplink" style="display: none;">&nbsp;</a>';
                arrows += '<a id="VolgendMedia" class="mediaPijl" rel="deeplink" style="display: none;">&nbsp;</a>';
                $('body').append(info + copyright + arrows + preloader);
                
                $('#VolledigScherm').append('<div id="Swf"></div>');
                
                // Voeg taal-navigatie & sluitknop toe aan de tekst
                var taalNavigatie = '<ul id="TaalNavigatie"><li class="geselecteerd">' + Variabelen.talen.join('</li><li>') + '</li></ul>';
                var sluitKnop = '<p id="SluitKnop">X</p>';
                $('#Tekst').prepend(taalNavigatie + sluitKnop).css('padding-top','26px');
            }
            
            return {
                // Publiek
                
                /**
                 * De setup die  afhankelijk is van de xml
                 * @returns {void}
                 */
                
                xmlAfhankelijk: function() {
                    // Voeg navigatie toe aan dom
                    $('#Hoofding').append(maakNavigatie());
                    hoverEffecten();
                },
                
                /**
                 * De setup die niet afhankelijk is van de xml
                 * @returns {void}
                 */
                
                xmlOnafhankelijk: function() {
                    Variabelen.deeplink = Variabelen.deeplinks[Math.floor(Math.random() * Variabelen.deeplinks.length)];
                    voorbereiding();
                }
            };
        }(); // Einde 'Setup' singleton
        
        // Alle functies die een element aanpassen.
        
        var Update = function() {
            // Privˇ
            
            return {
                // Publiek
                
                /**
                 * Verandert het media bestand.
                 * @param mediaXml {xml}
                 * @param locatie {string}
                 * @returns {void}
                 */
                
                media: function(mediaXml, locatie) {
                    
                    if (mediaXml.attr('copyright')) {
                        $('#Copyright').html('&copy; ' + mediaXml.attr('copyright'));
                    } else {
                        $('#Copyright').html('');
                    }
                    
                    $('#Preloader').css('display','block');
                    
                    switch (mediaXml.attr('type')) {
                        case 'film' :
                            Helper.toonFilm(mediaXml.attr('bestand'));
                        break;
                        case 'flash' :
                            Helper.toonFlash(mediaXml.attr('bestand'));
                        break;
                        default :
                            $('#AchtergrondAfbeelding').data('afmetingen', {
                                breedte : mediaXml.attr('breedte'),
                                hoogte : mediaXml.attr('hoogte')
                            });
                            Helper.toonAfbeelding(locatie + mediaXml.attr('bestand'));
                        break;
                    }
                },
                
                /**
                 * Verandert het href-atribuut van de gespecif•eerde pijl.
                 * @param id {string}
                 * @param deeplinks {array}
                 * @returns {void}
                 */
                
                pijl: function(id, deeplinks) {
                    var pijl = $('#' + id);
                    if (deeplinks) {
                        pijl.attr('href', deeplinks.join('/')).css('display','block');
                    } else {
                        pijl.attr('href', '').css('display','none');
                    }
                },
                
                /**
                 * Verandert de selectie van de navigatie.
                 * @param paginaIndex {int}
                 * @param itemIndex {int} (optioneel)
                 * @param mediaIndex {int} (optioneel)
                 * @returns {void}
                 */
                
                selectie: function(paginaIndex, itemIndex, mediaIndex) {
                    
                    // Verander de doorzichtbaarheid van de navigatie
                    $('.paginaItem.geselecteerd').css({
                        'padding-top' : '1px',
                        'border-top' : 'none',
                        'opacity': '.5', /* Standard: FF gt 1.5, Opera, Safari */
                        'filter': 'alpha(opacity=50)', /* IE lt 8 */
                        '-ms-filter': '"alpha(opacity=50)"', /* IE 8 */
                        '-khtml-opacity': '.5', /* Safari 1.x */
                        '-moz-opacity': '.5' /* FF lt 1.5, Netscape */
                    });
                    
                    $('.geselecteerd .dropdown').css('display','none');
                    
                    $('#Navigatie .geselecteerd').removeClass('geselecteerd');
                    
                    // Verander selectie van de pagina-navigatie
                    $('#Navigatie > li')
                        .eq(paginaIndex).addClass('geselecteerd')
                            .children('a').addClass('geselecteerd');
                    
                    // Verander de doorzichtbaarheid van de navigatie
                    $('.paginaItem.geselecteerd').css({
                        'padding-top' : '0',
                        'border-top' : '1px solid #fff',
                        'opacity': '1', /* Standard: FF gt 1.5, Opera, Safari */
                        'filter': 'alpha(opacity=100)', /* IE lt 8 */
                        '-ms-filter': '"alpha(opacity=100)"', /* IE 8 */
                        '-khtml-opacity': '1', /* Safari 1.x */
                        '-moz-opacity': '1' /* FF lt 1.5, Netscape */
                    });
                    
                    // ???
                    $('.geselecteerd .dropdown').css('display','block');
                    
                    // Verberg de prview-afbeelding
                    $('#Navigatie img').css('display','none');
                    
                    if (itemIndex !== null) {
                        $('#Navigatie .geselecteerd .dropdown > li')
                            .eq(itemIndex).addClass('geselecteerd')
                                .children('a').addClass('geselecteerd');
                        
                        if (mediaIndex !== null) {
                            $('#Navigatie .geselecteerd .dropdown .geselecteerd li')
                                .eq(mediaIndex).addClass('geselecteerd')
                                    .children('a').addClass('geselecteerd');
                        }
                    }
                }
            };
        }();
        
        // Alle functies die de controle over een pagina hebben.
        
        var Control = function() {
            // Privˇ
            
            /**
             * Bepaalt de deeplinks voor het volgende item.
             * @param paginaXml {xml}
             * @param paginaUrl {string}
             * @param itemIndex {int}
             * @param aantalItems {int}
             * @returns {array}
             */
            
            function volgendItemDeeplinks(paginaXml, paginaUrl, itemIndex, aantalItems) {
                var deeplinks = null;
                if (itemIndex < aantalItems - 1) {
                    deeplinks = [paginaUrl];
                    var volgendItemXml = paginaXml.find('item').eq(itemIndex + 1);
                    deeplinks.push(Helper.alsUrl(volgendItemXml.attr('label')));
                    if (volgendItemXml.find('media').size() > 1) {
                        deeplinks.push('1');
                    }
                }
                return deeplinks;
            }
            
            /**
             * Bepaalt de deeplinks voor het vorige item.
             * @param paginaXml {xml}
             * @param paginaUrl {string}
             * @param itemIndex {int}
             * @returns {array}
             */
            
            function vorigItemDeeplinks(paginaXml, paginaUrl, itemIndex) {
                var deeplinks = null;
                if (itemIndex > 0) {
                    deeplinks = [paginaUrl];
                    var vorigItemXml = paginaXml.find('item').eq(itemIndex - 1);
                    deeplinks.push(Helper.alsUrl(vorigItemXml.attr('label')));
                    if (vorigItemXml.find('media').size() > 1) {
                        deeplinks.push('1');
                    }
                }
                return deeplinks;
            }
            
            /**
             * Bepaalt de deeplinks voor volgend media bestand.
             * @param paginaXml {xml}
             * @param paginaUrl {string}
             * @param itemUrl {string}
             * @param itemIndex {int}
             * @param aantalItems {int}
             * @param mediaIndex {int}
             * @param aantalMedias {int}
             * @returns {array}
             */
            
            function volgendMediaDeeplinks(paginaXml, paginaUrl, itemUrl, itemIndex, aantalItems, mediaIndex, aantalMedias) {
                var deeplinks = null;
                if (itemIndex < aantalItems - 1 || mediaIndex < aantalMedias - 1) {
                    if (mediaIndex < aantalMedias - 1) {
                        deeplinks = [paginaUrl];
                        if (itemUrl !== '') {
                            deeplinks.push(itemUrl);
                        }
                        deeplinks.push(mediaIndex + 2);
                    } else {
                        var volgendItemXml = paginaXml.find('item').eq(itemIndex + 1);
                        deeplinks = [paginaUrl, Helper.alsUrl(volgendItemXml.attr('label'))];
                        if (volgendItemXml.find('media').size() > 1) {
                            deeplinks.push('1');
                        }
                    }
                }
                return deeplinks;
            }
            
            /**
             * Bepaalt de deeplinks voor vorig media bestand.
             * @param paginaXml {xml}
             * @param paginaUrl {string}
             * @param itemUrl {string}
             * @param itemIndex {int}
             * @param mediaIndex {int}
             * @returns {array}
             */
            
            function vorigMediaDeeplinks(paginaXml, paginaUrl, itemUrl, itemIndex, mediaIndex) {
                var deeplinks = null;
                if (itemIndex > 0 || mediaIndex > 0) {
                    if (mediaIndex > 0) {
                        deeplinks = [paginaUrl];
                        if (itemUrl !== '') {
                            deeplinks.push(itemUrl);
                        }
                        deeplinks.push(mediaIndex);
                    } else {
                        var vorigItemXml = paginaXml.find('item').eq(itemIndex - 1);
                        var vorigItemAantalMedias = vorigItemXml.find('media').size();
                        deeplinks = [paginaUrl, Helper.alsUrl(vorigItemXml.attr('label'))];
                        if (vorigItemAantalMedias > 1) {
                            deeplinks.push(vorigItemAantalMedias);
                        }
                    }
                }
                return deeplinks;
            }
            
            return {
                // Publiek
                
                /**
                 * Heeft de controle over alle paginas die geen eigen
                 * controller hebben.
                 * @returns {void}
                 */
                
                pagina: function(paginaIndex, paginaUrl) {
                    
                    // Verberg element die niet op deze pagina getoont moeten worden
                    $('#Tekst').css('display','none');
                    
                    // Validatie
                    
                    var geldigItem = false;
                    var geldigMedia = false;
                    
                    var deeplinks = $.address.pathNames();
                    var paginaXml = Variabelen.xml.find('pagina').eq(paginaIndex);
                    var aantalItems = paginaXml.find('item').size();
                    var itemUrl = deeplinks[1] || false;
                    var itemIndex = Helper.bepaalItemIndex(paginaXml, itemUrl);
                    
                    if (itemIndex === -1) {
                        itemUrl = Helper.alsUrl(paginaXml.find('item').eq(0).attr('label'));
                        itemIndex = 0;
                    } else {
                        geldigItem = true;
                    }
                    
                    var itemXml = paginaXml.find('item').eq(itemIndex);
                    var aantalMedias = itemXml.find('media').size();
                    
                    if (!geldigItem) {
                        deeplinks = [paginaUrl, itemUrl];
                        if (aantalMedias > 1) {
                            deeplinks.push('1');
                        }
                        Helper.redirect(deeplinks);
                        return;
                    }
                    
                    var mediaUrl = deeplinks[2] || 0;
                    var mediaIndex = 0;
                    
                    if (aantalMedias > 1) {
                        if (mediaUrl) {
                            mediaIndex = parseInt(mediaUrl, 10) - 1;
                            if (mediaIndex < aantalMedias && mediaIndex > -1) {
                                geldigMedia = true;
                            }
                        }
                    } else if (!mediaUrl) {
                        geldigMedia = true;
                    }
                    
                    
                    if (!geldigMedia || deeplinks[3]) {
                        deeplinks = [paginaUrl, itemUrl];
                        if (aantalMedias > 1) {
                            deeplinks.push(geldigMedia ? mediaIndex + 1 : 1);
                        }
                        Helper.redirect(deeplinks);
                        return;
                    }
                    
                    var mediaXml = itemXml.find('media').eq(mediaIndex);
                    
                    // Einde validatie begin met updaten
                    
                    Update.selectie(paginaIndex, itemIndex, mediaIndex);
                    
                    //Update.info();
                    
                    Update.pijl('VorigItem', vorigItemDeeplinks(
                        paginaXml, paginaUrl,
                        itemIndex
                    ));
                    
                    Update.pijl('VorigMedia', vorigMediaDeeplinks(
                        paginaXml, paginaUrl,
                        itemUrl, itemIndex,
                        mediaIndex
                    ));
                    
                    Update.pijl('VolgendItem', volgendItemDeeplinks(
                        paginaXml, paginaUrl,
                        itemIndex, aantalItems
                    ));
                    
                    Update.pijl('VolgendMedia', volgendMediaDeeplinks(
                        paginaXml, paginaUrl,
                        itemUrl, itemIndex, aantalItems,
                        mediaIndex, aantalMedias
                    ));
                    
                    Update.media(mediaXml, paginaXml.attr('locatie'));
                    
                    document.title = 'Random Light - ' + itemXml.attr('label');
                },
                
                /**
                 * Heeft controle over de about pagina.
                 * @returns {void}
                 */
                
                about: function(paginaIndex, paginaUrl) {
                    
                    // Validatie
                    
                    var geldigMedia = false;
                    
                    var deeplinks = $.address.pathNames();
                    var paginaXml = Variabelen.xml.find('pagina').eq(paginaIndex);
                    var aantalMedias = paginaXml.find('media').size();
                    var mediaUrl = deeplinks[1] || 0;
                    var mediaIndex = 0;
                    
                    if (aantalMedias > 1) {
                        if (mediaUrl) {
                            mediaIndex = parseInt(mediaUrl, 10) - 1;
                            if (mediaIndex < aantalMedias && mediaIndex > -1) {
                                geldigMedia = true;
                            }
                        }
                    } else if (!mediaUrl) {
                        geldigMedia = true;
                    }
                    
                    
                    if (!geldigMedia || deeplinks[2]) {
                        deeplinks = [paginaUrl];
                        if (aantalMedias > 1) {
                            deeplinks.push(geldigMedia ? mediaIndex + 1 : 1);
                        }
                        Helper.redirect(deeplinks);
                        return;
                    }
                    
                    var mediaXml = paginaXml.find('media').eq(mediaIndex);
                    
                    // Einde validatie begin updaten
                    
                    Update.selectie(paginaIndex, 0, mediaIndex);
                    
                    // Update.info();
                    
                    Update.pijl('VorigItem');
                    
                    Update.pijl('VolgendItem');
                    
                    Update.pijl('VorigMedia', vorigMediaDeeplinks(
                        paginaXml, paginaUrl,
                        '', 0,
                        mediaIndex
                    ));
                    
                    Update.pijl('VolgendMedia', volgendMediaDeeplinks(
                        paginaXml, paginaUrl,
                        '', 0, 0,
                        mediaIndex, aantalMedias
                    ));
                    
                    Update.media(mediaXml, paginaXml.attr('locatie'));
                    
                    $('#Over').css('display','block');
                    $('#Contact').css('display','none');
                    
                    document.title = 'Random Light - about';
                },
                
                /**
                 * Contact controller
                 * @returns {void}
                 */
                
                contact: function(paginaIndex, paginaUrl) {
                    
                    // Validatie
                    
                    if ($.address.pathNames()[1]) {
                        Helper.redirect([paginaUrl]);
                        return;
                    }
                    
                    var paginaXml = Variabelen.xml.find('pagina').eq(paginaIndex);
                    
                    // Einde validatie begin updaten
                    
                    Update.selectie(paginaIndex);
                    
                    // Update.info();
                    
                    Update.pijl('VorigItem');
                    Update.pijl('VolgendItem');
                    Update.pijl('VorigMedia');
                    Update.pijl('VolgendMedia');
                    
                    Update.media(paginaXml.find('media'), paginaXml.attr('locatie'));
                    
                    $('#Over').css('display','none');
                    $('#Contact').css('display','block');
                    
                    document.title = 'Random Light - contact';
                }
            };
        }();
        
        // Alle 'event handlers' komen in de 'Event' singleton
        // alphabetisch geranschikt
        
        var Event = function() {
            // Privˇ
            
            /**
             * Zet de deeplink-waarde gelijk aan de href-waarde van
             * de geklikte link.
             * @returns {void}
             */
            
            function bijDeeplinkKlik(evt) {
                evt.preventDefault();
                var $this = $(this);
                if ($this.parent().hasClass('about') || $this.parent().hasClass('contact')) {
                    Variabelen.tekstWordtGetoont = true;
                    $('#Tekst').css('display','block');
                }
                $.address.value(this.getAttribute('href').replace('http://dev.edocode.be/', ''));
            }
            
            /**
             * Valideert de deeplink en roept de juiste controller aan.
             * @returns {void}
             */
            
            function bijDeeplinkVerandert(evt) {
                
                // Omdat er pas geluisterd wordt naar het deeplink-verander-event
                // nadat de xml geladen is, wordt de eerste keer deze functie niet
                // aangeroepen. Om dit te omzeilen wordt de deeplink even gelijk gesteld
                // aan '/negeer'.
                
                if (evt.value === '/negeer') { return; }
                
                var geldigeDeeplink = false;
                var paginaUrl;
                var paginaIndex;
                
                // Valideer de pagina deeplink
                
                if (evt.value !== '/') {
                    paginaUrl = evt.pathNames[0];
                    paginaIndex = Helper.bepaalPaginaIndex(paginaUrl);
                    if (paginaIndex !== -1) {
                        geldigeDeeplink = true;
                    }
                }
                
                if (geldigeDeeplink) {
                    switch (paginaUrl) {
                        case 'about' :
                            Control.about(paginaIndex, paginaUrl);
                        break;
                        case 'contact' :
                            Control.contact(paginaIndex, paginaUrl);
                        break;
                        default :
                            Control.pagina(paginaIndex, paginaUrl);
                        break;
                    }
                } else {
                    Helper.redirect();
                }
                
                if ((paginaUrl === 'about' || paginaUrl === 'contact') && Variabelen.tekstMoetWordenGetoont) {
                    $('#Tekst').css('display','block');
                }
            }
            
            /**
             * Verbergt de tekst.
             * @returns {void}
             */
            
            function bijSluitKnopKlik() {
                Variabelen.tesktWordtGetoont = false;
                Variabelen.tekstMoetWordenGetoont = false;
                $('#Tekst').css('display','none');
            }
            
            /**
             * Verandert de taal
             * @returns {void}
             */
            
            function bijTaalNavigatieKlik() {
                var $this = $(this);
                if (!$this.hasClass('geselecteerd')) {
                    $('#TaalNavigatie .geselecteerd').removeClass('geselecteerd');
                    $this.addClass('geselecteerd');
                    $('.' + Variabelen.taal).css('display','none');
                    Variabelen.taal = $this.text();
                    $('.' + Variabelen.taal).css('display','block');
                }
            }
            
            /**
             * Past alles aan dat afhankelijk is van de groote van de viewport
             * @returns {void}
             */
            
            function bijWindowResize() {
                Helper.afbeeldingVulScherm();
            }
            
            /**
             * Voegt alle event-listeners toe.
             * @returns {void}
             */
            
            function voegEventListenersToe() {
                $.address.change(bijDeeplinkVerandert);
                $('a[rel="deeplink"]').live('click', bijDeeplinkKlik);
                $(window).resize(bijWindowResize);
                $('#TaalNavigatie li').bind('click', bijTaalNavigatieKlik);
                $('#SluitKnop').bind('click', bijSluitKnopKlik);
            }
            
            return {
                // Publiek
                
                
                /**
                 * Bewaart xml in globale variabele, roept setup-functies
                 * aan die afhankelijk zijn van de xml gegeven en voegt de
                 * event-listeners toe.
                 * @returns {void}
                 */
                
                xmlGeladen: function(evt) {
                    Variabelen.xml = $(evt).find('randomlight');
                    Setup.xmlAfhankelijk();
                    voegEventListenersToe();
                    
                    var deeplink = $.address.value();
                    $.address.history(false);
                    $.address.value('negeer');
                    $.address.value(deeplink);
                    $.address.history(true);
                }
            };
        }();
        
        return {
            
            /**
             * Laad het xml-bestand in en roept setup-functies aan die niet
             * afhankelijk zijn van het xml bestand.
             * @returns {void}
             */
            
            init: function(xml) {
                
                Setup.xmlOnafhankelijk();
                
                // Laad het xml-bestand in
                $.ajax({
                    type: 'GET',
                    url: 'xml/gegevens.xml',
                    dataType: 'xml',
                    success: Event.xmlGeladen
                });
            }
        };
    }();
    
})(jQuery);

jQuery(function() {
    
    jQuery.EDOCODE.init();
    
});
