/**************************************************************

	Script		: PanelSlider
	Version		: 1.0
	Authors		: Matt Robinson

**************************************************************/

var PanelSlider = new Class({
	
	Implements: [Events, Options],
	
	getOptions: function()
	{
		return {
			expandSize: 300,
			contractSize: 100,
			resetSize: 200,
			transitionSpeed: 1000,
			transitionType: 'sine:out',
			transitionProperty: 'width',
			contentOptions : 
			{
				contentElem: null,
				expandValue: 1,
				contractValue: 0,
				resetValue: 0,
				transitionProperty: 'opacity'
			}
		};
	},
	
	initialize: function(panelContainerId, panelClass, options)
	{
		this.setOptions(this.getOptions(), options);
		
		this.panelContainer = $(panelContainerId);
		
		if(this.panelContainer) this.panelElemArr = this.panelContainer.getElements('.' + panelClass);

		if (this.panelElemArr && this.panelElemArr.length > 1)
		{
			this.buildPanels();
			
			this.panelContainer.addEvent('mouseleave', this.resetPanels.bind(this));
		}
	},
	
	buildPanels: function()
	{
		this.panelArr = new Array();
		
		var panel;
		
		this.panelElemArr.each(function(el, i){
			panel = new Panel(el, i, this.options);
			panel.addEvent('hover', this.activatePanel.bind(this));
			this.panelArr.push(panel);
		}.bind(this));
	},
	
	activatePanel: function(target)
	{
		this.panelArr.each(function(panel, i)
		{
			if(panel != target)
			{
				panel.contract();	
			}
		});
	},
	
	resetPanels: function()
	{
		this.panelArr.each(function(panel, i)
		{
			panel.reset();
		}.bind(this));	
	}
});

/**************************************************************

	Script		: Panel
	Version		: 1.0
	Authors		: Matt Robinson

**************************************************************/

var Panel = new Class({
	
	Implements: [Events, Options],
	
	getOptions: function()
	{
		return {
			
		};
	},
	
	initialize: function(panelContainer, panelIndex, options)
	{
		this.setOptions(this.getOptions(), options);
		
		this.panelContainer = panelContainer;
		this.panelIndex = panelIndex;
		
		this.panelContainer.setStyles({
			'overflow' : 'hidden'
		});
		
		this.panelInner = new Element('div', 
		{
			'class' : 'panel-inner'
		});
		
		var panelChildren = this.panelContainer.getChildren();
		
		panelChildren.each(function(el, i)
		{
			this.panelInner.wraps(el);
		}.bind(this));
		
		this.panelTween = new Fx.Tween(this.panelContainer, {
			duration: this.options.transitionSpeed,
			transition: this.options.transitionType,
			link: 'cancel',
			property: this.options.transitionProperty
		});
		
		var contentElem = (this.options.contentOptions.contentElem) ? this.panelContainer.getElements(this.options.contentOptions.contentElem)[0] : null;
		
		if(contentElem)
		{
			this.elemTween = new Fx.Tween(contentElem, 
			{
				duration: this.options.transitionSpeed,
				transition: this.options.transitionType,
				link: 'cancel',
				property: this.options.contentOptions.transitionProperty
			});
		}
		
		this.addListeners();
		this.reset(true);
	},
	
	addListeners: function()
	{
		this.panelContainer.addEvents({
			mouseenter : function(evt)
			{
				this.expand();
			}.bind(this)
		});
	},
	
	expand: function()
	{
		this.fireEvent('hover', this);
		
		this.panelTween.start(this.options.expandSize);
		
		if(this.elemTween)
		{
			this.elemTween.start(this.options.contentOptions.expandValue);	
		}
	},
	
	contract: function()
	{
		this.panelTween.start(this.options.contractSize);
		
		if(this.elemTween)
		{
			this.elemTween.start(this.options.contentOptions.contractValue);	
		}
	},
	
	reset: function(set)
	{
		if(set)
		{
			this.panelTween.set(this.options.resetSize);
			
			if(this.elemTween)
			{
				this.elemTween.set(this.options.contentOptions.resetValue);	
			}
		}
		else
		{
			this.panelTween.start(this.options.resetSize);
			
			if(this.elemTween)
			{
				this.elemTween.start(this.options.contentOptions.resetValue);	
			}
		}
	}
});

/**************************************************************

Script		: HTMLSlider
Version		: 1.0
Authors		: Matt Robinson

**************************************************************/

