﻿/**
 * Klasse für die Bildergalerie.
 */
var CM_ImageGallery = Class.create();

CM_ImageGallery.prototype = {
    /**
     * Array mit Observern, die benachrichtigt werden wenn eine Bildergalerie
     * geladen wurde.
     * 
     * @type    {Array}
     */
    _observers: [],

    /**
     * Hash mit den Daten der geladenen Bildergalerien.
     * 
     * @type    {Hash}
     */
    _requestCache: {},

    /**
     * Date Objekt für den Timestamp beim nachladen der Galerie.
     * 
     * @type    {Date}
     */
    _time: new Date(),

    /**
     * Hash mit den Daten der Bildergalerien.
     * 
     * @var Hash
     */
    galleries: {},

    /**
     *  Array mit den Ids der Bildergalerien.
     * 
     * @var Array
     */
    imageGalleries: new Array(),

    /**
     * Das Interval zum Prüfen ob die Galerien geladen wurden.
     * 
     * @var intervalID
     */
    interval: undefined,

    /**
     * Anzahl der Requests.
     * 
     * @var {Number}
     */ 
    RequestCount: 0,

    /**
     * Array mit den bereits eingebundenen Scripten.
     * 
     * @var Array
     */
    scripts: new Array(),

    /**
     * Array mit den bereits eingebundenen Styles.
     * 
     * @var Array
     */
    styles: new Array(),



    /**
     * Benachrichtigt die Observer, dass eine Bildergalerie geladen wurde.
     * Status:
     * - loaded
     * 
     * @param   {HTMLDivElement}    gallery Der DIV der Bildergalerie.
     * @param   {String}            status  Der Status der Galerie.
     */
    _notify: function(gallery, status) {
        for (var index = 0; index < this._observers.length; index++) {
            this._observers[index](gallery, status);
        }
    },



    /**
     * Ermittelt die Bildergalerien auf der Seite und lädt diese.
     */
    initialize: function() {
        var regex = /^image_gallery_([0-9_]+)$/;
        var divs = document.getElementsByTagName('div');
        for (var i = 0; i < divs.length; i++) {
            if (regex.test(divs[i].id)) {
                this.imageGalleries.push(divs[i].id.match(regex)[1]);
            }
        }

        this.loadGalleries();
        this.interval = window.setInterval(this.setLoaded.bind(this), 500);
    },



    /**
     * Fügt einen Observer hinzu, der benachrichtigt wird, wenn eine
     * Bildergalerie geladen wurde.
     * 
     * @param   {Function}  callback    Das Callback bekommt den DIV der
     *                                  geänderten Bildergalerie und den
     *                                  aktuellen Status übergeben.
     */
    addObserver: function(callback) {
        this._observers.push(callback);
    },



    /**
     * Fügt die übergebenen Texte einmal der Seite hinzu.
     * 
     * @param   String  category    Zu welchem Bereich die Texte gehören.
     * @param   Array   texts       Die Texte.
     */
    addOnce: function(category, texts) {
        texts = texts.findAll(
            function(value) {
                return !this[category].include(value);
            }.bind(this)
        );
        texts.each(
            function(content) {
                if (category == 'styles') {
                    var element = document.getElementsByTagName('head')[0];
                    if (element.insertAdjacentHTML) {
                        try {
                            //damit IE Styles auch verwendet
                            if (document.createStyleSheet) {
                                document.createStyleSheet(content);
                            } else {
                                content = '<link rel="stylesheet" type="text/css" href="' + content + '" />';
                                element = document.getElementsByTagName('body')[0];
                                element.insertAdjacentHTML('beforeEnd', content);
                            }
                        } catch (e) {
                            throw e;
                        }
                    } else {
                        var link = document.createElement('link');
                        link.rel = 'stylesheet';
                        link.type = 'text/css';
                        link.href = content;
                        element.appendChild(link);
                    }
                } else {
                    content.evalScripts();
                }
            }
        );
        this[category] = this[category].concat(texts);
    },



    /**
     * Fügt eine Bildergalerie in die Seite ein.
     * 
     * @param   {Number}    id      Die Id der Bildergalerie.
     * @param   {Object}    request Das JSON Objekt mit den geladenen Daten.
     */
    displayGallery: function(id, request) {
        var gallery = $('image_gallery_' + id);
        if (gallery == undefined) {
            gallery = $('image_gallery_' + id.match(/(\d+)/g)[0]);
        }

        if (request.status != 200) {
            gallery.remove();
            return;
        }

        this.addOnce('styles', request.styles);

        gallery.innerHTML = request.preview;
        gallery.addClassName('image_gallery');
        if (gallery.id == 'image_gallery_' + id && typeof id == 'string') {
            var link = gallery.getElementsByClassName('image_gallery_index_link');
            if (link.length == 1) {
                Element.remove(link[0]);
            }
        }

        switch (request.type) {
            case 1:
                this.galleries[id] = request.galleryData;
                break;

            case 2:
                document.getElementById('image_gallery_detail_' + id).innerHTML = request.detail;
                Element.addClassName(document.getElementById('image_gallery_detail_' + id), 'image_gallery_detail');
                break;

            case 3:
                window['CM_ImageGallerySingle' + id] = new CM_ImageGallerySingle(id, request.galleryData);
                break;
        }

        var scripts = request.scripts;
        if (scripts.length > 0) {
            this.addOnce('scripts', scripts);
        }

        if (request.type == 1 && window['initLightbox'] != undefined) {
            initLightbox();
        }
        this._notify(gallery, 'loaded');
    },



    /**
     * Lädt eine Url.
     * 
     * @param   {String}    url     Die zu ladende Url.
     * @param   {Object}    options Die Paramter.
     */
    Request: function(url, options) {
        var identifier = options.parameters + '&time=' + this._time.getTime();
        this.RequestCount++;

        if (this._requestCache[identifier] == undefined) {
            var request = document.createElement('script');
            request.type = 'text/javascript';
            request.charset = 'utf-8';
            request.src = url + '?' + identifier;
            document.getElementsByTagName('head')[0].appendChild(request);
        } else {
            this.RequestLoaded(this._requestCache[identifier]);
        }
    },



    /**
     * Verarbeitet die Daten der geladenen Url.
     * 
     * @param   {Object}    json    Die geladenen Daten.
     */
    RequestLoaded: function(json) {
        this._requestCache[json.requestIdentifier] = json;

        this.displayGallery(json.id, json);
        this.RequestCount--;
    },



    /**
     * Lädt die Daten für eine einzelne Bildergalerie.
     * 
     * @param   {Number}    id          Die Id der Bildergalerie.
     * @param   {Hash}      [params]    Hash mit den zusätzlichen Parametern.
     */
    loadGallery: function(id, params) {
        var params = $H(Object.extend(CM_Load.queryParams.toQueryParams(), params || {}));
        params.action = 'json';
        params.moduleId = 175;
        params.imageGalleryId = id.match(/(\d+)/g)[0];
        if (id.match(/(\d+)/g)[1] != undefined) {
            params.categoryId = id.match(/(\d+)/g)[1];
        }
        this.Request(
            CM_Load.baseUrl + '../index.php',
            {
                method: 'get',
                parameters: params.toQueryString(),
                onComplete: this.displayGallery.bind(this, id)
            }
        )
    },



    /**
     * Lädt die Bildergalerien.
     */
    loadGalleries: function() {
        this.imageGalleries.each(
            function (id) {
                new Insertion.Bottom('image_gallery_' + id, '<img src="' + CM_Load.baseUrl + 'images/modules/lightbox/loading.gif" alt="" />');

                this.loadGallery(id);
            }.bind(this)
        );
    },



    /**
     * Löst einen onload Event aus.
     */
    setLoaded: function() {
        if (this.RequestCount == 0 && window['initLightbox'] != undefined) {
            window.clearInterval(this.interval);

            initLightbox();
        }
    }
}

var CM_RequestLoaded = Class.create();
CM_RequestLoaded.prototype = {
    interval: undefined,
    json: undefined,
    send: function() {
        if (window.CM_ImageGalleryInstance != undefined) {
            window.clearInterval(this.interval);
            window.CM_ImageGalleryInstance.RequestLoaded(this.json);
        }
    },
    initialize: function(json) {
        this.json = json;
        this.interval = window.setInterval(this.send.bind(this), 500);
    }
}

if (window.Effect === undefined) {
    CM_Load.require('modules/scriptaculous/effects.js');
}
var staticFilesUrl = CM_Load.baseUrl;
if (window.Lightbox === undefined) {
    CM_Load.require('modules/lightbox.js');
}
if (window.CM_ImageGallerySwitch === undefined) {
    CM_Load.require('ImageGallerySwitch.js');
}
if (window.CM_ImageGallerySingle === undefined) {
    CM_Load.require('ImageGallerySingle.js');
}

window.CM_ImageGalleryInstance = new CM_ImageGallery;