function Gallery(){

    var _thumb  = null;
    var _slider = null;
    var _self   = this;
    
    var _main   = null;
    var _id     = -1;

    /**
     * speichert die Bild Informationen ab
     * 0 = Bild Src
     * 1 = Bild Beschreibung
     * 2 = Bild Weite
     * 3 = Bild Höhe
     * 4 = Bild Index
     */
    var _imghash = [];

    var _description = null;
    var _wrapper     = null;

    var _oldwidth  = 0;
    
    var _scalemode      = 0;
    var _scalevelocity  = 0.14;
    var _scalespeed     = 0;
    var _scalewidth     = 0;

    var preloader = document.createElement('div');
        preloader.className = "gallery_preloader";
        
    var text = document.createElement("p");
        text.appendChild(document.createTextNode("Loading ... "));
    
    preloader.appendChild(text);

    /** 
     * constructor
     */
    (function(){
        var ground    = document.getElementById("thumbs");
        var thumblist = document.getElementById("thumblist");

        _wrapper     = document.getElementById('gallery_wrapper');
        _description = document.getElementById('gallery_desc');

        _slider = new Slider(ground,thumblist);
        _thumb  = new Thumbs(thumblist);

        _main = document.getElementById('mainimg');

        prepareFirstImage();

        //navigation klar machen
        var _back = document.getElementById('gb');
        var _forw = document.getElementById('gf');

        addEvent(_back, "click", function(){
            showPreviousThumb();
        });

        addEvent(_forw, "click", function(){
            showNextThumb();
        });

        _thumb.addObserver( _self );
    })();

    function trim(node){
        node.innerHTML = node.innerHTML.replace(/>\s*/gm,">");
        node.innerHTML = node.innerHTML.replace(/\s*</gm,"<");
        node.innerHTML = node.innerHTML.replace(/>\s*</gm,"><");
    };

    function addEvent(element,type,callback){
        if(element.attachEvent) {
            if(!type.match(/^on(.*)/)) type = "on"+type;
            element.attachEvent(type,handleEvent,false);
        } else {
            element.addEventListener(type,handleEvent,false);
        }

        function handleEvent(event){
            var e = event || window.event;
            callback.call(e);
        };
    };

    function stopEvent(event){
        if(event.stopPropagation) event.stopPropagation();
        else                      event.cancleBubble = true;

        if(event.preventDefault)  event.preventDefault();
        else                      event.returnValue = false;
    };

    /**
     * das vorherige Bild anzeigen
     * @access private
     */
    function showPreviousThumb(){
        _slider.displayNode(_imghash[4]-1);
        _thumb.displayThumb(_imghash[4], -1);
    };

    /**
     * das nächste Bild anzeigen
     * @access private
     */
    function showNextThumb(){
        _slider.displayNode(_imghash[4]+1);
        _thumb.displayThumb(_imghash[4], 1);
    };

    function setOpacity(node,value){
        if(!navigator.userAgent.match(/msie/i) ) {
            node.style.opacity = value;
        } else {
            node.style.filter = "alpha(opacity="+(Math.round(value*100))+")";
        }
    };

    /**
     * beim starten das erste Bild vorbereiten
     * @access private
     */
    function prepareFirstImage(){
        trim(_main);

        _imghash = ["","",parseInt(_main.style.width),parseInt(_main.offsetHeight),0];
        _oldwidth = [_imghash[2]];

        _wrapper.style.width = (_imghash[2]+56)+"px";
    };

    /**
     * ein neues Bild über Ajax laden sobald die Bildinformationen
     * geladen wurden und das Bild selber wird es in displayImage
     * aufgerufen
     * @access private
     * @param _gallery String
     */
    function loadImage(_gallery){
        // ajax request absetzen
        // daten holen
        var route = "";

        if( window.location.search != "" )
            route = "index.php"+window.location.search;
        else
            route = window.location.pathname;

        var ajax = {
            method:"POST",
            path:route,
            params:{
                ajax:true,
                imgid:_id,
                gallery:_gallery
            }
        };
        _main.insertBefore(preloader, _main.firstChild );

        new Load.ajaxContent(ajax).initLoad(null,function(img){
            
            var _det     = img.split("#");

            var _img     = new Image();
                _img.src = _det[0];
                _img.style.display = "none";

            setOpacity(_img, 0);

            _det[1] = _det[1].replace(/^"(.*?)"$/,"$1");
            _imghash = [_img, _det[1],                       // Src, Beschreibung
                        parseInt(_det[2]), parseInt(_det[3]) // Weite, Höhe
                        ,parseInt(_det[4])                   // Index
                       ];

            if(_img.complete) {
                displayImage();
            } else {
                _img.onload = function(){
                    displayImage();
                }
            }
        });
    };

    /**
     * das neue Bild anzeigen
     * gleichzeitiges Berechnen der Weite um die das neue Bild skaliert
     * werden muss ruft dann scale auf
     * @access private
     */
    function displayImage(){
        if (_oldwidth > 0) {

            if(_oldwidth < _imghash[2])  _scalemode =  1;
            else                         _scalemode = -1;

            _scalewidth = Math.abs(_oldwidth-_imghash[2]);
            
            _main.innerHTML = "";
            _description.innerHTML = "";

            scale();
        }
    };

    /**
     * den Hauptbereich main für den Wert Scalewidth skalieren
     * sobald die skalierung abgeschlossen ist das Bild darstellen
     * und die Bildbeschreibung anzeigen
     * @access private
     */
    function scale(){
        _scalespeed += _scalevelocity;

        var _newwidth = _scalewidth*Math.sin(_scalespeed)*_scalemode;

        if(_scalespeed > Math.PI/2) {

            _scalespeed = 0;

            _main.style.width    = _imghash[2]+"px";
            _wrapper.style.width = (parseInt(_imghash[2])+56)+"px";

            _main.appendChild(_imghash[0]);
            _description.innerHTML = _imghash[1];

            setVisible(_imghash[0], 1);

        } else {
            var w = parseInt(_oldwidth)+_newwidth;
            
            _main.style.width    = w + "px";
            _wrapper.style.width = (w+56)+"px";
            window.setTimeout(scale,40);
        }
    };

    function setVisible( img , modi ){
        img.style.display = "block";

        var veloc = 0.12;
        var speed = 0;
        var end   = (modi && modi == -1) ? 0:1;

        function fade(){
            speed += veloc;

            if(speed < Math.PI/2) {

                var newval = speed * Math.sin(speed);
                setOpacity(img,newval);

                window.setTimeout(fade,40);
            } else
                setOpacity(img,end);
        }
        fade();
    };

    /**
     * wird von Thumb.class.js aufgerufen wenn
     * ein neuer Thumb angezeigt wird
     * @access public
     * @param thumb HTML Object image
     */
    this.update = function( thumb ){

        var _gallery = thumb.src.match(/[^\/]+(?=\/small_thumbs)/)[0];
        
        _id = thumb.id.replace(/^.*?([\d]+)$/,"$1");

        if(_imghash[4] != _id && _id != -1) {
            _oldwidth = _imghash[2];
        }

        loadImage(_gallery);
    };
};
