var makandra; if (!makandra) { makandra = new Object(); }

/***********************************************************************************************************/

makandra.openScreenshot = function(imageURL, width, height) {
    var screenshotApplication = makandra.Applications.get("screenshot");
    screenshotApplication.windowWidth = width + 35;
    screenshotApplication.windowHeight = height + 65;
    screenshotApplication.source = function(canvasElement) {
        var screenshot = new Element("img", { 'src': imageURL, 'class': 'screenshot' });
        var link = new Element("a", { 'href': '#', 'onclick': 'makandra.shell.closeFocusedApplication(); false;' });
        link.appendChild(screenshot);
        canvasElement.appendChild(link);
    };
    makandra.shell.openApplication(screenshotApplication);
};

makandra.openDownloadLink = function(url) {
    // alert("o: " + url);
    setTimeout(function() {
      var documentApplication = makandra.Applications.get("document");
      // alert(documentApplication);
      documentApplication.source = url;
      documentApplication.windowWidth = 900;
      documentApplication.windowHeight = 500;
      makandra.openApplication(documentApplication.name);
    }, 50);
};

makandra.defineApplications = function(applicationProperties) {

    makandra.Applications = new Hash();
        
    new makandra.Application({
        name:          "document",
        iconPath:      "coquette/64x64/attachment.png",
        smallIconPath: "coquette/16x16/attachment.png",
        windowWidth:   320,
        windowHeight:  160,
        closeOnBlur:   true,
        source:        "files/"
    });

    
    new makandra.Application({
        name:          'screenshot',
        title:         'Bildanzeige',
        iconPath:      "coquette/64x64/film.png",
        smallIconPath: "coquette/16x16/film.png",
        windowWidth:   500,
        windowHeight:  480
    });

    new makandra.Application({
        name:          'schoen_einfach',
        iconPath:      "coquette/64x64/accept.png",
        smallIconPath: "coquette/16x16/accept.png",
        windowWidth:   854,
        windowHeight:  560,
        source:        "/window/schoen_einfach",
        reopenAutomatically: true
    });

  new makandra.Application({
      name:          'malennachzahlen',
      iconPath:      "coquette/64x64/palette.png",
      smallIconPath: "coquette/16x16/palette.png",
      windowWidth:   600,
      windowHeight:  476,
      source:        "/window/malennachzahlen",
      reopenAutomatically: true
  });

  new makandra.Application({
      name:          'blog',
      iconPath:      "coquette/64x64/note_book.png",
      smallIconPath: "coquette/16x16/note_book.png",
      windowWidth:   700,
      windowHeight:  266,
      source:        "/window/blog",
      reopenAutomatically: true
  });

    new makandra.Application({
        name:          'einfach_schoen',
        iconPath:      "coquette/64x64/accept.png",
        smallIconPath: "coquette/16x16/accept.png",
        windowWidth:   854,
        windowHeight:  560,
        source:        "/window/einfach_schoen",
        reopenAutomatically: true
    });

    new makandra.Application({
        name:          'konsole',
        title:         'Konsole',
        iconPath:      "console.png",
        smallIconPath: "console_small.png",
        windowWidth:   800,
        windowHeight:  500,
        source:        "/console?node_name=%2F&command=hello"
    });
        
    
    new makandra.Application({
        name:          'kontakt',
        iconPath:      "coquette/64x64/mail.png",
        smallIconPath: "coquette/16x16/mail.png",
        windowWidth:   680,
        windowHeight:  500,
        source:        "/window/kontakt"
    });

    new makandra.Application({
        name:          'kontakt_formular',
        iconPath:      "coquette/64x64/mail.png",
        smallIconPath: "coquette/16x16/mail.png",
        windowWidth:   550,
        windowHeight:  500,
        source:        "/window/kontakt_formular"
    });

    /*
    new makandra.Application({
        name:          'meinung',
        iconPath:      "coquette/64x64/comment.png",
        smallIconPath: "coquette/16x16/comment.png",
        windowWidth:   550,
        windowHeight:  500,
        source:        "/window/meinung"
    });
    */
        
    /*        
    new makandra.Application({
        name:          'auftrags_formular_makandra_os',
        iconPath:      "os.png",
        smallIconPath: "os_small.png",
        windowWidth:   600,
        windowHeight:  500,
        source:        "/window/auftrags_formular_makandra_os"
    });
    */

    new makandra.Application({
        name:          'referenzen',
        iconPath:      "coquette/64x64/prize_winner.png",
        smallIconPath: "coquette/16x16/prize_winner.png",
        windowWidth:   800,
        windowHeight:  600,
        reopenAutomatically: true,
        source:        "/window/referenzen"
    });
        
    new makandra.Application({
        name:          'produkte',
        iconPath:      "coquette/64x64/shopping_cart.png",
        smallIconPath: "coquette/16x16/shopping_cart.png",
        windowWidth:   800,
        windowHeight:  600,
        reopenAutomatically: true,
        source:        "window/produkte"
    });
    
    new makandra.Application({
        name:          'leistungen',
        iconPath:      "coquette/64x64/home.png",
        smallIconPath: "coquette/16x16/home.png",
        windowWidth:   800,
        windowHeight:  600,
        reopenAutomatically: true,
        source:        "/window/leistungen"
    });

    
    new makandra.Application({
        name:          'ueber_uns',
        iconPath:      "coquette/64x64/image.png",
        smallIconPath: "coquette/16x16/image.png",
        windowWidth:   800,
        windowHeight:  600,
        source:        "/window/ueber_uns"
    });
        
    new makandra.Application({
        name:          'willkommen',
        iconPath:      "coquette/64x64/prize_winner.png",
        smallIconPath: "coquette/16x16/prize_winner.png",
        windowWidth:   800,
        windowHeight:  500,
        closeOnBlur:   true,
        source:        "/window/willkommen",
        onManualClose: "makandra.pulsateDesktop(500)"
    });
        
    new makandra.Application({
        name:          'community',
        iconPath:      "coquette/64x64/users.png",
        smallIconPath: "coquette/16x16/users.png",
        windowWidth:   330,
        windowHeight:  180,
        reopenAutomatically: true,
        source: function(canvasElement) {
            var applications = [
                makandra.Applications.get('blog'),
                makandra.Applications.get('malennachzahlen')
            ];
            return new makandra.IconGroup(this.shell, canvasElement, applications, makandra.IconGroup.ALIGN_HORIZONTALLY);
        }.bind(this)
    });

    new makandra.Application({
      name:          'warum_webbasierte_software',
      iconPath:      "coquette/64x64/info.png",
      smallIconPath: "coquette/16x16/info.png",
      windowWidth:   800,
      windowHeight:  600,
      reopenAutomatically: true,
      source:        "/window/warum_webbasierte_software"
    });

    // Import server-side properties    
    applicationProperties.each(function(properties) {
        var application = makandra.Applications.get(properties.name);
        if (application) {
            ["browser_title", "title", "short_title", "description", "keywords", "hide_from_crawlers"].each(function(key) {
                value = properties[key];
                if (value) {
                    application[key.dasherize().camelize()] = value;
                }
            });
        }
    });
        
};

