function Gallery( conf ){
	
	//create bindings to our DOM 
	this.$nav 		= $(conf.nav);
	this.$media		= $(conf.media);
	this.$more		= $(conf.more);
	this.$title 	= $(conf.title);
	
	//add some vars for slideshow
	this.paused 	= true;
	this.timeout 	= null;
	
	//extend teh default settings
	this.config 	= $.extend( { autosize:false, slideShow: false, slideDelay: 10000, change: function(){} }, conf);
	
	//create a ref to this
	var self 		= this;
	
	//setup the nav
	this.$nav
		.find('>li>a')
		.unbind('click.gallery')
		.bind('click.gallery',function(e){ 
			e.preventDefault(); 
			self.stop();
			self.load(this); 
		});
		
	//make one a default if there is no current
	if( this.$nav.find('>li.current').length < 1 ){
		this.load( this.$nav.find('>li:first-child>a') );
	}
	
	//kick off the slideshow if needed	
	if( this.config.slideShow == true ){
		this.start();
	}
}

Gallery.prototype.start = function(){
	
	this.stop();
	var self 				= this;
	this.paused 			= false;
	this.config.slideShow 	= true;
	this.timeout 			= setTimeout( function(){ self.next(); }, this.config.slideDelay );	
}

Gallery.prototype.stop = function(){

	this.paused = true;
	clearTimeout( this.timeout );
}

Gallery.prototype.fit = function( dims, fit, apply ){
	
	var h = dims.height;
	var w = dims.width;
	var r = h/w;
	
	//fit image dimensions
	if( r <=1 && w > fit.width ){
		w = fit.width;
		h = Math.floor(w * r);
	}
	if( h > fit.height ){
		h = fit.height;
		w = Math.floor(h / r);
	}
	if( apply ){
		dims.width 	= w;
		dims.height = h;	
	}
	
	return {width:w,height:h};	
} 

Gallery.prototype.next = function(){
	
	var $next = this.$nav.find('>li.current+li>a');
	if( $next.length == 0 ){
		$next = this.$nav.find('>li:first-child>a');
	}
	this.load( $next );	
}

Gallery.prototype.previous = function(){
	
	var $prev = this.$nav.find('>li.current').prev().find('>a');
	if( $prev.length == 0 ){
		$prev = this.$nav.find('>li:last-child>a');
	}
	this.load( $prev );	
}

Gallery.prototype.loadMedia = function( media, onload ){

	//if it is an image
	if( media.match(/.gif|.png|.jpg|.jpeg/i) != null ){
		var obj  = new Image();
		obj.onload = function(){
			if( typeof onload == 'function' ){
				onload( obj );
			}							
		}
		obj.src = media;
	} else {
		
		var $obj = $('<div class="object"><div></div></div>');
		
		var obj = $obj.find('>div').media({
			width: 			this.$media.width(),
			height: 		this.$media.height(),
			autoplay: 	true,
			src: 	  		media,
			caption:		false,
			bgColor: 		null,
			attrs: { wmode: 'transparent', bgcolor: null},
			params: { wmode: 'transparent', bgcolor: null}
			
		});
		if( typeof onload == 'function' ){
			onload( $obj );
		}	
						
	}
	return $obj;

}

Gallery.prototype.load = function( item ){
	
	if( this.$media.hasClass('loading') == false ){
		
		var title 		= '';
		var media		= '';
		var more		= '';
		var $item 		= $(item);
		var self		= this;
		
		//if this is a link
		if( $item.is('a') ){
			title 	 = $item.attr('title');
			media 	 = $item.attr('href');
			more	 = $item.siblings('.more').html(); 
			
			//if this item is in a nav, add a class of parent to it
			this.$nav.find('>li').removeClass('current');
			if( $item.parent().is('li') ){
			  $item.parent().addClass('current');
			}
		
		//else, if this is a JSON object
		} else if ( typeof item == 'object' ){
			
			if( item.title ){
				title 	 = item.title;
				mediaUrl = item.media;
				more 	 = item.more; 
			}
			 		
		//if it is a string, we assume a jQuery expression
		} else if ( typeof item == 'string' ){
			
			self.load( $(item) );	
	
		}		
		
		//load the image in the background
		this.$media.addClass('loading').find('img').animate({opacity:0});
		
		this.loadMedia( 
			media,
			function( object ){
				//make a ref to the jquery image
				var $prev 	= self.$media.find('img,.object').parent();
				var $next	= $('<span/>').append($(object)).hide().css({opacity:0},10);
				
				//fit this image to the viewport
				if( self.config.autosize == true ){
					self.fit( object, {width:self.$media.width(), height:self.$media.height()}, true );
				}
				
				//now that we've extracted the title, url and more text, add it to the DOM
				self.$title.html(title);
				self.$more.html( more );
				
				//lastly, add the image to the DOM and cross fade it
				self.$media.removeClass('loading').prepend( $next );
				
				//cross-fade if images - fade in if transitioning from object to image
				if( $prev.find('img').length > 0 && $next.find('img').length > 0 ){
					$prev.animate({opacity:0}, 
						function(){ 
							$(this).remove(); 
							if( self.paused == false ){
								self.start();
							} 
						} 
					);
					$next.show().animate({opacity:1});
				} else {
					$prev.hide().remove();
					$next.css({opacity:1}).hide().show();
					if( self.paused == false ){
						self.start();
					} 
				}

				//call the callback	
				self.config.change.call(self, $item.get(0), self.$media.get(0), self.$title.get(0), self.$more.get(0));	

			}
		)
	
	}
	
}