// -----------------------------------------------------------------------------------
//
//	Gallery v0.1
// -----------------------------------------------------------------------------------
/*

    Table of Contents
    -----------------
    Configuration

    Lightbox Class Declaration
    - initialize()
    - updateImageList()
    - start()
    - changeImage()
    - resizeImageContainer()
    - showImage()
    - updateDetails()
    - updateNav()
    - enableKeyboardNav()
    - disableKeyboardNav()
    - keyboardAction()
    - preloadNeighborImages()
    - end()
    
    Function Calls
    - document.observe()
   
*/
// -----------------------------------------------------------------------------------

//
//  Configurationl
//
GalleryOptions = Object.extend({
	
    fileLoadingImage:        'images/loading.gif',     
    fileBottomNavCloseImage: 'images/closelabel.gif',

    overlayOpacity: 0.8,   // controls transparency of shadow overlay

    animate: false,         // toggles resizing animations
    resizeSpeed: 7,        // controls the speed of the image resizing animations (1=slowest and 10=fastest)

    borderSize: 10,         //if you adjust the padding in the CSS, you will need to update this variable

	// When grouping images this is used to write: Image # of #.
	// Change it for non-english localization
	labelImage: "Image",
	labelOf: "of",
	data : {}
}, window.GalleryOptions || {});

// -----------------------------------------------------------------------------------

var Galleria = Class.create();