makandra.preloadImages = function() {
    makandra.Applications.values().each(function(application) {
        makandra.Util.loadImage(application.getAbsoluteIconPath());
        makandra.Util.loadImage(application.getAbsoluteSmallIconPath());
    });
};

makandra.openApplication = function(applicationName, options) {
    makandra.shell.openApplication(makandra.Applications.get(applicationName), options);
};

makandra.closeFocusedApplication = function() {
    makandra.shell.closeFocusedApplication();
};

makandra.pulsateDesktop = function(delay) {
    if (!delay) {
        delay = 0;
    }
    window.setTimeout(function() { makandra.shell.desktop.pulsate(); }, delay);
};

/***********************************************************************************************************/

Effect.Transitions.square = function(pos) {
    return pos * pos;
};
      
Effect.Transitions.invertedSquare = function(pos) {
    return 1.0 - Math.pow(1 - pos, 2);
};
      
Effect.Transitions.invertedCubic = function(pos) {
    return 1.0 - Math.pow(1 - pos, 3);
};
      
Effect.Transitions.cubic = function(pos) {
    return Math.pow(pos, 3);
};

/***********************************************************************************************************/

makandra.Application = Class.create({
    
    initialize: function(options) {
        var i = 0;
        this.name = options.name;
        this.browserTitle = options.browserTitle;
        this.title = options.title;
        this.shortTitle = options.shortTitle;
        this.description = options.description;
        this.keywords = options.keywords;
        this.hideFromCrawlers = options.hideFromCrawlers;
        this.iconPath = options.iconPath;
        this.smallIconPath = options.smallIconPath;
        this.windowWidth = options.windowWidth;
        this.windowHeight = options.windowHeight;
        this.source = options.source || function(canvasElement) {};
        this.reopenAutomatically = options.reopenAutomatically;
        this.closeOnBlur = options.closeOnBlur;
        this.directLink = options.directLink;
        this.onManualClose = options.onManualClose;
        makandra.Applications.set(this.name, this);
    },
        
    getShortTitle: function() {
        return this.shortTitle || this.title;
    },
        
    getAbsoluteIconPath: function() {
        return makandra.Icon.IMAGE_ROOT + "/" + this.iconPath;
    },
        
    getAbsoluteSmallIconPath: function() {
        return makandra.Icon.IMAGE_ROOT + "/" + this.smallIconPath;
    }
    
});

/***********************************************************************************************************/

//makandra.LauncherWindowContent = Class.create({
//    
//    initialize: function(shell, applications) {
//        this.shell = shell;
//        this.element = new Element("div", { "class": "launcher" });
//        this.iconGroup = new IconGroup(shell, this.element, this.application, makandra.IconGroup.ALIGN_HORIZONTALLY);
//        return element;
//    },
//        
//    layout: function() {
//        this.iconGroup.layout();
//    }
//    
//});

/***********************************************************************************************************/

makandra.Component = Class.create({
    
    setPosition: function(left, top) {
        makandra.Util.setPosition(this.element, left, top);
    },
    
    setSize: function(width, height) {
        makandra.Util.setSize(this.element, width, height);
    },
        
    setWidth: function(width) {
        makandra.Util.setWidth(this.element, width);
    },
        
    setTop: function(top) {
        makandra.Util.setTop(this.element, top);
    },
        
    setLeft: function(left) {
        makandra.Util.setLeft(this.element, left);
    },
        
    setHeight: function(height) {
        makandra.Util.setHeight(this.element, height);
    },
        
    setOpacity: function(opacity) {
        this.element.setOpacity(opacity);
    },
        
    layout: function() {
    },
        
    destroy: function() {
        this.element.remove();
    },
        
    getWidth: function() {
        return this.element.getWidth();
    },
    
    getHeight: function() {
        return this.element.getHeight();
    }
    
});

/***********************************************************************************************************/

makandra.Clock = Class.create(makandra.Component, {
    
    initialize: function() {
        this.element = $('clock');
        this.setOpacity(0.75);
        this.update();
        this.updater = new PeriodicalExecuter(this.update.bind(this), 10);
    },
        
    update: function() {
        var now = new Date();
        var hours = now.getHours() + '';
        var minutes = now.getMinutes() + '';
        if (hours.length == 1) {
            hours = '0' + hours;
        }
        if (minutes.length == 1) {
            minutes = '0' + minutes;
        }
        this.element.innerHTML = hours + ":" + minutes;
    }
    
});

/***********************************************************************************************************/

