var ProductGallery = new Class({
	
	Implements: Options,
	
    options: {
        borderColors: ['#ccc', '#cc0009'],
        centerImages: true,
        classCurrentThumbnail: 'current',
        classLeftButton: 'product-gallery-slider-left',
        classRightButton: 'product-gallery-slider-right',
		enableMouseWheel: true,
        fadeOutDisabledButtons: false,
        slideFxDuration: 500,
        slideFxTransition: 'quad:out',
        slideOpacity: false,
        visibleImages: 5
    },
    
    initialize: function(galleryElement, options)
    {
        // extend default options
        this.setOptions(options);

        // Init vars
		this.busy = false;
        this.current = 0;
        this.galleryElement = $(galleryElement);
        this.imageContainer = this.galleryElement.getElement('.gallery-image-holder');
        this.images = $H({});
        this.imageTitle = this.galleryElement.getElement('strong');
        this.stack = [];
        this.thumbnailContainer = this.galleryElement.getElement('ul');
		this.thumbnailLinks = this.galleryElement.getElements('a');
        this.thumbnails = this.getThumbnails();

		if(!this.thumbnails.length > 0)
		{
			return;
		}

        // highlight first thumbnail
		this.setCurrentThumbnail();

        // init gallery
        //this.preLoadImages(0);
        this.wrap();
        this.attach();
    },
    
    /**
     * Getter Methods
     */

    getCurrentImage: function()
    {
        return this.imageContainer.getElement('img');
    },

    getImageLinks: function()
    {
        return this.thumbnailContainer.getElements('a');
    },

    getThumbnailPosition: function(img)
    {
        return img.getPosition(img.getParent('div'));
    },

    getThumbnails: function()
    {
        return this.thumbnailContainer.getElements('li');
    },
    
    getWidthForImageWrapper: function()
    {
        var w = 0;
        this.getImageLinks().each(function(a){
            w+= a.getWidth() + a.getStyle('margin-left').toInt() + a.getStyle('margin-right').toInt() + a.getStyle('padding-left').toInt() + a.getStyle('padding-right').toInt();
        });
        return w;
    },

    /**
     * Images Functions
     */
    
    preLoadImages: function(start)
    {
        var end = (start + this.options.visibleImages).limit(0, this.thumbnails.length);

        var images = [];
        var imageLinks = this.getImageLinks();

        var links = this.getImageLinks();
        for(var i = start; i < end; i++)
        {
            var a = links[i];
            images.push(a.href);
            this.addIndicator(a)            
        }
        
        // return if all images are loaded
        if(this.images.getLength() >= this.thumbnails.length)
        {
            return;
        }

        var assets = new Asset.images(images, {
            onProgress: function(counter, index) {
                var imgNo = start + index;
                this.thumbnails[imgNo].store('image', assets[index]);

				// center first Image                
                if(start == 0 && index == 1)
                {
                    this.center();
                }

                this.removeIndicator(imageLinks[imgNo]);
            }.bind(this)
        });
    },

    addIndicator: function(a)
    {
		if(a.getElement('img').retrieve('image'))
		{
			return;
		}
        var links = this.getImageLinks();
        var imgNo = links.indexOf(a);
        if(this.images.getLength() > imgNo)
        {
            return;
        }
        a.getElement('img').set('opacity', .5);
        var dim = a.getSize();
        new Element('span', {
            'class': 'loading',
            styles: {
                height: dim.x,
                width: dim.x
            }
        }).inject(a);
    },
    
    removeIndicator: function(a)
    {
		if(a.getElement('span'))
		{
			a.getElement('span').dispose();
		}
        a.getElement('img').setStyle('opacity', 1);
    },
    
    center: function(el)
    {
        var img = el.getElement('img');

        if(!this.options.centerImages || img.getStyle('padding-top').toInt() > 0)
        {
            return;
        }
        var paddingTop = ((el.getHeight() - img.getHeight() - img.getStyle('padding-top').toInt()) /2).round();

        img.setStyle('padding-top', paddingTop.limit(0, this.imageContainer.getHeight()));

    },
	
	setCurrentThumbnail: function()
	{
		var c = this.galleryElement.getElement('.'+this.options.classCurrentThumbnail);
		if(c)
		{
			c.removeClass(this.options.classCurrentThumbnail);
		}
    
		this.thumbnailLinks[this.current].addClass(this.options.classCurrentThumbnail);
	},

    /**
     * Events
     */
    
    attach: function()
    {
        this.thumbnailLinks.each(function(el, i){

            var img = el.getElement('img');

            img.store('fxInstance', new Fx.Tween(img, {
                duration: 250
            }));

            el.addEvents({
                'click': function(e){
                    e.stop();
                    this.show(el, i);
                }.bind(this),
                'mouseover': function(){
                    this.toggleBackgroundColor(el, 1);
                }.bind(this),
                'mouseout': function(){
                    this.toggleBackgroundColor(el, 0);
                }.bind(this)
            })
        }, this);

		if(!this.options.enableMouseWheel || this.thumbnails.length <= this.options.visibleImages)
		{
			return;
		}
return;
        this.wrapper.addEvent('mousewheel', function(e) {
            e.stop();
            /* Mousewheel UP */
            if(e.wheel > 0) {
                this.prev();
            } 
            /* Mousewheel DOWN*/
            else if (e.wheel < 0) {
                this.next();
            }
        }.bind(this));
    },

    show: function(el, i)
    {
        if(el.hasClass('current') || this.busy)
        {
            return false;
        }

		this.busy = true;

        var current = this.galleryElement.getElement('.'+this.options.classCurrentThumbnail);        

        // Toggle Image
		this.toggleImage(el);

		this.current = i;

		this.setCurrentThumbnail();

        this.setTitle(this.thumbnails[i]);
    },
    
    setTitle: function(thumb)
    {
        this.imageTitle.set('html', thumb.getParent().get('title'));
    },
	
	toggleImage: function(el)
	{
		var containerWidth = this.imageContainer.getWidth();
		var current = this.imageContainer.getElement('div');
		
		var imageholder = new Element('div', {
			styles: {
				left: containerWidth
			}
		}).inject(this.imageContainer);
		
		var image = new Asset.image(el.get('href'), {
			onLoad: function(){
				
				this.center(imageholder);
				
				new Fx.Elements($$(current, imageholder), {
					onComplete: function(){
						current.dispose();
						this.busy = false;
					}.bind(this)
				}).start({
					'0': {
						left: containerWidth*-1
					},
					'1': {
						left: 0
					}
				});	
			}.bind(this)
		}).inject(imageholder);

	},
    
    /**
     * Slider / Pagination
     */
    
    wrap: function()
    {
		new Element('div').wraps(this.imageContainer.getElement('img'));
		
		new Element('div', {
			'class': 'gallery-thumbnails'	
		}).wraps(this.thumbnailContainer);
		
		return;
        var width = this.getWidthForImageWrapper();

        this.wrapper = new Element('div', {
            'class': 'product-gallery-wrapper'
        }).adopt(
            new Element('div', {
                'class': 'product-gallery-slide'
            }).adopt(
                new Element('div', {
                    'styles': {
                        width: width
                    }
                }).adopt(
                    this.getImageLinks()   
                )
            )
        ).inject(
            this.thumbnailContainer
        );

        // define global fx for the slider
        this.slideFx = new Fx.Morph(this.wrapper.getElement('div div'), {
            duration: this.options.slideFxDuration,
            transition: this.options.slideFxTransition
        });

        this.createButtons();
    },
    
    centerWrapper: function()
    {
        var width = this.getWidthForImageWrapper();
        this.wrapper.setStyle('width', width);
        this.wrapper.getElement('div').setStyle('margin', 0);
    },
    
    createButtons: function()
    {
        // return if buttons are not necessary
        if(this.thumbnails.length <= this.options.visibleImages)
        {
            return this.centerWrapper();
        }
        this.leftButton = new Element('span', {
            'class': this.options.classLeftButton,
            events: {
                'click': function()
                {
                    this.prev();
                }.bind(this)
            }
        }).inject(this.wrapper);

        this.rightButton = new Element('span', {
            'class': this.options.classRightButton,
            events: {
                'click': function()
                {
                    this.next();
                }.bind(this)
            }
        }).inject(this.wrapper);
        this.toggleButtons();
    },
    
    next: function()
    {
        // images left after slide
        var va = this.thumbnails.length - ( this.current + this.options.visibleImages );

        this.current = va >= this.options.visibleImages ? this.current + this.options.visibleImages : this.thumbnails.length - this.options.visibleImages;
        this.slide();
        this.preLoadImages(this.current);
    },
    
    prev: function()
    {
        this.current = (this.current- this.options.visibleImages).limit(0, this.thumbnails.length);
        this.slide();
    },    
    
    toggleButtons: function()
    {
        if(!this.options.fadeOutDisabledButtons)
        {
            return;
        }

        // first thumb is visible
        var isFirst = this.current == 0;
        var opaqueLeft =  isFirst ? .5 : 1;
        this.leftButton.fade(opaqueLeft);
        var cursorLeft = isFirst ? 'default' : 'pointer';
        this.leftButton.setStyle('cursor', cursorLeft);

        // last thumb is visible
        var isLast = ( this.current + this.options.visibleImages ) == this.thumbnails.length;
        var opaqueRight = isLast ? .5 : 1;
        this.rightButton.fade(opaqueRight);
        var cursorRight = isLast ? 'default' : 'pointer';
        this.rightButton.setStyle('cursor', cursorRight);

    },
    
    toggleBackgroundColor: function(el, i)
    {
		if(el.hasClass(this.options.classCurrentThumbnail))
        {
            return;
        }
        var fxInstance = el.retrieve('fxInstance');
		if(fxInstance)
		{
			fxInstance.cancel().start('backgroundColor', this.options.borderColors[i]);
		}
    },
    
    slide: function()
    {
        // image to scroll to
        var img = this.thumbnails[this.current];
        var imgPos = this.getThumbnailPosition(img);

        var newPos = imgPos.x * -1;

        this.slideFx.start({
            left: newPos    
        });

        this.toggleButtons();
    }    

});