/***************************************************************/
/* MZ Gallery (ver 2.0)                       			       */
/* Multifunctional Image Gallery.                              */
/*                                                             */
/* Mootools 1.2.1 Required (Core, Fx.Scroll, Scroller,         */
/* Fx.Elements)                                                */
/* Mootools 1.2.1 Patch Required                               */
/*                                                             */
/* Copyright Maurizio Ziraldo 2009                             */
/***************************************************************/

/*
    mzGallery
    Main object: create the gallery.
*/
var mzGallery = new Class({

    Implements: [Events, Options],

    options: {
        usethumbGallery: true,
        usetxtGallery: true,
        usecmdGallery: true,
        imageidPrefix: "IM_",
        imagecontainerClass: "imageContainer",
        imagewrapperClass: "imageWrapper",
        imageClass: "imageElement",
        imageTransition: Fx.Transitions.Quad.easeOut,
        imageSpeed: 500,
        imageAnimation: "scrolling",
        imageStart: null,
        automatic: false,
        cycling: false,
        timeout: 3000,
        /*onStartShow: Class.empty,
        onStopShow: Class.empty,*/
        eStart: Class.empty,
        eComplete: Class.empty
    },

    initialize: function(element, options) {

        this.setOptions(options);

        this.element = element;
        this.container = this.element.getElement("div[class=" + this.options.imagecontainerClass + "]");
        this.wrapper = this.container.getElement("div[class=" + this.options.imagewrapperClass + "]");
        this.images = this.wrapper.getElements("div[class=" + this.options.imageClass + "]");
        if (this.images[0] && this.options.imageAnimation == 'scrolling') this.wrapper.setStyle('width', (this.images[0].getSize().x * this.images.length) + 'px')
        this.imagenumber = this.images.map(function(item, index) { return item.id });
        this.imagenumber = this.imagenumber.map(function(item, index) { return index + 1 }).associate(this.imagenumber);
        this.selected = null;

        switch (this.options.imageAnimation) {
            case "news":
                this.imagesfxopen = this.images.map(function(item, index) { return new Fx.Tween($(item.id), { property: 'opacity', duration: this.options.imageSpeed, transition: this.options.imageTransition, onStart: this.options.eStart }) } .bind(this)).associate(this.images.map(function(item, index) { return item.id }));
                this.imagesfxclose = this.images.map(function(item, index) { return new Fx.Tween($(item.id), { property: 'opacity', duration: this.options.imageSpeed, transition: this.options.imageTransition, onComplete: this.options.eComplete }) } .bind(this)).associate(this.images.map(function(item, index) { return item.id }));
                break;
            case "fading":
                this.imagesfxopen = this.images.map(function(item, index) { return new Fx.Tween($(item.id).getElement('img'), { property: 'opacity', duration: this.options.imageSpeed, transition: this.options.imageTransition, onStart: this.options.eStart }) } .bind(this)).associate(this.images.map(function(item, index) { return item.id }));
                this.imagesfxclose = this.images.map(function(item, index) { return new Fx.Tween($(item.id).getElement('img'), { property: 'opacity', duration: this.options.imageSpeed, transition: this.options.imageTransition, onComplete: this.options.eComplete }) } .bind(this)).associate(this.images.map(function(item, index) { return item.id }));
                break;
            case "scrolling":
                this.scroller = new Fx.Scroll(this.container, {
                    duration: this.options.imageSpeed,
                    transition: this.options.imageTransition,
                    onStart: this.options.onStart,
                    onComplete: this.options.onComplete
                });
                break;
        }

        if (this.options.usethumbGallery) this.thumbGallery = new mzThumbGallery(this, this.options);
        if (this.options.usetxtGallery) this.txtGallery = new mzTxtGallery(this, this.options);
        if (this.options.usecmdGallery) this.cmdGallery = new mzCmdGallery(this, this.options);

        var imageStart = (this.options.imageStart) ? ((this.options.imageStart == 'nothing') ? null : this.options.imageStart) : ((this.images[0]) ? this.images[0].id.substr(this.options.imageidPrefix.length) : null)
        if (imageStart) this.goto(imageStart);
        if (imageStart && this.options.usethumbGallery) this.thumbGallery.scrollto.delay(500, this.thumbGallery, imageStart);
        if (this.options.automatic) this.start();

    },

    goto: function(id) {

        switch (this.options.imageAnimation) {
            case "fading":
            case "news":
                if (this.selected) this.imagesfxclose[this.options.imageidPrefix + this.selected].start(1, 0);
                this.selected = id;
                this.imagesfxopen[this.options.imageidPrefix + this.selected].start(0, 1);
                break;
            case "scrolling":
                this.selected = id;
                this.scroller.toElement($(this.options.imageidPrefix + this.selected));
                break;
        }
        if (this.options.usetxtGallery) this.txtGallery.select(id);
        if (this.options.usethumbGallery) this.thumbGallery.select(id);
        if (this.options.usecmdGallery) this.cmdGallery.select(id);

    },

    back: function() {

        if ($(this.options.imageidPrefix + this.selected).getPrevious()) {
            this.goto($(this.options.imageidPrefix + this.selected).getPrevious().id.substr(this.options.imageidPrefix.length));
            if (this.options.usethumbGallery) this.thumbGallery.scrollto.delay(500, this.thumbGallery, this.selected);
        }

    },

    next: function() {

        if ($(this.options.imageidPrefix + this.selected).getNext()) {
            this.goto($(this.options.imageidPrefix + this.selected).getNext().id.substr(this.options.imageidPrefix.length));
            if (this.options.usethumbGallery) this.thumbGallery.scrollto.delay(500, this.thumbGallery, this.selected);
        }

    },

    first: function() {

        if (this.wrapper) {
            this.goto(this.wrapper.getFirst().id.substr(this.options.imageidPrefix.length));
            if (this.options.usethumbGallery) this.thumbGallery.scrollto.delay(500, this.thumbGallery, this.selected);
        }

    },

    start: function() {

        this.fireEvent('startShow', this);

        if (!this.selected) this.first();
        this.automatic = this.timerhit.periodical(this.options.timeout, this);

    },

    stop: function() {

        $clear(this.automatic);

        this.fireEvent('stopShow', this);

    },

    timerhit: function() {

        if ($(this.options.imageidPrefix + this.selected)) {
            if ($(this.options.imageidPrefix + this.selected).getNext()) {
                this.next();
            } else if (this.options.cycling && this.element) {
                this.first();
            }
        } else {
            this.stop();
        }
    }

});