makandra.Desktop = Class.create(makandra.Component, {
    
    initialize: function(shell) {
        this.shell = shell;
        this.element = $('desktop');
        this.createApplications();
        this.iconGroup = new makandra.IconGroup(
            this.shell,
            this.element, 
            this.applications,
            makandra.IconGroup.ALIGN_VERTICALLY
        );
    },
        
    pulsate: function() {
        Effect.Pulsate(this.iconGroup.element, { duration: 1.3, from: 0.0, pulses: 2 });
    },
        
    createApplications: function() {
        this.applications = [
            // makandra.Applications.get('advice'),
            makandra.Applications.get('leistungen'),
            makandra.Applications.get('produkte'),
            makandra.Applications.get('referenzen'),
            makandra.Applications.get('ueber_uns'),
            makandra.Applications.get('kontakt'),
            makandra.Applications.get('konsole'),
            makandra.Applications.get('community'),
            makandra.Applications.get('warum_webbasierte_software')
        ];
    },        
    
   layout: function() {
        this.setTop(this.shell.getClientTop());
        this.setHeight(this.shell.getClientHeight());
        this.iconGroup.layout();
    },

    setUnscaledBottomIconPadding: function(padding) {
      this.iconGroup.setBottomIconPadding(this.shell.setUnscaledBottomIconPadding(padding));
    }

});

/***********************************************************************************************************/

makandra.Dock = Class.create(makandra.Component, {
  
    HEIGHT: 30,
    START_BUTTON_WIDTH: 36,
        
    initialize: function(shell) {
        this.shell = shell;
        this.element = $('dock');
        this.tasksElement = $('tasks');
        this.tasks = [];
    },
    
    layout: function() {
        for (var i = 0; i < this.tasks.length; i++) {
            var task = this.tasks[i];
            task.setPosition(this.START_BUTTON_WIDTH + i * makandra.Task.WIDTH, 0);
        }
    },
        
    getHeight: function() {
        return this.HEIGHT;
    },
        
    applicationOpened: function(application) {
        var task = new makandra.Task(this.shell, this.tasksElement, application);
        this.tasks.push(task);
        this.layout();
    },
        
    applicationClosed: function(application) {
        var task = this.findTask(application);
        task.destroy();
        this.tasks = this.tasks.without(task);
        this.layout();
    },
        
    applicationFocused: function(application) {
        var task = this.findTask(application);
        task.focus();
    },
        
    applicationBlurred: function(application) {
        var task = this.findTask(application);
        task.blur();
    },
        
    findTask: function(application) {
        return this.tasks.detect(function(task) {
            return task.application == application;
        });
    }
    
});

/***********************************************************************************************************/

makandra.Icon = Class.create(makandra.Component, {
    
    HEIGHT: 110,
    WIDTH: 150,

    initialize: function(shell, container, application) {
        this.shell = shell;
        this.container = container;
        this.application = application;
        this.createElement();
    },
        
    createElement: function() {
        this.element = new Element("div", { 
            "class": "icon"
        });
        this.imageElement = new Element("img", { 
            "class": "icon_image", 
            "src": this.application.getAbsoluteIconPath(), 
            "alt": "" 
        });
        makandra.Util.fixTransparency(this.imageElement);
        this.labelElement = new Element("div", { "class": "icon_label" });
        this.labelTextElement = new Element("span", { "class": "icon_label_text" }).update(this.application.getShortTitle());
        this.labelShadowElement = new Element("div", { "class": "icon_label_shadow" }).update(this.application.getShortTitle());
        // this.labelShadowElement.setOpacity(0.5);
        this.labelElement.appendChild(this.labelTextElement);
        this.element.appendChild(this.imageElement);
        this.element.appendChild(this.labelShadowElement);
        this.element.appendChild(this.labelElement);
        this.addElementEvents();
        this.container.appendChild(this.element);
    },
        
    addElementEvents: function(i) {
        [this.imageElement, this.labelTextElement].each(function(element) {
            Event.observe(element, "click", function(event) {
                this.shell.openApplication(this.application);
                return false;
            }.bind(this));
            Event.observe(element, "mouseover", function(event) {
                this.element.addClassName("hover");
            }.bind(this));
            Event.observe(element, "mouseout", function(event) {
                this.element.removeClassName("hover");
            }.bind(this));
        }.bind(this));
    },
    
    setLabelColor: function(color) {
      this.labelTextElement.setStyle({ color: theme[1] })
    }
           
});

makandra.Icon.IMAGE_ROOT = "/images/icons";

/***********************************************************************************************************/

makandra.IconGroup = Class.create(makandra.Component, {
    
    TOP_OFFSET: 20,
    LEFT_OFFSET: 0,
    
    initialize: function(shell, container, applications, alignment) {
        this.shell = shell;
        this.container = container;
        this.element = new Element("div", { "class": "icon_group" });
        this.container.appendChild(this.element);
        this.applications = applications;
        this.alignment = alignment;
        this.bottomIconPadding = 0;
        this.createIcons();
        this.layout();
    },
    
    createIcons: function() {
        this.icons = [];
        this.applications.each(function(application) {
            var icon = new makandra.Icon(this.shell, this.element, application);
            this.icons.push(icon);
        }.bind(this));
    },
        
    layout: function() {
        this.setSize(this.container.getWidth(), this.container.getHeight());
        if (this.alignment == makandra.IconGroup.ALIGN_VERTICALLY) {
            this.layoutVertically();
        } else {
            this.layoutHorizontally();
        }
    },
        
    layoutVertically: function() {
        var y = this.TOP_OFFSET;
        var x = this.LEFT_OFFSET;
        var iconSpace = this.container.getHeight() - this.bottomIconPadding;
        for (var i = 0; i < this.icons.length; i++) {
            var icon = this.icons[i];
            if (y + icon.HEIGHT > iconSpace) {
                y = this.TOP_OFFSET;
                x += icon.WIDTH;
            }
            icon.setPosition(x, y);
            y += icon.HEIGHT;
        }
    },
        
    layoutHorizontally: function() {
        var y = this.TOP_OFFSET;
        var x = this.LEFT_OFFSET;
        for (var i = 0; i < this.icons.length; i++) {
            var icon = this.icons[i];
            if (x + icon.WIDTH > this.container.getWidth()) {
                x = this.LEFT_OFFSET;
                y += icon.HEIGHT;
            }
            icon.setPosition(x, y);
            x += icon.WIDTH;
        }
    },
    
    setLabelColor: function(color) {
      this.icons.each(function(icon) {
        icon.setLabelColor(color);
      });
    },

    setBottomIconPadding: function(padding) {
      this.bottomIconPadding = padding;
      this.layout();
    }
    
});

