function slide(src){
    this.src = src;
    this.start_load = false;

    if(document.images) this.image = new Image();

    this.image.onload = function(){
        this.loaded = true;
    }

    this.load = function(){
        if(this.start_load || !document.images) return;
        this.start_load = true;
        if(/Konqueror|Safari|KHTML/i.test(navigator.userAgent)) this.image.loaded = true;
        else this.image.loaded = false;
        this.image.src = this.src;
    }
}

function slideshow(slideshowname){
    this.name = slideshowname;
    this.repeat = true;
    this.prefetch = 5;
    this.image;
    this.timeout = 3000;
    this.err_timeout = 500;
    this.slides = new Array();
    this.current = 0;
    this.waitid = 0;
    this.timeoutid = 0;
    this.inner_width = 0;
    this.inner_height = 0;
    this.wait_width = 16;
    this.wait_height = 16;
    this.wait = new Image();
    this.wait.src = "/images/spinner.gif";
    this.wait.ldr = null;

    this.add = function(slide){
        var i = this.slides.length;
        if(this.prefetch == -1) slide.load();
        this.slides[i] = slide;
    }

    this.startwait = function(timeout){
        this.waited();
        this.waitid = setTimeout(this.name+".waitnow()", timeout);
    }

    this.play = function(timeout){
        this.pause();
        if(!timeout) timeout = this.timeout;
        this.timeoutid = setTimeout(this.name+".loop()", timeout);
    }

    this.autoplay = function(src){
        if(src.value == "Play"){
            src.value = "Stop";
            this.play();
        }else{
            src.value = "Play";
            this.pause();
        }
    }

    this.waited = function(){
        if(this.waitid){
            clearTimeout(this.waitid);
            this.waitid = 0;
        }
    }

    this.pause = function(){
        if(this.timeoutid){
            clearTimeout(this.timeoutid);
            this.timeoutid = 0;
        }
    }

    this.reset = function(){
        if(this.timeoutid) this.play();
    }

    this.update = function(){
        if(!this.image) return;
        if(typeof this.pre_update == 'function') this.pre_update();
        var slide = this.slides[this.current];
        slide.load();
        var dofilter = false;
        if(typeof this.image.filters != 'undefined' && typeof this.image.filters[0] != 'undefined'){
            dofilter = true;
            if(slide.filter && this.image.style && this.image.style.filter) this.image.style.filter = slide.filter;
            this.image.filters[0].Apply();
        }

        if(slide.image.loaded){
            if(this.wait.ldr) this.wait.ldr.style.display = "none";
            this.image.src = slide.image.src;
            this.image.wait = false;
            this.resize(1);
        }else{
            if(this.wait.ldr){
                this.wait.ldr.style.display = "";
            }else{
                this.image.width = 0;
                this.image.height = 0;
                this.image.src = this.wait.src;
                this.image.width = this.wait_width;
                this.image.height = this.wait_height;
            }
            this.image.wait = true;
            this.startwait(this.err_timeout);
        }
        if(dofilter) this.image.filters[0].Play();
        if(typeof this.post_update == 'function') this.post_update();
        if(this.prefetch > 0){
            var next, prev, count;
            next = this.current;
            prev = this.current;
            count = 0;
            do{
                if(++next >= this.slides.length) next = 0;
                if(--prev < 0) prev = this.slides.length-1;
                this.slides[next].load();
                this.slides[prev].load();
            }while(++count < this.prefetch);
        }
    }

    this.gotoslide = function(n){
        this.reset();
        if(n == -1) n = this.slides.length-1;
        if(n < this.slides.length && n >= 0) this.current = n;
        this.update();
    }

    this.next = function(){
        this.reset();
        if(this.current < this.slides.length-1) this.current++;
        else if(this.repeat) this.current = 0;
        this.update();
    }

    this.previous = function(){
        this.reset();
        if(this.current > 0) this.current--;
        else if(this.repeat) this.current = this.slides.length-1;
        this.update();
    }

    this.first = function(){
        this.reset();
        this.current = 0;
        this.update();
    }

    this.last = function(){
        this.reset();
        this.current = this.slides.length-1;
        this.update();
    }

    this.resize = function(force){
        if(!this.image || this.image.wait) return;
        var slide = this.slides[this.current];
        if(!slide.image.width || !slide.image.height) return;
        if(slide.image.width > this.inner_width || slide.image.height > this.inner_height){
            if(slide.image.width/slide.image.height < this.inner_width/this.inner_height){
                if(this.image.height == slide.image.height || force){
                    this.image.height = this.inner_height;
                    var p = (slide.image.height-this.inner_height)/slide.image.height;
                    this.image.width = slide.image.width-Math.round(slide.image.width*p);
                    return;
                }
            }else{
                if(this.image.width == slide.image.width || force){
                    this.image.width = this.inner_width;
                    var p = (slide.image.width-this.inner_width)/slide.image.width;
                    this.image.height = slide.image.height-Math.round(slide.image.height*p);
                    return;
                }
            }
        }
        this.image.width = slide.image.width;
        this.image.height = slide.image.height;
    }

    this.loop = function(){
        var next_slide = null;
        if(this.current < this.slides.length-1) next_slide = this.slides[this.current+1];
        else next_slide = this.slides[0];
    
        if(this.slides[this.current].image.loaded && next_slide.image.loaded){
            this.next();
            this.play();
        }else{
            next_slide.load();
            this.play(this.err_timeout);
        }
    }

    this.waitnow = function(){
        var slide = this.slides[this.current];
        if(slide.image.loaded){
            if(this.image.wait) this.update();
        }else this.startwait(this.err_timeout);
        this.reset();
    }
}