var HTMLSlider = new Class({

    Implements: [Events, Options],

    getOptions: function () {
        return {
            captionClass: null,
            interval: 4000,
            autoSlideEnabled: true,
            randomStart: false,
            indicatorContainerId: null,
            paginationEnabled: true,
            paginationContainerId: null
        };
    },

    initialize: function (slideContainerId, slideClass, options) {
        this.setOptions(this.getOptions(), options);

        this.slideContainer = $(String(slideContainerId));
        this.slideElems = this.slideContainer.getChildren(String('.' + slideClass));
        this.activeSlide = null;
        this.prevSlide = null;
        this.slides = null;

        if (this.slideElems.length > 1) {
            this.createElements();
            this.createSlides();
            if (this.options.autoSlideEnabled) this.initAutoSlide();
        }
    },

    createElements: function () {
        this.slideContainer.setStyle('position', 'relative');

        if (this.options.indicatorContainerId) {
            if ($(String(this.options.indicatorContainerId))) {
                this.indicatorContainer = $(String(this.options.indicatorContainerId));
                this.indicatorContainer.set('html', '');
            }
            else {
                this.indicatorContainer = new Element('div',
				{
				    'class': 'indicator-container',
				    'styles':
					{
					    'position': 'absolute',
					    'z-index': this.slideContainer.getChildren().length
					}
				});

                this.indicatorContainer.inject(this.slideContainer);
            }
        }

        if (this.options.paginationEnabled) {
            this.paginatePrev = new Element('a',
			{
			    'class': 'paginate-prev',
			    'href': '#',
			    'html': 'Prev'
			});

            this.paginatePrev.addEvent('click', function (evt) {
                evt.stop();

                this.paginate(-1);
            } .bind(this));

            this.paginateNext = new Element('a',
			{
			    'class': 'paginate-next',
			    'href': '#',
			    'html': 'Next'
			});

            this.paginateNext.addEvent('click', function (evt) {
                evt.stop();

                this.paginate(1);
            } .bind(this));

            if ($(String(this.options.paginationContainerId))) {
                $(String(this.options.paginationContainerId)).set('html', '');
                $(String(this.options.paginationContainerId)).setStyles(
				{
				    'z-index': this.slideContainer.getChildren().length
				});

                this.paginatePrev.inject($(String(this.options.paginationContainerId)));
                this.paginateNext.inject($(String(this.options.paginationContainerId)));
            }
            else {
                this.paginatePrev.setStyles(
				{
				    'position': 'absolute',
				    'z-index': this.slideContainer.getChildren().length
				});

                this.paginateNext.setStyles(
				{
				    'position': 'absolute',
				    'z-index': this.slideContainer.getChildren().length
				});

                this.paginatePrev.inject(this.slideContainer);
                this.paginateNext.inject(this.slideContainer);
            }
        }
    },

    createSlides: function () {
        var slide;
        var zIndex;
        var indicator;

        this.slides = new Array();

        this.slideElems.each(function (el, i) {
            if (this.indicatorContainer) {
                indicator = new Element('a', {
                    'class': 'slider-indicator',
                    'href': '#',
                    'html': i + 1
                });

                indicator.addEvent('click', function (evt) {
                    evt.stop();

                    if (this.options.autoSlideEnabled) this.initAutoSlide();
                    this.changeSlide(i);
                } .bind(this));

                indicator.inject(this.indicatorContainer);
            }

            zIndex = this.slideElems.length - i - 1;

            slide = new HTMLSlide(el, i, zIndex, indicator, this.options);
            slide.addEvent('tweenComplete', this.deactivatePrevSlide.bind(this));

            this.slides.push(slide);

        } .bind(this));

        var startingSlideIndex = (this.options.randomStart) ? Math.round(Math.random() * ((this.slides.length - 1) - 0) + 0) : 0;
        
        this.activeSlide = this.slides[startingSlideIndex];
        this.activeSlide.show();
    },

    paginate: function (modifier) {
        var currentIndex = this.activeSlide.slideIndex;

        var modifiedIndex = this.validateSlide(currentIndex + modifier);

        if (this.options.autoSlideEnabled) this.initAutoSlide();
        this.changeSlide(modifiedIndex);
    },

    initAutoSlide: function () {
        if (this.timer) this.timer = clearInterval(this.timer);
        this.timer = setInterval(this.autoSlide.bind(this), this.options.interval);
    },

    autoSlide: function () {
        var currentIndex = this.activeSlide.slideIndex;

        var modifiedIndex = this.validateSlide(currentIndex + 1);

        this.changeSlide(modifiedIndex);
    },

    validateSlide: function (modifiedIndex) {
        if (modifiedIndex > (this.slides.length - 1)) {
            modifiedIndex = 0;
        }
        else if (modifiedIndex < 0) {
            modifiedIndex = this.slides.length - 1;
        }

        return modifiedIndex;
    },

    deactivatePrevSlide: function () {
        this.prevSlide.deactivate();
    },

    changeSlide: function (index) {
        var newSlide = this.slides[index];

        if (newSlide != this.activeSlide) {
            var newZIndex = this.activeSlide.zIndex;
            var oldZIndex = newSlide.zIndex;

            if (newZIndex > oldZIndex) {
                newSlide.setIndex(newZIndex);
                this.activeSlide.setIndex(oldZIndex);
            }

            this.prevSlide = this.activeSlide;
            this.activeSlide = newSlide;

            this.activeSlide.activate();
        }
    }
});