makandra.IconGroup.ALIGN_VERTICALLY =  0;
makandra.IconGroup.ALIGN_HORIZONTALLY =  1;

/***********************************************************************************************************/

makandra.PageAttributes = Class.create({
    
    initialize: function() {
        this.descriptionElement = $$('meta[name=description]')[0];
        this.keywordsElement = $$('meta[name=keywords]')[0];
        this.robotsElement = $$('meta[name=robots]')[0];
        this.initialDescription = this.descriptionElement.getAttribute('content');
        this.initialKeywords = this.keywordsElement.getAttribute('content');
        this.initialRobots = this.robotsElement.getAttribute('content');
        this.initialTitle = document.title;
    },
    
    set: function(attributes) {
        this.descriptionElement.setAttribute('content', attributes.description || '');
        this.keywordsElement.setAttribute('content', attributes.keywords || '');
        this.robotsElement.setAttribute('content', attributes.robots || '');
        document.title = attributes.title || this.initialTitle;
    },
        
    reset: function() {
        this.set({
            description: this.initialDescription, 
            keywords: this.initialKeywords, 
            robots: this.initialRobots,
            title: this.initialTitle
        });
    }
    
});

/***********************************************************************************************************/

makandra.Shell = Class.create(makandra.Component, {

    TITLE_POSTFIX: "makandra GmbH, Augsburg, München | Individuelle Web Software, Programmierung, Entwicklung & Support",

    initialize: function() {
        showSplashAndWelcome = (location.hash == "" || location.hash == "#");
        this.element = $('shell');
        this.element.removeClassName('hidden');
        this.dock = new makandra.Dock(this);
        this.wallpaper = new makandra.Wallpaper(this);
        this.desktop = new makandra.Desktop(this);
        this.themeSwitcher = new makandra.ThemeSwitcher(this);
        this.splash = new makandra.Splash(this, showSplashAndWelcome);
        this.splash.schedule(showSplashAndWelcome);
        this.openApplications = [];
        this.pageAttributes = new makandra.PageAttributes();
        this.focusedWindow = null;
        this.focusedApplication = null;
        this.focusedApplicationHistory = [];
        this.layout();
        this.lastLocationHash = null;
        Event.observe(window, 'resize', this.layout.bind(this));
        new PeriodicalExecuter(this.checkForLocationHashChange.bind(this), 0.4);
        $('shell_startup').addClassName('hidden');
    },
    
    setLocationHash: function(hash) {
        this.lastLocationHash = hash;
        location.hash = hash;
    },
        
    checkForLocationHashChange: function() {
        var hash = location.hash;
        if (hash != this.lastLocationHash) {
            this.lastLocationHash = hash;
            this.locationHashChanged(hash);
        }
    },
        
    locationHashChanged: function(newHash) {
        if (newHash != "" && newHash != "#") {
            var applicationID = newHash.substr(1);
            var application = makandra.Applications.get(applicationID) || makandra.Applications.get('willkommen');
            if (application != null) {
                this.openApplication(application);
            } else {
                this.setLocationHash("#");
            }
        }
    },
        
    layout: function() {
        this.dock.layout();
        this.wallpaper.layout();
        this.desktop.iconGroup.bottomIconPadding = this.wallpaper.bottomIconPadding;
        this.desktop.layout();
        this.splash.layout();
        if (this.focusedWindow != null) {
            this.focusedWindow.layout();
        }
    },
        
    getClientTop: function() {
        return this.dock.getHeight();
    },
        
    getClientHeight: function() {
        return this.getHeight() - this.getClientTop();
    },
    
    getClientWidth: function() {
        return this.getWidth();
    },
        
    openApplication: function(application, options) {
        if (application.directLink) {
            pageTracker._trackPageview(application.directLink);
            window.open(application.directLink, '_blank');
        }
        else {
            var wasOpen = true;
            if (!this.openApplications.include(application)) {
                this.openApplications.push(application);
                this.dock.applicationOpened(application);
                wasOpen = false;
            }
            this.focusApplication(application, wasOpen, options);
        }
    },
        
    focusApplication: function(application, wasOpenBefore, options) {
        // alert("focus");
        if (application != this.focusedApplication) {
            if (this.focusedApplication && this.focusedApplication.closeOnBlur) {
                this.closeFocusedApplication();
            } else {
                this.blurFocusedApplication();
            }
            this.focusedApplication = application;
            this.focusedWindow = new makandra.Window(this, application, wasOpenBefore, options);
            this.dock.applicationFocused(this.focusedApplication);
            this.focusedApplicationHistory.push(application);
            this.setLocationHash("#" + application.name);
            this.pageAttributes.set({
                title: application.browserTitle || application.title,
                description: application.description, 
                keywords: application.keywords, 
                robots: application.hideFromCrawlers ? "noindex,nofollow" : "index,follow"
            });
        }
    },
        
    blurFocusedApplication: function(isBeforeDestroy) {
        if (this.focusedApplication) {
            var formerFocusedWindow = this.focusedWindow;
            var formerFocusedApplication = this.focusedApplication;
            this.focusedWindow = null;
            this.focusedApplication = null;
            formerFocusedWindow.saveApplicationState();
            formerFocusedWindow.destroy(isBeforeDestroy);
            this.dock.applicationBlurred(formerFocusedApplication);
            this.pageAttributes.reset();
        }
    },
        
    closeFocusedApplication: function() {
        if (this.focusedApplication) {
            var formerFocusedApplication = this.focusedApplication;
            this.blurFocusedApplication(true);
            this.openApplications = this.openApplications.without(formerFocusedApplication);
            this.dock.applicationClosed(formerFocusedApplication);
            this.focusedApplicationHistory.pop();
            this.setLocationHash("#");
            var newFocus = this.findLastFocusedApplicationStillOpen();
            if (newFocus) {
                if (newFocus.reopenAutomatically) this.focusApplication(newFocus, true);
            }
        }
    },
        
    findLastFocusedApplicationStillOpen: function() {
        var match = null;
        for (var i = this.focusedApplicationHistory.length - 1; i >= 0; i--) {
            var application = this.focusedApplicationHistory[i];
            if (this.openApplications.include(application)) {
                match = application;
                break;
            }
        }
        return match;
    },

    setUnscaledBottomIconPadding: function(padding) {
      return this.wallpaper.setUnscaledBottomIconPadding(padding);
    }
    
});