/*
mzThumbGallery
Optional object: create the gallery thumbs.
*/
var mzThumbGallery = new Class({

    Implements: [Options],

    options: {
        externalthumbGallery: false,
        thumbidPrefix: "TD_",
        thumbwrapperClass: "thumbWrapper",
        thumbcontainerClass: "thumbContainer",
        thumbgalleryClass: "thumbGallery",
        thumbonClass: { '0': { 'opacity': [0.4, 1] }, '1': {} },
        thumboffClass: { '0': { 'opacity': [1, 0.4] }, '1': {} },
        thumbgalleryMaxH: 170,
        thumbgalleryMinH: 15,
        thumbgalleryDim: "height",
        thumbgalleryObj: "thumbgallery",
        thumbTransition: Fx.Transitions.linear,
        thumbSpeed: 500,
        thumbWidth: 100,
        thumbSpacing: 15,
        thumbOverflow: 0,
        thumbstartOpened: false,
        thumbsautoscroll: true,
        thumbscrollarea: 100,
        thumbscrollvelocity: 0.2
    },

    initialize: function(element, options) {

        this.setOptions(options);

        this.gallery = element;
        this.thumbgallery = (this.options.externalthumbGallery) ? this.options.externalthumbGallery : this.gallery.element.getElement("div[class=" + this.options.thumbgalleryClass + "]");
        this.container = this.thumbgallery.getElement("div[class=" + this.options.thumbcontainerClass + "]");
        this.wrapper = this.container.getElement("div[class=" + this.options.thumbwrapperClass + "]");
        this.layermenu = (this[this.options.thumbgalleryObj]) ? this[this.options.thumbgalleryObj] : this.gallery.element.getElement("div[class=" + this.options.thumbgalleryObj + "]");
        this.thumbs = this.container.getElements("div[id^=" + this.options.thumbidPrefix + "]")
        this.thumb_fx = {};
        this.selected = null;

        this.wrapper.style.width = ((this.thumbs.length * (this.options.thumbWidth + this.options.thumbSpacing)) + this.options.thumbSpacing + this.options.thumbOverflow  + 100) + "px";
        this.navscroller = new Fx.Scroll(this.container, { duration: 500 });
        this.slider = new Fx.Tween(this.layermenu, { property: this.options.thumbgalleryDim, duration: 500 });

        if (this.options.thumbsautoscroll) {

            this.scroller = new Scroller(this.container, { area: this.options.thumbscrollarea, velocity: this.options.thumbscrollvelocity });

            this.container.addEvent('mouseenter', function(e) {
                this.scroller.start();
            } .bind(this));

            this.container.addEvent('mouseleave', function(e) {
                this.scroller.stop();
            } .bind(this));
        }

        this.thumbs.each(function(el) {

            this.thumb_fx[el.id] = new Fx.Elements([el, el.getElement('img')], { duration: this.options.thumbSpeed, transition: this.options.thumbTransition });

            el.addEvent('mouseenter', function(e) {
                this.thumb_fx[this.options.thumbidPrefix + e.target.id.substr(this.options.thumbidPrefix.length)].cancel();
                this.thumb_fx[this.options.thumbidPrefix + e.target.id.substr(this.options.thumbidPrefix.length)].start(this.options.thumbonClass);
            } .bind(this));

            el.addEvent('mouseleave', function(e) {
                if (e.target.id.substr(this.options.thumbidPrefix.length) != this.selected) {
                    this.thumb_fx[this.options.thumbidPrefix + e.target.id.substr(this.options.thumbidPrefix.length)].cancel();
                    this.thumb_fx[this.options.thumbidPrefix + e.target.id.substr(this.options.thumbidPrefix.length)].start(this.options.thumboffClass);
                }
            } .bind(this));

            el.addEvent('click', function(e) {
                e = new Event(e).stop();
                if (e.target.id.substr(this.options.thumbidPrefix.length) != this.selected) {
                    if (this.gallery) this.gallery.goto(e.target.id.substr(this.options.thumbidPrefix.length));
                }
            } .bind(this));

        } .bind(this))

        if (this.options.thumbstartOpened) this.slider.start(this.options.thumbgalleryMaxH);

    },

    toggle: function() {

        (this.layermenu.getStyle(this.options.thumbgalleryDim).toInt() == this.options.thumbgalleryMinH) ? this.slider.start(this.options.thumbgalleryMaxH) : this.slider.start(this.options.thumbgalleryMinH)

    },

    select: function(id) {
        if (this.selected) this.thumb_fx[this.options.thumbidPrefix + this.selected].start(this.options.thumboffClass);
        this.selected = id;
        this.thumb_fx[this.options.thumbidPrefix + this.selected].start(this.options.thumbonClass);
    },

    scrollto: function(id) {
        this.navscroller.start(this.wrapper.getElement("div[id=" + this.options.thumbidPrefix + id + "]").getLeft() - this.container.getLeft() - this.options.thumbSpacing, 0);
    }

});

