jQuery(document).ready(function() {

    var alreadyRunning = false;

	var run = function($) {
        if(alreadyRunning) {
            return;
        }
        alreadyRunning = true;

		// globals
        var platform = "desktop";
        var specialCss = false;

		var templates;
		var controller;
		var loader;
		
		var templateData = [];
		var appData;

        var browserIsSupported;

        var browserName;
        var fullVersion;
        var majorVersion;

		var init = function() {

			loader = new LIB3m5.JQueryLoader();

			loader.$.bind(LIB3m5.JQueryLoader.EVT_PROGRESS, onLoaderProgress);
			loader.$.bind(LIB3m5.JQueryLoader.EVT_COMPLETE, onLoaderComplete);

            // LOAD SCRIPTS ////////////////////////////////////////////////////////////////////////////////////////////
            loader.addScripts.apply(null, configData.scripts);

            // BROWSER DETECTION

            var nVer = navigator.appVersion;
            var nAgt = navigator.userAgent;
            browserName  = navigator.appName;
            fullVersion  = ''+parseFloat(navigator.appVersion);
            majorVersion = parseInt(navigator.appVersion,10);
            var nameOffset,verOffset,ix;

            // In Opera, the true version is after "Opera" or after "Version"
            if ((verOffset=nAgt.indexOf("Opera"))!=-1) {
             browserName = "Opera";
             fullVersion = nAgt.substring(verOffset+6);
             if ((verOffset=nAgt.indexOf("Version"))!=-1)
               fullVersion = nAgt.substring(verOffset+8);
            }
            // In MSIE, the true version is after "MSIE" in userAgent
            else if ((verOffset=nAgt.indexOf("MSIE"))!=-1) {
             browserName = "Microsoft Internet Explorer";
             fullVersion = nAgt.substring(verOffset+5);
            }
            // In Chrome, the true version is after "Chrome"
            else if ((verOffset=nAgt.indexOf("Chrome"))!=-1) {
             browserName = "Chrome";
             fullVersion = nAgt.substring(verOffset+7);
            }
            // In Safari, the true version is after "Safari" or after "Version"
            else if ((verOffset=nAgt.indexOf("Safari"))!=-1) {
             browserName = "Safari";
             fullVersion = nAgt.substring(verOffset+7);
             if ((verOffset=nAgt.indexOf("Version"))!=-1)
               fullVersion = nAgt.substring(verOffset+8);
            }
            // In Firefox, the true version is after "Firefox"
            else if ((verOffset=nAgt.indexOf("Firefox"))!=-1) {
             browserName = "Firefox";
             fullVersion = nAgt.substring(verOffset+8);
            }
            // In most other browsers, "name/version" is at the end of userAgent
            else if ( (nameOffset=nAgt.lastIndexOf(' ')+1) < (verOffset=nAgt.lastIndexOf('/')) )
            {
             browserName = nAgt.substring(nameOffset,verOffset);
             fullVersion = nAgt.substring(verOffset+1);
             if (browserName.toLowerCase()==browserName.toUpperCase()) {
              browserName = navigator.appName;
             }
            }
            // trim the fullVersion string at semicolon/space if present
            if ((ix=fullVersion.indexOf(";"))!=-1) fullVersion=fullVersion.substring(0,ix);
            if ((ix=fullVersion.indexOf(" "))!=-1) fullVersion=fullVersion.substring(0,ix);

            majorVersion = parseInt(''+fullVersion,10);
            if (isNaN(majorVersion)) {
              fullVersion  = ''+parseFloat(navigator.appVersion);
              majorVersion = parseInt(navigator.appVersion,10);
            }

            // get the version of
            if(browserName == "Microsoft Internet Explorer") {
                // for ie we need additional css
                specialCss = "ie" + majorVersion;
            }

            // alert(browserName + " " + majorVersion);

//            alert(navigator.userAgent);
//            alert(navigator.platform);

            var isAndroidDevice = navigator.userAgent.indexOf("Android") != -1;
            var displayWidth, displayHeight;
            try {
                displayWidth = window.screen ? window.screen.availWidth : $(window).width();
                displayHeight = window.screen ? window.screen.availHeight : $(window).height();
            }
            catch(e) {
                displayWidth = $(window).width();
                displayHeight = $(window).height();
            }
            var shortDisplaySide = Math.min(displayWidth, displayHeight);

            // is a specific platform defined?
            if(configData.platform && configData.platform != "") {
                platform = configData.platform;
            }
            else {
                // do the platform detection

                // is it a iphone?
                if (navigator.platform === "iPhone") {
                    platform = "iphone";
                }
                else if (navigator.platform === "iPad") {
                    platform = "tablet";
                }
                else if (isAndroidDevice) {
                    if (shortDisplaySide < 768) {
                        platform = "android_phone";
                    }
                    else {
                        // this is an android the has a resolution big enough to act as tablet
                        platform = "tablet";
                    }

                    // use the dolphin styles if the browserName is Safari
                    if (browserName == "Safari") {
                        specialCss = "safari";
                    }
                }
            }

            // we assume that the browser is supported
            browserIsSupported = true;
            // these browsers are not supported
            if(
                    (browserName == "Microsoft Internet Explorer" && majorVersion < 7)
                ||  (browserName == "Firefox" && majorVersion < 3)
                ||  (browserName == "Safari" && majorVersion < 3)
                ||  (browserName == "Chrome" && majorVersion < 8)
                ||  (browserName == "Opera" && majorVersion < 10)
            ) {
                browserIsSupported = false;
            }

			// load initial data
			loader.add(
				  null
                // LOAD TEMPLATES //////////////////////////////////////////////////////////////////////////////////////
                , $.get(configData.templates[platform]).done(function(data) {templateData.push(data);})

				// LOAD APP DATA ///////////////////////////////////////////////////////////////////////////////////////
				, $.get(configData.dataUrl).done(function(data) {appData = data;})
				
				, null
			);

            // add css
            var i;
            var cssArr;
            if (!specialCss || !configData.styles[platform][specialCss]) {
                cssArr = configData.styles[platform]["std"];
            }
            else {
                cssArr = configData.styles[platform][specialCss];
            }
            if(cssArr) {
                for (i = 0; i < cssArr.length; i++) {
                    loader.addCSS(cssArr[i], $("head"));
                }
            }

		};
		
		var onLoaderProgress = function (event, progress, totalDownloads, doneDownloads, failedDownloads) {
			//$.log("progress: " + [progress, totalDownloads, doneDownloads, failedDownloads]);
			$("#loaderProgressBar").progressbar({value : progress*100});
		};
		
		var onLoaderComplete = function (event, progress, totalDownloads, doneDownloads, failedDownloads){
			//$.log('done ' + [progress, totalDownloads, doneDownloads, failedDownloads]);
			initialize();
		};
		
		var initialize = function () {
			// configure the toolbox
			LIB3m5.JQueryToolbox.configure({
				jsonpURI : configData.jsonpUrl
			});

            if (browserIsSupported) {

                // init templating engine
                templates = new LIB3m5.JQueryTemplates();

                for(i = 0; i < templateData.length; i++) {
                    var data = templateData[i];

                    templates.parse(data, "geothekTemplate");
                }

                // remove loading div
                $('#loading').remove();
                // create config data
                var config = new ZDFGEOTHEK.Config(configData);

                config.browserName = browserName;
                config.browserMajorVersion = majorVersion;

                // is this the maptool or the geothek?
                if(configData.app == "MAPTOOL") {
                    // create the root display
                    $('body').append(templates.get("rootMaptool"));

                    // initialize controller
                    controller = new ZDFGEOTHEK.MapToolController($("#geothek_root"), templates, config);
                }
                else {
                    // create the root display
                    $('body').append(templates.get("rootGeothek"));

                    // intialize controller
                    switch(platform) {
                        case "desktop":
                        default:
                            controller = new ZDFGEOTHEK.GeothekDesktopController($("#geothek_root"), templates, config);
                            break;
                        case "iphone":
                            controller = new ZDFGEOTHEK.GeothekIPhoneController($("#geothek_root"), templates, config);
                            break;
                        case "tablet":
                            controller = new ZDFGEOTHEK.GeothekTabletController($("#geothek_root"), templates, config);
                            break;
                        case "android_phone":
                            controller = new ZDFGEOTHEK.GeothekAndroidPhoneController($("#geothek_root"), templates, config);
                            break;
                    }
                }

                setTimeout(function () {
                    // run the controller
                    controller.initUI(appData, true);
                }, 1000);
            }
            else {
                if ($('#unsupportedBrowser')) {
                    $('#unsupportedBrowser').css('display', 'block');
                }
                if ($('#loading')) {
                    $('#loading').css('display', 'none');
                }
                if ($('#loading_spinner')) {
                    $('#loading_spinner').css('display', 'none');
                }
            }
		};
		
		//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// CALL INIT
		init();
	};
	
	function tryInit() {
        var cannotStart = false;
		try {
            cannotStart = !(LIB3m5)
                ||  !(LIB3m5.JQueryToolbox)
                ||  !(LIB3m5.JQueryLoader)
                ||  !(LIB3m5.JQueryTemplates)
            ;
        }
        catch(e) {
            $.log("cannot start");
			setTimeout(tryInit, 100);
            return;
		}

        if (!cannotStart) {
            run(jQuery);
        }
	}
	
	tryInit();
});