/***********************************************************************************************************/

makandra.Splash = Class.create(makandra.Component, {

    SPLASH_WIDTH: 300,
    SPLASH_HEIGHT: 160,
    DELAY: 400,
    FADE_OUT_DURATION: 0.4, 
    LOADING_OPACITY: 0.5,
    ICON_IDS: [
        'splash_icon_logo', 'splash_icon_clock', 'splash_icon_dock', 
        'splash_icon_icons', 'splash_icon_welcome'
    ],
    ASSOCIATED_IDS: [
        'logo', 'clock_container', 'dock_container', 
        'desktop', null
    ],
    ICON_NAMES: [
        "Lade Logo…", "Lade Uhr…", "Lade Taskleiste…", 
        "Lade Icons…", "Lade Fenster…", "Fertig."
    ],

    initialize: function(shell, visible) {
        this.element = $('splash_container');
        this.child = $('splash');
        this.shell = shell;
        this.visible = visible;
        this.loadingText = $('splash_load_text');
        this.iconList = $('splash_icons');
        if (this.visible) this.initOpacity();
    },

    initOpacity: function() {
        for (var i = 0; i < this.ICON_IDS.length; i++) {
            this.setOpacity(i, this.LOADING_OPACITY, 0);
        }
    },

    layout: function() {
        this.setSize(this.SPLASH_WIDTH, this.SPLASH_HEIGHT);
        makandra.Util.setSize(this.child, this.SPLASH_WIDTH - 4, this.SPLASH_HEIGHT - 4);
        this.setPosition(this.computeLeft(), this.computeTop());
        this.element.removeClassName("hidden");
    },

    computeLeft: function() {
        return (this.shell.getWidth() - this.SPLASH_WIDTH) * 0.5;
    },

    computeTop: function() {
        return (this.shell.getHeight() - this.SPLASH_HEIGHT) * 0.3;
    },

    schedule: function(showWelcome) {
        if (this.visible) {
            for (var i = 0; i < this.ICON_IDS.length; i++ ) {
                setTimeout(this.showText.bind(this, this.ICON_NAMES[i]), i * this.DELAY);
                setTimeout(this.setOpacity.bind(this, i, 1, 1), (i+1) * this.DELAY);
            }
            l = this.ICON_IDS.length;
            setTimeout(this.showText.bind(this, this.ICON_NAMES[l]), l * this.DELAY);
            setTimeout(this.hideSplash.bind(this), l * this.DELAY);
        }
        else
        {
            this.element.remove();
        }
        if (showWelcome) {
            setTimeout(this.openWelcome.bind(this), this.ICON_IDS.length * this.DELAY);
        }
    },

    setOpacity: function(i, opacity, associated_opacity) {
        $(this.ICON_IDS[i]).setOpacity(opacity);
        if (this.ASSOCIATED_IDS[i]) $(this.ASSOCIATED_IDS[i]).setOpacity(associated_opacity);
    },

    showText: function(newText) {
        this.loadingText.innerHTML = newText;
    },

    hideSplash: function() {
        Effect.Fade(this.element, this.FADE_OUT_DURATION);
    },

    openWelcome: function() {
        setTimeout(this.shell.openApplication.bind(this.shell, makandra.Applications.get('willkommen')), this.SHOW_WELCOME_DELAY);
    }
});


/***********************************************************************************************************/

makandra.Task = Class.create(makandra.Component, {
    
    initialize: function(shell, container, application) {
        this.shell = shell;
        this.container = container;
        this.application = application;
        this.createElement();
    },
    
    createElement: function() {
        this.element = new Element("span", { "class": "task_container" });
        this.linkElement = new Element("a", {
            "class": "task",
            "href": "#",
            "onclick": "return false;"
        });
        this.imageElement = new Element("img", { src: this.application.getAbsoluteSmallIconPath(), "class": "task_icon" });
        this.labelElement = new Element("span", { "class": "task_label" }).update(this.getLabelText());
        this.linkElement.appendChild(this.imageElement);
        this.linkElement.appendChild(this.labelElement);
        this.element.appendChild(this.linkElement);
        this.addElementEvents();
        this.container.appendChild(this.element);
        makandra.Util.fixTransparency(this.imageElement);
    },
        
    getLabelText: function() {
        return makandra.Util.truncate(this.application.title, 20);
    },
        
    addElementEvents: function() {
        Event.observe(this.linkElement, "click", function() {
            this.shell.focusApplication(this.application, true);
            return false;
        }.bind(this));
    },
        
    focus: function() {
        this.element.addClassName("focused_task_container");
    },
        
    blur: function() {
        this.element.removeClassName("focused_task_container");
    }
        
});