/*
mzTxtGallery
Optional object: create the gallery descriptions.
*/
var mzTxtGallery = new Class({

    Implements: [Options],

	options: {
		txtidPrefix:"DE_",
		externaltxtGallery:false,
		txtcontainerClass:"txtGallery"
	}, 

	initialize: function(element, options) {

		this.setOptions(options);

		this.gallery = element;
		this.container = (this.options.externaltxtGallery) ? this.options.externaltxtGallery : this.gallery.element.getElement("div[class="+this.options.txtcontainerClass+"]");
		this.selected = null;

	},

	over: function(id) {

		if(this.selected) this.container.getElement("div[id="+this.options.txtidPrefix+this.selected+"]").setStyle("visibility","hidden");
		this.container.getElement("div[id="+this.options.txtidPrefix+id+"]").setStyle("visibility","visible");

	},

	out: function(id) {

		this.container.getElement("div[id="+this.options.txtidPrefix+id+"]").setStyle("visibility","hidden");	
		if(this.selected) this.container.getElement("div[id="+this.options.txtidPrefix+this.selected+"]").setStyle("visibility","visible");

	},

	select: function(id) {

		if(this.selected) this.container.getElement("div[id="+this.options.txtidPrefix+this.selected+"]").setStyle("visibility","hidden");
		this.container.getElement("div[id="+this.options.txtidPrefix+id+"]").setStyle("visibility","visible");
		this.selected=id;		

	}

});

