var ExtendedGallery = new Class({
    Implements: [Options, Events],    
    
    options: {
        canvas: 'canvas',
        duration: 1000,
        delay: 5000,
        fps: 20,
        images: []
    },
    
    _item: [],
    _fade_out: [],
    _fade_in: [],
    _timer: '',
    _stopped: false,
    _index: 0,
    
    initialize: function(options) {
        this.setOptions(options);
        this.options.canvas = $(this.options.canvas);
        
        // Inject 2 img items into canvas
        var item = new Element('div', {
            styles: {
                display: 'block',
                position: 'absolute'
            }
        });
        var img = new Element('img');
        var descr = new Element('div', {
            'class': 'gallery-description'
        });
        var hl = new Element('div', {
            'class': 'gallery-headline'
        });
        var txt = new Element('div', {
            'class': 'gallery-text'
        });
        
        img.inject(item);
        descr.inject(item);
        hl.inject(descr);
        txt.inject(descr);
        
        this._item[0] = item;
        this._item[1] = item.clone();
        
        this._item.each(function(ele, index) { 
            if(index == 0) ele.set('rel', 'active');
            ele.inject(this.options.canvas);
            ele.getChildren('img').addEvent('click', function(e) {
                if ( this.hasClass('gallery-link') ) {
                    window.location.href = this.get('rel');
                }
            });
        }.bind(this));
        
        this.changeImage(0);
    },
    
    changeImage: function(index) {
        if (index >= this.options.images.length) index = 0;
        if (index < 0) index = this.options.images.length - 1;
        
        $clear(this._timer);
        
        var newEle = '';
        this._fade_out = new Array();
        this._fade_in = new Array();
        
        // Get current image in front
        this._item.each(function(ele, i) {
        
            var t = new Fx.Tween(ele, {
                duration: this.options.duration,
                fps: this.options.fps
            });
            
            if(ele.get('rel') == 'active') {
                this._fade_out[this._fade_out.length] = t;
            } else {
                this._fade_in[this._fade_in.length] = t;
                
                var img = ele.getChildren('img');
                
                img.removeEvents('load');
                img.addEvent('load', function() {
                    this._fade_out.each(function(fo) {
                        fo.start('opacity', 0);
                    });
                    
                    this._fade_in.each(function(fi) {
                        fi.start('opacity', 1);
                    });
                    
                    this.fireEvent('imageChange', index);
                    this._index = index;
                }.bind(this));
                
                newEle = ele;
            }
        }.bind(this));
        
        this._item.each(function(ele) { ele.set('rel', ''); }.bind(this));
        newEle.set('rel', 'active');
        
        // update properties of active element
        newEle.getChildren('img').set('src', this.options.images[index].href);
        newEle.getElements('.gallery-headline').set('text', this.options.images[index].title);
        if ( this.options.images[index]['link'] !== undefined ) {
            newEle.getChildren('img').addClass('gallery-link');
            newEle.getChildren('img').set('rel', this.options.images[index]['link']);
        } else {
            newEle.getChildren('img').removeClass('gallery-link');
            newEle.getChildren('img').set('rel', '');
        }
        
        var html = this.options.images[index].text;
        if ( this.options.images[index]['link'] !== undefined ) {
            html = ' <a href="' + this.options.images[index].link + '">' + html + '</a>';
        }
        newEle.getElements('.gallery-text').set('html', html);
        
        if ( !this._stopped ) {
            this._timer = (function() { 
                this.changeImage(index + 1); 
            }.bind(this)).delay(this.options.delay);
        }
    },
    
    stop: function() {
        this._stopped = true;
        window.clearTimeout(this._timer);
    },
    
    prev: function() {
        this.stop();
        this.changeImage(this._index - 1);
    },
    
    next: function() {
        this.stop();
        this.changeImage(this._index + 1);
    }
});