makandra.Task.WIDTH = 180;

/***********************************************************************************************************/

makandra.ThemeSwitcher = Class.create(makandra.Component, {
  
  THEMES: [
    ['/images/shell/wallpaper_0.jpg', '#eeeeee', 0, '/images/shell/wallpaper_0_thumb.png'],
    ['/images/shell/wallpaper_1.jpg', '#000000', 0, '/images/shell/wallpaper_1_thumb.png'], 
    ['/images/shell/wallpaper_2.jpg', '#000000', 0, '/images/shell/wallpaper_2_thumb.png'], 
    ['/images/shell/wallpaper_3.jpg', '#eeeeee', 375, '/images/shell/wallpaper_3_thumb.png'], 
    ['/images/shell/wallpaper_4.jpg', '#eeeeee', 0, '/images/shell/wallpaper_4_thumb.png'],
    ['/images/shell/wallpaper_5.jpg', '#eeeeee', 0, '/images/shell/wallpaper_5_thumb.png']
  ],
  
  initialize: function(shell) {
    this.shell = shell;
    this.setupElement();
    this.element = $('theme_switcher');
    this.setupChildElements();
    this.setThemeOfTheDay();
  },
  
  setupElement: function() {
    var themeSwitcher = new Element("div", { "id": "theme_switcher" });
    this.shell.desktop.element.appendChild(themeSwitcher);
  },

  setHover: function(element, hover) {
    var elements = element.up("#theme_switcher").select(".theme_switch");
    elements.each(function(el) {
      el.removeClassName("hover");
      if (hover && element == el) {
        el.addClassName("hover");
      }
    }.bind(this));
  },

  observeThemeSwitch: function(themeSwitch, theme) {
    themeSwitch.observe('click', this.switchTheme.bind(this, theme));
    themeSwitch.observe('mouseover', this.setHover.bind(this, themeSwitch, true) );
    themeSwitch.observe('mouseout',  this.setHover.bind(this, themeSwitch, false) );
  },

  setupChildElements: function() {
    this.THEMES.each(function(theme) {
      var imageThumbPath = theme[3];
      var themeSwitch = new Element("div", { "class": "theme_switch" });
      this.element.appendChild(themeSwitch);
      // This might seem a bit complicated but actually is the only way to work in every browser
      var image = new Element("img", { "src": imageThumbPath, "class": "inactive_image" });
      themeSwitch.appendChild(image);
      makandra.Util.fixTransparency(image);
      var hoverImage = new Element("img", { "src": imageThumbPath, "class": "active_image" });
      themeSwitch.appendChild(hoverImage);
      makandra.Util.fixTransparency(hoverImage);
      this.observeThemeSwitch(themeSwitch, theme);
    }.bind(this));
    this.element.appendChild(new Element("div", { "class": "clear" }));
  },
  
  switchTheme: function(param) {
    theme = this.THEMES.detect(function(e) { return e == param });
    if (theme) {
      this.shell.wallpaper.setImage(theme[0]);
      this.shell.desktop.iconGroup.setLabelColor(theme[1]);
      this.shell.desktop.setUnscaledBottomIconPadding(theme[2]);
    }
  },
  
  setThemeOfTheDay: function() {
    var themeChoice = ((new Date).getMinutes() % this.THEMES.length);
    this.switchTheme(this.THEMES[themeChoice]);
  }
  
});

/***********************************************************************************************************/

makandra.Wallpaper = Class.create(makandra.Component, {
    
    /**
     * Scale the image a little larger than necessary to cover scrollbars
     * and rounding errors.
     */
    IMAGE_PADDING: 30,
    unscaledBottomIconPadding: 120, // 405, // number of pixels in unscaled wallpaper at the bottom, 
                            // that may should not be covered with icons
    IMAGE_WIDTH: 1680,
    IMAGE_HEIGHT: 1120,
      
    initialize: function(shell) {
        this.shell = shell;
        this.setupElement();
        this.image = $('wallpaper_image');
        this.sizingImage = $('wallpaper_sizing_image');
        this.clock = new makandra.Clock();
        this.logo = $('logo');
        this.bottomIconPadding = this.BOTTOM_ICON_PADDING - this.IMAGE_PADDING;
        makandra.Util.fixTransparency(this.logo);
    },
      
    setupElement: function() {
        this.element = $('wallpaper');
        this.element.innerHTML = '' +
            '<img src="" id="wallpaper_image" alt="" galleryimg="false" />' +
            '<!-- galleryimage=false removes hovering image toolbar in IE6 -->' +
            '<img src="/images/shell/logo_dark.png" id="logo" alt="" />' +
            '<div id="clock_container"><div id="clock"></div></div>';
    },
    
    layout: function() {
        
        var widthToCover = this.shell.getClientWidth()  + 2 * this.IMAGE_PADDING;
        var heightToCover = this.shell.getClientHeight() + 2 * this.IMAGE_PADDING;
        var imageWidth = this.IMAGE_WIDTH;
        var imageHeight = this.IMAGE_HEIGHT;
        var imageScale = Math.max(widthToCover / imageWidth, heightToCover / imageHeight);
        var scaledImageWidth = imageScale * imageWidth;
        var scaledImageHeight = imageScale * imageHeight;
        var scaledImageOffsetX = (widthToCover - scaledImageWidth) - this.IMAGE_PADDING;
        var scaledImageOffsetY = (heightToCover - scaledImageHeight) / 2 - this.IMAGE_PADDING;

        this.bottomIconPadding = Math.max((this.unscaledBottomIconPadding * imageScale) - this.IMAGE_PADDING + scaledImageOffsetY, 0);
        
        this.setTop(this.shell.getClientTop());
        this.setHeight(this.shell.getClientHeight());
            
        this.image.setStyle({
            top: Math.round(scaledImageOffsetY) + "px",
            left: Math.round(scaledImageOffsetX) + "px",
            width: Math.round(scaledImageWidth) + "px",
            height: Math.round(scaledImageHeight) + "px"
        });

    },
    
    setImage: function(imagePath) {
      this.image.src = imagePath;
    },

    setUnscaledBottomIconPadding: function(padding) {
      this.unscaledBottomIconPadding = padding;
      this.layout();
      return this.bottomIconPadding;
    }

});