Galleria.prototype = {
    imageArray: [],
    activeImage: undefined,
    data : {},
    id : '',
    // initialize()
    // Constructor runs on completion of the DOM loading. Calls updateImageList and then
    // the function inserts html at the bottom of the page which is used to display the shadow 
    // overlay and the image container.
    //
    // holder for init state
	inited : 0,
	rowColors : [],
	tables : [],
	rowHighlightColor : "#FFFFAA",
	columnHighlightColor : "#EFEAE7",
	cellHighlightColor : "#EAEA9C",
	rowSelectedColor : "#FFFF66",
	columnSelectedColor : "#EDE0C2",
    options : {
            preload: 2,
            image_crop: true,
            thumb_crop: true,
            thumb_quality: 'auto',
            image_margin: 0,
            thumb_margin: 0,
            infoWidth: '',
            image_border: false,
            thumb_margin_adjustment: 0,
            transition: 'fade',
            transition_speed: 400,
            carousel: true,
            carousel_speed: 200,
            carousel_steps: 'auto',
            carousel_follow: true,
            popup_links: false,
            max_scale_ratio: undefined,
            thumbnails: true,
            width: '',
            height:'',
            data_type: 'auto',
            data_image_selector: 'img',
            data_source: 'gallery',
            data_config : function( elem ) { return {}; },
            queue: true,
            remove_original: true
        },
    initialize: function(id, data) {    
        this.data = data;
        this.options.data_source = this.options.target = id;
        if(this.options.width==''){
        	if($(id).getWidth()>700){
        		this.options.width = 700;
        	}else{
        		this.options.width = $(id).getWidth();
        	}
        }
        if(this.options.height==''){
        	this.options.height = Math.round(this.options.width*14/16);
        }
        //this.updateImageList(data);
        
        if (GalleryOptions.resizeSpeed > 10) GalleryOptions.resizeSpeed = 10;
        if (GalleryOptions.resizeSpeed < 1)  GalleryOptions.resizeSpeed = 1;

	    this.resizeDuration = GalleryOptions.animate ? ((11 - GalleryOptions.resizeSpeed) * 0.15) : 0;
	    this.overlayDuration = GalleryOptions.animate ? 0.2 : 0;  // shadow fade in/out duration

        // When Lightbox starts it will resize itself from 250 by 250 to the current image dimension.
        // If animations are turned off, it will be hidden as to prevent a flicker of a
        // white 250 by 250 box.
        var size = (GalleryOptions.animate ? 250 : 250) + 'px';
        

        var objBody = $(id);

		this.id = id;
        objBody.appendChild(Builder.node('div',{id:id+'galleriaContainer', className:'galleriaContainer'}, [
            Builder.node('div',{id:id+'galleriaStage', className:'galleriaStage'}, 
                Builder.node('div',{id:id+'galleriaImages', className:'galleriaImages'}, [
                    Builder.node('img',{id:id+'galleriaImage', className:'galleriaImage'}),
                    Builder.node('div',{id:id+'galleriaInfo', className:'galleriaInfo'}),
                    Builder.node('div',{id:id+'galleriaBorder', className:'galleriaBorder'})
                ]),
                Builder.node('div',{id:id+'galleriaCaption', className:'galleriaCaption'})
                ),
            Builder.node('div', {id:id+'galleriaThumbnailsContainer', className:'galleriaThumbnailsContainer'}),
            Builder.node('div',{id:id+'imageIndicator', className:'imageIndicator'})
        ]));
		sizeWidth = $(id).up().getWidth();
		sizeheight = $(id).up().getHeight();
		$(this.id+'galleriaImages').hide();//.observe('click', (function(event) { if (event.element().id == 'lightbox') this.end(); }).bind(this));
		$(this.id+'galleriaContainer').setStyle({ width: sizeWidth, height: sizeheight });
		$(this.id+'galleriaThumbnailsContainer').hide();
		$(this.id+'imageIndicator').hide();
		$(this.id+'galleriaBorder').hide();
		$(this.id+'galleriaInfo').hide();
        var th = this;
        (function(){
            var ids = 
                this.id+'galleriaContainer '+this.id+'galleriaStage '+this.id+'galleriaImages '+this.id+'galleriaImage '+this.id+'galleriaThumbnailsContainer';
            $w(ids).each(function(id){ th[id] = $(id);});
        }).defer(); 
       // this.start();
    },    
	 //
    // updateImageList()
    // Loops through anchor tags looking for 'lightbox' references and applies onclick
    // events to appropriate links. You can rerun after dynamically adding images w/ajax.
    //			   
    updateImageList: function(images) {   
        var loaded = 0;
        var o = this.options;
        if (
            (o.data_type == 'auto' && 
                typeof o.data_source == 'object' && 
                !o.data_source.tagName
            ) || o.data_type == 'json' || o.data_source.constructor == 'Array' ) {
            this.data = o.data_source;
            this.trigger( G.DATA );
            
        } else { // assume selector 
            var images = $(o.data_source).getElementsBySelector(o.data_image_selector);
            var getData = function( elem ) {
                var i,j,anchor = elem.parentNode;
                if (anchor && anchor.nodeName == 'A') {
                    if (anchor.href.match(/\.(png|gif|jpg)/)) {
                        i = anchor.href;
                    } else {
                        j = anchor.href;
                    }
                }
                var obj = new Object({
                    title: elem.title,
                    thumb: elem.src,
                    image: i || elem.src,
                    description: elem.alt,
                    link: j || elem.longdesc
                }); 
                return obj;
            };

            var data = [];
            images.each(function( elem ) {
                loaded++; 
                data.push( elem );
                if (o.remove_original) {
                    elem.parentNode.removeChild(elem);
                }
                if ( loaded == images.length ) {
                    //this.trigger( G.DATA );
                } 
            }); 
            this.data = data;
        }
    },
    
    //
    //  start()
    //  Display overlay and lightbox. If image is part of a set, add siblings to imageArray.
    //
    start: function(imageLink) {
    	this.imageArray = this.data;
        var imageNum = 0;
        this.createNav();        
        this.init_table($(this.id+'galleriaTable'));
        this.changeImage(imageNum);
    },

    //
    //  changeImage()
    //  Hide most elements and preload image in preparation for resizing image container.
    //
    changeImage: function(imageNum) {   
        this.activeImage = imageNum; // update global var		 
	
        var imgPreloader = new Image();
        
        // once image is preloaded, resize image container

        imgPreloader.onload = (function(){
            $(this.id+'galleriaImage').src = this.imageArray[this.activeImage].fileName;
            this.scale(imgPreloader, this.options.width, this.options.height, this.options.image_crop, this.options.max_scale_ratio);
            height = this.options.height;
            width = this.options.width;
            $(this.id+'galleriaImage').setStyle({
            position : 'relative',
            top :  Math.round(imgPreloader.height * -1 / 2 + (height / 2)),
            left : Math.round(imgPreloader.width * -1 / 2 + (width / 2)),
            width:imgPreloader.width, 
            height:imgPreloader.height
            });
            $(this.id+'galleriaThumbnailsContainer').setStyle({
            position : 'relative',
            top :  imgPreloader.height,
            left : 0,
            width : imgPreloader.width
            });
            if(this.options.infoWidth != ''){
            	infoWidth = this.options.infoWidth;
            }else{
            	infoWidth = imgPreloader.width-65;
            }
            $(this.id+'galleriaInfo').setStyle({
            	position : 'absolute',
            	top :  imgPreloader.height-65,
            	left : 10,
	            width:infoWidth
            });
            $(this.id+'galleriaBorder').setStyle({
            	top :  0,
            	left : 0,
	            width:imgPreloader.width+Math.round(imgPreloader.width * -1 / 2 + (width / 2)), 
            	height:imgPreloader.height+Math.round(imgPreloader.height * -1 / 2 + (height / 2))
            });
            this.resizeImageContainer(imgPreloader.width, imgPreloader.height);
        }).bind(this);
        imgPreloader.src = this.imageArray[this.activeImage].fileName;    
        this.preloadNeighborImages();    
    },

    //
    //  resizeImageContainer()
    //
    resizeImageContainer: function(imgWidth, imgHeight) {
        //$('imageIndicator').show();
        // get current width and height
        var widthCurrent  = $(this.id+'galleriaStage').getWidth();
        var heightCurrent = $(this.id+'galleriaStage').getHeight();
        // get new width and height
        var widthNew  = (imgWidth  + GalleryOptions.borderSize*2)+1;
        var heightNew = (imgHeight + GalleryOptions.borderSize);

        // scalars based on change from old to new
        var xScale = (widthNew  / widthCurrent)  * 100;
        var yScale = (heightNew / heightCurrent) * 100;

        // calculate size difference between new and old image, and resize if necessary
        var wDiff = widthCurrent - widthNew;
        var hDiff = heightCurrent - heightNew;

        if(navigator.appName != 'Microsoft Internet Explorer'){
        	if (hDiff != 0) new Effect.Scale($(this.id+'galleriaContainer'), yScale, {scaleX: false, duration: this.resizeDuration, queue: 'front'});
        } 
        if (wDiff != 0) new Effect.Scale($(this.id+'galleriaContainer'), xScale, {scaleY: false, duration: this.resizeDuration, delay: this.resizeDuration}); 
		
        // if new and old image are same size and no scaling transition is necessary, 
        // do a quick pause to prevent image flicker.
        var timeout = 0;
        if ((hDiff == 0) && (wDiff == 0)){
            timeout = 100;
            if (Prototype.Browser.IE) timeout = 250;   
        }
        //this.galleriaContainer.setStyle({ width: imgWidth, height: imgHeight+50 });
        if(this.options.image_border){
			$(this.id+'galleriaContainer').setStyle({ border: '1px solid #000000' });
        }
        (function(){
			this.showImage();
			$(this.id+'galleriaThumbnailsContainer').show();
			$(this.id+'galleriaBorder').show();
        }).bind(this).delay(timeout / 1000);
    },
    
    //
    //  showImage()
    //  Display image and begin preloading neighbors.
    //
    showImage: function(){
       // this.loading.hide();
        new Effect.Appear($(this.id+'galleriaImages'), { 
            duration: this.resizeDuration, 
            queue: 'end'
        });        
    },

    //
    //	Function for creating navigation
    //
    createNav: function() {
		navigationLength = this.imageArray.length;
		var table = Builder.node('table', {id:this.id+'galleriaTable',
					  cellpadding: '0',
					  cellspacing: '2',
					  border: '1',
					  className: 'galleriaTable'
					});

		var tbody = Builder.node('tbody');
		var tr = Builder.node('tr');
		
		
		for(i=0;i<navigationLength;i++){
			var td = Builder.node('td', {'height':((this.options.width/this.imageArray.length)-this.options.thumb_margin)*0.5+'px','width': (i==(navigationLength-1)?((this.options.width/this.imageArray.length)+this.options.thumb_margin_adjustment):(this.options.width/this.imageArray.length))-this.options.thumb_margin+'px'}, [Builder.node('strong', ' ')] );
			tr.appendChild(td);

		}	
		
		tbody.appendChild(tr);
		table.appendChild(tbody);  
		$(this.id+'galleriaThumbnailsContainer').appendChild(table);
    },
    
    //
    //  preloadNeighborImages()
    //  Preload previous and next images.
    //
    preloadNeighborImages: function(){
        var preloadNextImage, preloadPrevImage;
        for(i=0;i<this.imageArray.length;i++){
        	preloadImage = new Image();
            preloadImage.src = this.imageArray[i].image;          
        }   
    },  
    
	//For scaling the image
	scale: function(image, w, h, crop, max, margin, complete) {
        margin = margin || 0;
        complete = complete || function() {};
        width = w || image.width;
        height = h || image.height;
        var ratio = Math[ (crop ? 'max' : 'min') ](width / image.width, height / image.height);
        if (max) {
            ratio = Math.min(max, ratio);
        }
        image.width = Math.ceil(image.width * ratio) - margin*2;
        image.height = Math.ceil(image.height * ratio) - margin*2;
        return image;
    },

//ROLL OVER FUNCTIONS FOR LIST TABLES
//add these to cells by doing a javascript add listener event thing
init_table:function (thisTable){
	var tableRows = thisTable.rows;
	i=0;
	while(tableRows[i]){
		rowCells = tableRows[i].cells;
		j=0;
		while(rowCells[j]){
			if (navigator.appName == "Microsoft Internet Explorer"){
				Element.observe(rowCells[j],'mouseover', (function(event) { 
					this.navCellRollOn(event);
				}).bindAsEventListener(this));   
				Element.observe(rowCells[j],'mouseout', (function(event) { 
					this.navCellRollOff(event);
				}).bindAsEventListener(this));
			} else {								
				rowCells[j].observe('mouseover', (function(event) { 
					this.navCellRollOn(event);
				}).bindAsEventListener(this));   
				rowCells[j].observe('mouseout', (function(event) { 
					this.navCellRollOff(event);
				}).bindAsEventListener(this));   
			}
			j++;
		}
		rowCells[0].style.backgroundColor = cellHighlightColor;
		i++;
	}
},
//the roll on function to highlight the cell and change image
navCellRollOn:function (e){
	var whichElement = e.target || e.srcElement;
		
	myRow = whichElement.parentNode.parentNode.rows[whichElement.parentNode.rowIndex];
	myRowCells = myRow.cells;
	i=0;
	while(myRowCells[i]){				
		myRowCells[i].style.backgroundColor = whichElement.parentNode.parentNode.style.backgroundColor;
		i++;
	}
	whichElement.style.backgroundColor = cellHighlightColor;
	this.changeImage(whichElement.cellIndex); 
	if (this.imageArray[this.activeImage].description != ""){
         $(this.id+'galleriaInfo').update(this.imageArray[this.activeImage].caption).show();    
    }    
},
//the roll off function to hide the info
navCellRollOff:function (e){
	$(this.id+'galleriaInfo').hide();
}
};

//ROLL OVER FUNCTIONS FOR LIST TABLES
// holder for init state
var cellBorderColor = "#FFFFFF";
var cellHighlightColor = "#000000";
