	function get_nextsibling(el) {
		var sibling = el.nextSibling;
		while ( sibling.nodeType != 1 ) {
			 sibling = sibling.nextSibling;
		 }
		return sibling;
	}


var ThumbnailMosaic = Class.create();

ThumbnailMosaic.prototype = {

	initialize : function() {
		return;
	},
	
	setConfig : function(config) {
		this.config = config;
	},
	
	cancelQueue : function(id) {
		var queue = Effect.Queues.get(id);
		queue.each(function(effect) { effect.cancel(); });
	},
	
	growThumbnail : function(el) {	
			var parent = el;
			this.cancelQueue('thumb_shrink_' + this.config.id + '_' + el.id);
			
			var thumb = Element.firstDescendant(parent);
			var nextSibling = get_nextsibling(thumb);
			var siblingHeight = this.config.isHorizontal ? 0 : nextSibling.offsetHeight;
			var siblingWidth = this.config.isHorizontal ? nextSibling.offsetWidth : 0;
			
			var xGrow = (this.config.targetThumbWidth + siblingWidth) - this.config.thumbWidth;
			var yGrow = (this.config.targetThumbHeight + siblingHeight) - this.config.thumbHeight;
			
			var margintop = '0px';
			var marginleft = '0px';
			var marginbottom = '0px';
			var marginright = '0px';
			
			var parentLeft = parseInt(parent.style.left);
			var parentTop = parseInt(parent.style.top);
		
			
			if ( parentLeft == this.config.margin ) {
				marginleft = '0px';
			} else if ( parentLeft < parseInt( (this.config.wallWidth - (this.config.margin * 2)) / 2) ) {
				marginleft = ( (parentLeft - (xGrow/2) ) < 0 ? 0 - parentLeft : (0 - (xGrow/2) ) ) + 'px'; 
			} else {
				marginleft = ( Number(parentLeft + this.config.thumbWidth + (xGrow/2)) > this.config.wallWidth ? 0 - ( (parentLeft + this.config.thumbWidth + (xGrow/2) + this.config.margin) - this.config.wallWidth + (xGrow/2) ) : (0 - (xGrow/2)) ) + 'px';
			}
			
			if ( parentTop == this.config.margin ) {
				margintop = '0px';
			} else if ( parentTop < parseInt( (this.config.wallHeight - (this.config.margin * 2)) / 2) ) {
				margintop = ( (parentTop - (yGrow/2) ) < 0 ? 0 - parentTop : (0 - (yGrow/2)) ) + 'px';
			} else {
				margintop = ( Number(parentTop + this.config.thumbHeight + (yGrow/2)) > this.config.wallHeight ? 0 - ( (parentTop + this.config.thumbHeight + (yGrow/2) + this.config.margin) - this.config.wallHeight + (yGrow/2) ) : (0 - (yGrow/2)) ) + 'px';
			}
		
		
			parent.style.zIndex = 500;
			var movement = { width: (this.config.targetThumbWidth+siblingWidth) + 'px', height: (this.config.targetThumbHeight+siblingHeight) + 'px', marginTop: margintop, marginLeft: marginleft, marginBottom: marginbottom, marginRight: marginright };
			
			new Effect.Morph(parent, {
				style: movement,
				duration: 0.2,
				queue: { scope: 'thumb_grow_' + this.config.id + '_' + el.id }
			});						
			
			new Effect.Morph(thumb.id, {
				style: {
					width: this.config.targetThumbWidth + 'px',
					height: this.config.targetThumbHeight + 'px'
				},
				duration: 0.05,
				queue: { position: 'front', scope: 'thumb_grow_' + this.config.id + '_' + el.id }
			});
	},
	
	shrinkThumbnail : function(el) {			
			var parent = el;	
			this.cancelQueue('thumb_grow_' + this.config.id + '_' + el.id);
			
			var thumb = Element.firstDescendant(parent);
			var nextSibling = get_nextsibling(thumb);
			var siblingHeight = nextSibling.offsetHeight;
					
			new Effect.Morph(parent, {
				style: {
					width: this.config.thumbWidth + 'px',
					height: this.config.thumbHeight + 'px',
					marginLeft: '0px',
					marginRight: '0px',
					marginTop: '0px',
					marginBottom: '0px'
				},
				duration: 0.05,
				queue: { scope: 'thumb_shrink_' + this.config.id + '_' + el.id }
			});
			
			new Effect.Morph(thumb.id, {
				style: {
					width: this.config.thumbWidth + 'px',
					height: this.config.thumbHeight + 'px'
				},
				duration: 0.05,
				queue: { scope: 'thumb_shrink_' + this.config.id + '_' + el.id }
			});
			
			parent.style.zIndex = 0;
	}
}
