var BackgroundChanger = new Class({
    Implements: [Options],
    
    options:{
        "delay":5000,   // delay between changing images
        "duration":2000, // fade duration
        "stateActive": "Playing (click to pause)",
        "stateInactive": "Paused (click to play)",
        "stateLoading": "Loading... (click to pause)",
        "textActive": "►",
        "textInactive": "■",
        "textLoading": "●",
        "stateElement": null,
        "debug": false
    },
    
    /**
     * initialize backgroundchanger
     * 
     * @param array  pics    array of image objects {src:X,url:Y,user:Z}
     * @param object options optional objects object
     */
    initialize: function(pics,options){
        this.setOptions(options);
        
        this.active = false;
        this.preloading = false;
        this.picNr = 0;                                                         // current pic-number
        this.globalCounter = 1;
        this.picsList = pics;
        this.timerNext = null;
        if(this.options.stateElement){
            this.options.stateElement = $(this.options.stateElement);
        }
        
        this.effectOptions = {
            property: "opacity",
            duration: this.options.duration, 
            link: "cancel",
            transition: Fx.Transitions.Quart.easeInOut
        };
        
        if(Browser.Engine.trident4){    // reset image onResize and onScroll for IE
            window.addEvent('resize',this.position.bindWithEvent(this));
            window.addEvent('scroll',this.position.bindWithEvent(this));
        }
        // do first resize on start
        this.position();
        
        // set button functions
//        $("btn_left").setStyle("cursor", "pointer").addEvent('click', function(event){
//            this.changeManually("left");
//            event.preventDefault();
//        }.bindWithEvent(this));
//        $("btn_right").setStyle("cursor", "pointer").addEvent('click', function(event){
//            this.changeManually("right");
//            event.preventDefault();
//        }.bindWithEvent(this));
        $("state").setStyle("cursor","pointer").addEvent("click",function(){
            this.toggle();
        }.bindWithEvent(this));
        
        if(Setting.get("backgroundchanger",true)){
            this.start();
        }else{
            if(this.options.stateElement) $("state").set("title",this.options.stateInactive).set("text",this.options.textInactive);
        }
    },
        
    /**
     * preloading function for next pic
     * 
     * @param int n image number
     * @return BackgroundChanger
     */
    preload: function(n){
        if(this.options.debug && window.console) console.debug("preloading",n,this.picsList[n].src);
        this.preloading = true;
        this.newPicture = new Asset.image(this.picsList[n].src,{onload: function(){
            if(this.options.debug && window.console) console.debug("preloading",n,"done");
            this.preloading = false;
            if(!this.timerNext){ // timer already expired, preloading took to long
                if(this.options.stateElement) $("state").set("title",this.active ? this.options.stateActive : this.options.stateInactive).set("text",this.active ? this.options.textActive : this.options.textInactive);
                this.show(n);
            }else{
                if(this.options.debug && window.console) console.debug("preloading",n,"finished in time, waiting for timer");
            }
        }.bindWithEvent(this)});
        return this;
    },
    
    /**
     * smooth change between pics
     * 
     * @param int n image number to show
     * @return BackgroundChanger
     */
    show: function(n){
        this.timerNext = null;
        if(this.preloading){    // still preloading, wait for preloading to finish
            if(this.options.stateElement) $("state").set("title",this.options.stateLoading).set("text",this.options.textLoading);
            if(this.options.debug && window.console) console.debug("show",n,"wait for preloading to finish");
            return this;
        }
        
        if(this.options.debug && window.console) console.debug("show",n,this.picsList[n].src);
        
        this.picNr = n;
        if(this.active){
            n = this.capNum(this.picNr+1);
            if(this.options.debug && window.console) console.debug("preparing",n);
            this.timerNext = this.preload(n).show.delay(this.options.delay,this,n); // start bg-changing
        }
        
        
        //change bg-image in the background
        $("bgImage"+(this.globalCounter % 2 + 1)).setStyle("background-image","url(" + this.picsList[this.picNr].src + ")");
        //display transparent background again
        $("bgImage"+(this.globalCounter % 2 + 1)).setStyle("opacity", "1");
        
        //change shown image-name
        $("pic_name").set("html",this.picsList[this.picNr].title);
        // change url of link
        $("pic_name").set("href",this.picsList[this.picNr].url);
        // change shown user-name
        $("user").set("html",this.picsList[this.picNr].user);
        // !TODO! change link to user-profile
        
        $("bgImage"+(this.globalCounter % 2 == 0 ? "2" : "1")).get("tween",this.effectOptions).start(0).chain(function(){                               // FADE OUT old background, so that new background moves to the front
            
            // Move one picture to the front the other in the background
            $("bgImage1").setStyle("z-index",(this.globalCounter % 2 == 0 ? "-20" : "-30"));
            $("bgImage2").setStyle("z-index",(this.globalCounter % 2 == 0 ? "-30" : "-20"));
            
            this.globalCounter++;
        }.bind(this));
        return this;
    },
    
    /**
     * position background image
     * 
     * @return BackgroundChanger
     */
    position: function(){
        if(Browser.Engine.trident4){
            var size   = $(window).getSize();
            var scroll = $(window).getScroll();
            $$("#bgImage1","#bgImage2").setStyles({
                "width":size.x,
                "height":size.y,
                "left":scroll.x,
                "top":scroll.y
            });
        }else{
            $$("#bgImage1","#bgImage2").setStyles({
                "position":"fixed",
                "width":"100%",
                "height":"100%"
            });
        }
        return this;
    },
    
    /**
     * cap image number
     * 
     * @param int n
     * @return n
     */
    capNum: function(n){
        if(n >= this.picsList.length){
            n = 0;
        }else if(n < 0){
            n = this.picsList.length - 1;
        }
        return n;
    },
    
    /**
     * start backgroundchanger
     * 
     * @return BackgroundChanger
     */
    start: function(){
        if(!this.active){
            Setting.set("backgroundchanger",true);
            if(this.options.debug && window.console) console.debug("start");
            this.active = true;
            
            var n = this.capNum(this.picNr + 1);
            this.timerNext = this.preload(n).show.delay(this.options.delay,this,n); // start bg-changing
            $("state").set("title",this.options.stateActive).set("text",this.options.textActive);
        }
        return this;
    },
    
    /**
     * stop backgroundchanger
     * 
     * @return BackgroundChanger
     */
    stop: function(dontsave){
        if(this.active){
            if(!dontsave) Setting.set("backgroundchanger",false);
            if(this.options.debug && window.console) console.debug("stop");
            this.active = false;
            
            $clear(this.timerNext);
            $("state").set("title",this.options.stateInactive).set("text",this.options.textInactive);
        }
        return this;
    },
    
    /**
     * toggle state (start/stop)
     * 
     * @return BackgroundChanger
     */
    toggle: function(){
        if(this.active){
            this.stop();
        }else{
            this.start();
        }
        return this;
    },
    
    /**
     * manually change image
     * 
     * @param string direction left/right
     * @return BackgroundChanger
     */
    changeManually: function(direction){
        this.stop(true);
        
        var n = this.picNr;
        if(direction == 'left'){
            n--;
        }else if(direction == 'right'){
            n++;
        }
        n = this.capNum(n);
        if(this.options.debug && window.console) console.debug("manual",n);
        return this.preload(n).show(n);
    }
});