/***********************************************************************************************************/

makandra.Window = Class.create(makandra.Component,  {
    
    FADE_IN_DELAY: 0.1,
    FADE_IN_DURATION: 0.7,
    FADE_OUT_DURATION: 0.4,
    CANVAS_FADE_IN_DURATION: 0.2,
    CANVAS_FADE_OUT_DURATION: 0.2,
    HEAD_HEIGHT: 32,
    CLOSE_BUTTON_PASSIVE_OPACITY: 0.5,
    CLOSE_BUTTON_HOVER_OPACITY: 1.0,
    
    initialize: function(shell, application, wasOpenBefore, options) {
        this.shell = shell;
        this.application = application;
        this.container = $('desktop');
        this.createElement();
        this.layout();
        this.fillCanvasFromSource(wasOpenBefore, options);
        this.layout();
        this.appear(wasOpenBefore);
    },
    
    /**
     * The window elements are nested like this:
     *
     * window_container
     *   window
     *     window_inner
     *       window_head
     *         window_icon
     *         window_title
     *         window_close_button
     *       window_canvas
     *         (window_iframe or source DOM element)
     */
    createElement: function() {
        var elementID = this.application.name + "_window_container";
        this.element = new Element("div", { "class": "window_container", "id": elementID });
        this.childElement = new Element("div", { "class": "window" });
        this.childChildElement = new Element("div", { "class": "window_inner" });
        this.headElement = new Element("div", { "class": "window_head" });
        this.iconElement = new Element("img", { "class": "window_icon", "src": this.application.getAbsoluteSmallIconPath() });
        this.createCloseButtonElement();
        makandra.Util.fixTransparency(this.iconElement);
        this.titleElement = new Element("div", { "class": "window_title" }).update(this.application.title);
        this.canvasElement = new Element("div", { "class": "window_canvas" }); //.update("canvas");
        this.canvasElement.hide();
        this.headElement.appendChild(this.iconElement);
        this.headElement.appendChild(this.closeButtonElement);
        this.headElement.appendChild(this.titleElement);
        this.childChildElement.appendChild(this.headElement);
        this.childChildElement.appendChild(this.canvasElement);
        this.childElement.appendChild(this.childChildElement);
        this.element.appendChild(this.childElement);
        this.container.appendChild(this.element);
        makandra.Window.iframeCounter += 1;
        this.iframeName = "window_iframe_" + makandra.Window.iframeCounter;
        new Draggable(elementID, { revert: true });
    },
        
    createCloseButtonElement: function() {
        /* Wrap the image in a DIV because we cannot apply opacity to a image that was fixed for
           IE's alpha channel disability */
        this.closeButtonElement = new Element("div", { "class": "close_window_button" });
        this.closeButtonImageElement = new Element("img", { "src": "/images/shell/close_window_button.png" });
        makandra.Util.fixTransparency(this.closeButtonImageElement);
        this.closeButtonElement.appendChild(this.closeButtonImageElement);
        Event.observe(this.closeButtonElement, "mouseover", this.onCloseButtonMouseOver.bind(this));
        Event.observe(this.closeButtonElement, "mouseout", this.onCloseButtonMouseOut.bind(this));
        Event.observe(this.closeButtonElement, "click", this.onCloseButtonClick.bind(this));
        this.onCloseButtonMouseOut(); // show passive opacity
    },
        
    fillCanvasFromSource: function(wasOpenBefore, options) {
        var sourceType = typeof(this.application.source);
        if (sourceType == 'function') {
            this.sourceComponent = this.application.source(this.canvasElement);
        } else if (sourceType == 'string') {
            var source = this.application.source;
            if (options) source+= "?" + options;
            if (wasOpenBefore && this.application.lastURI && !options) source = this.application.lastURI;
            this.iframeElement = new Element("iframe", { 
                "class": "window_iframe", 
                "src": source, 
                "name": this.iframeName,
                "frameborder": "0"
            });
            this.canvasElement.appendChild(this.iframeElement);
            // this.iframeElement.document.body.focus();
        } else {
            alert("Unknown application source type: " + sourceType);
        }
    },

    saveApplicationState: function() {
        if (this.iframeElement) {
            try {
                this.application.lastURI = window[this.iframeName].location.href;
            } catch(e) {
                // Every now and then Firefox throws an internal error in the block above.
            }
        }
    },
        
    onCloseButtonMouseOver: function() {
        this.closeButtonElement.setOpacity(this.CLOSE_BUTTON_HOVER_OPACITY);
    },
        
    onCloseButtonMouseOut: function() {
        this.closeButtonElement.setOpacity(this.CLOSE_BUTTON_PASSIVE_OPACITY);
    },
        
    onCloseButtonClick: function() {
        if (this.application.onManualClose) {
          eval(this.application.onManualClose);
        }
        this.shell.closeFocusedApplication();
    },
        
    layout: function() {
        this.setSize(this.getWidth(), this.getHeight());
        this.setPosition(this.computeLeft(), this.computeTop());
        makandra.Util.setSize(this.childElement, this.getWidth() - 2, this.getHeight() - 2);
        makandra.Util.setSize(this.childChildElement, this.getWidth() - 4, this.getHeight() - 4);
        makandra.Util.setSize(this.headElement, this.getWidth() - 6, this.HEAD_HEIGHT);
        makandra.Util.setSize(this.canvasElement, this.getWidth() - 6, this.getHeight() - 6 - this.HEAD_HEIGHT);
        if (this.sourceComponent && this.sourceComponent.layout) {
            this.sourceComponent.layout();
        }
    },
        
    computeTop: function() {
        return 0.5 * (this.container.getHeight() - this.getHeight());
    },
        
    computeLeft: function() {
        return 0.5 * (this.container.getWidth() - this.getWidth());
    },
        
    getWidth: function() {
        return this.application.windowWidth;
    },
        
    getHeight: function() {
        return this.application.windowHeight;
    },
        
    appear: function(wasOpenBefore) {
        this.setOpacity(0.0);
        new Effect.Appear(this.element, { 
            duration: this.FADE_IN_DURATION,
            delay: this.FADE_IN_DELAY,
            afterFinish: function() {
                new Effect.Appear(this.canvasElement, {
                   duration: this.CANVAS_FADE_IN_DURATION,
                   afterFinish: function() {
                       setTimeout(this.focusIframe.bind(this), 50);
                       setTimeout(this.triggerIframeEvent.bind(this), 60);
                   }.bind(this)
                });
            }.bind(this)
        });
        this.setPosition(this.computeLeft() + (wasOpenBefore ? 400 : - 400), this.computeTop());
        new Effect.Move(this.element, { 
            x: (wasOpenBefore ? -400 : 400),
            y: 0,
            mode: 'relative',
            duration: this.FADE_IN_DURATION,
            delay: this.FADE_IN_DELAY,
            transition: Effect.Transitions.invertedCubic
        });
    },
      
    focusIframe: function() {
        if (this.iframeElement) {
            // alert("f");
            this.iframeElement.focus();
        }
    },

    triggerIframeEvent: function() {
        if (this.iframeElement) {
          var innerDocument = this.iframeElement.contentWindow || this.iframeElement.contentDocument;
          if ( innerDocument.document ) {
            innerDocument = innerDocument.document;
          }

          innerDocument.fire('shellWindow:show');
        }
    },
        
    destroy: function(vertical) {
        if ( this.iframeElement ) this.iframeElement.name = '';
        new Effect.Fade(this.canvasElement, {
            duration: this.CANVAS_FADE_OUT_DURATION,
            afterFinish: function() {
                new Effect.Move(this.element, { 
                    x: vertical ? 0 : 600, 
                    y: vertical ? 600 : 0, 
                    mode: 'relative', 
                    duration: this.FADE_OUT_DURATION,
                    transition: Effect.Transitions.square
                });
                new Effect.Fade(this.element, { 
                    duration: this.FADE_OUT_DURATION,
                    afterFinish: function() {
                        if ( this.iframeElement ) this.iframeElement.remove();
                        this.element.remove();
                    }.bind(this)
                });
            }.bind(this)
        });
    }
            
});