/**************************************************************

Script		: HTMLSlide
Version		: 1.0
Authors		: Matt Robinson

**************************************************************/

var HTMLSlide = new Class({

    Implements: [Events, Options],

    getOptions: function () {
        return {

    };
},

initialize: function (slideElem, slideIndex, zIndex, indicator, options) {
    this.setOptions(this.getOptions(), options);

    this.captionContainer = null;
    this.slideElem = slideElem;
    this.slideIndex = slideIndex;
    this.zIndex = zIndex;
    this.indicator = indicator;

    slideElem.setStyle('z-index', this.zIndex);

    this.slideTween = new Fx.Tween(this.slideElem,
		{
		    duration: 500,
		    transition: Fx.Transitions.Quad.easeIn,
		    link: 'cancel'/*,
		    onComplete: this.dispatchComplete.bind(this)*/
		});

    if (this.options.captionClass) {
        this.captionContainer = this.slideElem.getFirst(String('.' + this.options.captionClass));

        if (this.captionContainer) {
            this.captionTween = new Fx.Tween(this.captionContainer,
				{
				    duration: 'long',
				    transition: Fx.Transitions.Quad.easeInOut
				});
        }
    }

    this.slideTween.set('opacity', 0);
},

activate: function (zIndex) {
    this.slideElem.set('opacity', 0);
    this.slideTween.start('opacity', 1);

    if (this.captionTween) {
        this.captionContainer.setStyle('left', Number(0 - (this.captionContainer.getSize().x)));
        this.captionTween.start('left', 0)
    }

    this.dispatchComplete();

    if (this.indicator) this.indicator.addClass('active');
},

show: function () {
    this.slideElem.set('opacity', 1);

    if (this.indicator) this.indicator.addClass('active');
},

deactivate: function (zIndex) {
    this.slideTween.start('opacity', 0);

    if (this.indicator) this.indicator.removeClass('active');
},

dispatchComplete: function () {
    this.fireEvent('tweenComplete');
},

setIndex: function (zIndex) {
    this.slideElem.setStyle('display', 'block');
    this.zIndex = zIndex;
    this.slideElem.setStyle('z-index', this.zIndex);
}
});

/**************************************************************

Script		: Equalizer
Version		: 1.0
Authors		: Matt Robinson

**************************************************************/

var Equalizer = new Class({

    Implements: [Events, Options],

    getOptions: function () {
        return {
            equalizeWidth : false,
            equalizeHeight : true
    };
},

initialize: function (elemClass, options) {
    this.setOptions(this.getOptions(), options);

    this.elems = $$(String('.' + elemClass));

    var targetDimObj = { width: 0, height: 0}
    var currentDimObj = { width: 0, height: 0}

    this.elems.each(function(el, i)
    {
        currentDimObj.width = el.getSize().x - el.getStyle('padding-left').toInt() - el.getStyle('padding-right').toInt();
        currentDimObj.height = el.getSize().y - el.getStyle('padding-top').toInt() - el.getStyle('padding-bottom').toInt();
    
        if(currentDimObj.width > targetDimObj.width) targetDimObj.width = currentDimObj.width;
        if(currentDimObj.height > targetDimObj.height) targetDimObj.height = currentDimObj.height;
    });

    this.elems.each(function(el, i)
    {
        if(this.options.equalizeWidth) el.setStyle('width', String(targetDimObj.width + 'px'));
        if(this.options.equalizeHeight) el.setStyle('height', String(targetDimObj.height + 'px'));
    }.bind(this));
}
});