/*
mzCmdGallery
Optional object: create the gallery command panels and buttons.
*/
var mzCmdGallery = new Class({

    Implements: [Options],

	options: {
		externalcmdLeft:false,
		externalcmdRight:false,
		externalcmdThumb:false,
		externalcmdNumber:false,
		cmdidLeft:"thumbLeft",
		cmdidRight:"thumbRight",
		cmdidThumb:"thumbButton",
		cmdidNumber:"thumbNumber",
		cmdhtmlThumbOn:"[ x ]",
		cmdhtmlThumbOff:"Open"
	}, 

	initialize: function(element, options) {

		this.setOptions(options);

		this.gallery = element;
		this.left = (this.options.externalcmdLeft) ? this.options.externalcmdLeft : this.gallery.element.getElement("div[class="+this.options.cmdidLeft+"]");
		this.right = (this.options.externalcmdRight) ? this.options.externalcmdRight : this.gallery.element.getElement("div[class="+this.options.cmdidRight+"]");
		this.thumb = (this.options.externalcmdThumb) ? this.options.externalcmdThumb : this.gallery.element.getElement("div[class="+this.options.cmdidThumb+"]");
		this.thumbopened = this.gallery.options.thumbstartOpened;
		this.numb = (this.options.externalcmdNumber) ? this.options.externalcmdNumber : this.gallery.element.getElement("div[class=" + this.options.cmdidNumber + "]");

		if(this.options.cmdidLeft) this.left.addEvent('click', function(e){
				e = new Event(e).stop();
				this.gallery.back();
		}.bind(this));
		
		if(this.options.cmdidRight) this.right.addEvent('click', function(e){
				e = new Event(e).stop();
				this.gallery.next();
		}.bind(this));

		if(this.options.cmdidThumb) this.thumb.addEvent('click', function(e){
				e = new Event(e).stop();
				if(this.options.usethumbGallery) this.gallery.thumbGallery.toggle();
				this.thumbbuttonToggle();
		}.bind(this));

	},
	
	thumbbuttonToggle: function() {

    	(this.thumbopened) ? this.thumb.getElement("a").set('html',this.options.cmdhtmlThumbOff) : this.thumb.getElement("a").set('html',this.options.cmdhtmlThumbOn);
	    this.thumbopened = !this.thumbopened;
		
	},

	select: function(id) {

		if(this.numb) this.numb.set('html',this.gallery.imagenumber[this.options.imageidPrefix+id]+"/"+this.gallery.images.length)
		
	}
	

});