// Leitet www.makandra.de/foo auf www.makandra.de/#foo um
makandra.tryRedirectToHashPath = function() {
    if (location.pathname.length > 1 && location.pathname.substr(1, 1) != "#" && location.pathname.substr(1) != "console") {
        location.href = "/#" + location.pathname.substr(1); // .replace(/\-/g, '_');
    }
};

makandra.Window.iframeCounter = 0;

/***********************************************************************************************************/

makandra.launchShell = function(applicationProperties) {
    if (!(parent && parent.makandra && parent.makandra.shell)) {
        makandra.tryRedirectToHashPath ();
        makandra.defineApplications(applicationProperties);
        makandra.preloadImages();
        makandra.shell = new makandra.Shell();
    }
}


﻿var makandra; if (!makandra) { makandra = new Object(); }

makandra.Util = {
    
    loadImage: function(url) {
        var image = new Image();
        image.src = url;
    },
    
    /**
     * @deprecated
     */
    fixTransparencyWithHTC: function(pngImage) {
        pngImage.setStyle({
            behavior: "url(/resources/iepngfix-mod/iepngfix.htc);"
        });
    },
        
    fixTransparency: function(img) {
        if (/MSIE (5\.5|6)/.test(navigator.userAgent)) {
            if (img.complete) {
                this.fixTransparencyForLoadedImage(img);
            } else {
                img.transparencyLoader = this.fixTransparencyForLoadedImage.bind(this, img);
                Event.observe(img, "load", img.transparencyLoader);
            }
        }
    },
        
    fixTransparencyForLoadedImage: function(img) {
        if (img.transparencyLoader) {
            Event.stopObserving(img, "load", img.transparencyLoader);
        }
        var src = img.src;
        img.style.width = img.width + "px";
        img.style.height = img.height + "px";
        img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizingMethod='scale')";
        img.src = "/images/shell/blank.gif";
    },
        
    setWidth: function(element, width) {
        element.setStyle({ "width": width + "px" });
        // alert(width + " -- " + element.getStyle("width") + " -- " + element.getWidth());
    },
        
    setTop: function(element, top) {
        element.setStyle({ "top": top + "px" });
    },
        
    setLeft: function(element, left) {
        element.setStyle({ "left": left + "px" });
    },
        
    setHeight: function(element, height) {
        element.setStyle({ "height": height + "px" });
    },
        
    setPosition: function(element, left, top) {
        this.setLeft(element, left);
        this.setTop(element, top);
    },
    
    setSize: function(element, width, height) {
        this.setWidth(element, width);
        this.setHeight(element, height);
    },
        
    truncate: function(string, maxLength) {
        if (string.length > maxLength) {
            string = string.substr(0, maxLength) + '&hellip;';
        }
        return string;
    }
    
};
