/**

 */

var Gallery = Base.extend({

	loader: null,		// String, path to image preloader loading gif;
	secondary: null,	// HTMLElement(s), additional content to be inc. in gallery;
	primary: null,		// String, (url) ref to current image;
	$: null,			// jQuery; 
	link: null,			// temp;
	

    // constructor;
     constructor: function() {},
     
    // init;
    init: function( $ ){
		if( ! $ )
			{ return false; };
		this.$ = $;
		this.loader = "Images/Gallery/loader.gif";
		this.bind();
		this.build();
	},
	
    /**
     * builds the following dom structure and binds event handlers;
     * <div class="ui-overlay"></div>
	 * <div class="ui-gallery">
	 *		<div class="head">
	 *			<a>Prev</a><a>Next</a>
	 *		</div>
	 *		<div class="main"></div>
	 *		<div class="foot">
	 *			<p></p>
	 *			<a>Close</a>
	 *		</div>
	 * </div>
     */
    build: function(){
		var root = this.$( "body" );
		var self = this;

		var overlay = this.$( "<div></div>" )
						.addClass( "ui-overlay" )
						.appendTo( root )		
						.bind( "click", function( e ){
							self.handler.call( self, e, "hide" );
							return stopDefault( e );
						});
						
		var gallery = this.$( "<div></div>" )
						.addClass( "ui-gallery" )
						.hide()
						.appendTo( root );	
						
		var head =	this.$( "<div></div>" )
						.addClass( "head clear" )
						.appendTo( gallery );
												
		var main =	this.$( "<div></div>" )
						.addClass( "main" )
						.appendTo( gallery );
						
		var gutter = this.$( "<div></div>" )
						.addClass( "gutter clear" )
						.appendTo( main );

		var foot =	this.$( "<div></div>" )
						.addClass( "foot clear" )
						.appendTo( gallery );					
		/*
			var title =	this.$( "<p></p>" )	
						.css({ visibility: "hidden" })
						.appendTo( foot );
		*/

		var prev =	this.$( "<a>&laquo Prev</a>" )	
						.attr( "href", "#" )	
						.addClass( "prev" )
						.appendTo( foot )
						.bind( "click", function( e ){
							self.handler.call( self, e, "prev" );
							this.blur();
							return stopDefault( e );
						});	

		var next =	this.$( "<a>Next &raquo</a>" )	
						.attr( "href", "#" )
						.addClass( "next" )	
						.appendTo( foot )
						.bind( "click", function( e ){
							self.handler.call( self, e, "next" );
							this.blur();
							return stopDefault( e );
						});					

		var close =	this.$( "<a>Close</a>" )	
						.attr( "href", "#" )
						.addClass( "close" )		
						.appendTo( foot )
						.bind( "click", function( e ){
							self.handler.call( self, e, "hide" );
							return stopDefault( e );
						});	
						
		var loader = this.$( "<div></div>" )
						.addClass( "ui-preloader" )
						.appendTo( root )
						.hide();	
						
		var image =	 this.$( "<img></img>" )
						.attr( "src", this.loader )
						.attr( "width", 38 )
						.attr( "height", 38 )
						.appendTo( loader );	
						
    },
    
    /**
     * bind the child links of all elements with 
     * a parent of class gallery;
     */
    bind: function(){
		var self = this;
		// collect all in page galleries...;
	    this.$( ".gallery" ).each( function( i, val ){
			// ..and bind click handlers;
			self.$( "a", val ).bind( "click", function( e ){
				self.handler.call( self, e );
				this.blur();
				return stopDefault( e );
			}); 
	    });
    },
    
    /**
     * 
     */
    handler: function( event, type ){
		switch( type ){
			case "hide":
				this.hide();
				break;
			case "prev":
				this.prev( event );
				break;
			case "next":
				this.next( event );
				break;
			default:
				var node = event.target.parentNode;
				this.setContent( node );
				break;
		};
    },
    
    next: function(){
		var link, elem;
		elem = this.getSibling( "next" )
		if( elem ){
			link = this.$( "a", elem ).get();
			this.setContent( link );
		};
    },
    
    prev: function(){
		var link, elem;
		elem = this.getSibling( "prev" )
		if( elem ){
			link = this.$( "a", elem ).get();
			this.setContent( link );
		};
    },
    
    getSibling: function( direction ){
		var self = this, elem, node;
		var galleries = this.$( ".gallery" );
		this.$( "a", galleries ).each( function(){
			if( this.href.indexOf( self.primary ) !== -1 ){
				elem = this;
			 };
		});
		// HACK: get parent li elem next 
		// sibling, not very clever!!;
		var node =	this.$( elem )
					.parent()
					.parent()
					[direction]();
		if( node.length == 1 ){
			return node;
		}else{
			return false;
		};
    },
    
    /**
     * set required content;
     * @param	elem{HTMLElement}	current clicked item;
     */
    setContent: function( elem ){
		this.link = elem;
		this.hide();
		this.clear();
		this.primary = this.$( elem ).attr( "href" );
		this.setPrimary( this.primary );
		this.setSecondary( this.primary );
    },
    
    /**
     *clear gallery content;
     */
    clear: function(){
		var gallery = this.$( ".ui-gallery" );
		this.$( ".gutter", gallery )
			.empty();
    },
    
    /**
     * primary gallery content, project specific implimentation;
     * @param	elem{HTMLElement}	current clicked item;
     */
    setPrimary: function( elem ){
		this.loadImage( elem );
    },
    
    setSecondary: function( elem ){
		
		/*var link, self = this, elem, paras;
		// loop though all the galleries in the page and...;
		this.$( ".gallery" ).each( function( i, val ){
			var links = self.$( "a", this );
			// ..locate the anchor the current 
			// image is linked to from;
			link = links.filter( function(){
				//console.log( this.href );
				return ( this.href.indexOf( self.primary ) !== -1 )
			});
		});
		// get li element that contains 
		// the current image link;
		elem =	this.$( link )
					.parent()
					.parent();
		// grab it's paras;		
		var i = this.secondary = this.$( "p", elem )
								.clone( true );

		return i;*/
		var elems = {};
		var elem =	this.$( this.link )
					.parent()
					.parent();
		elems.header =	this.$( "h3", elem )
						.clone( true );
		elems.paras =	this.$( "p", elem )
						.clone( true );
		return this.secondary = elems;
    },
    
    /**
	 * preload new image;
	 * @param	image{String}	ref to new image;
	 */	
	loadImage: function( url ){
		// this.preloader.load( image, this.loaded, this );
		var self = this;
		var image = new Image();
		image.onload = function(){
			self.loaded.call( self, image );
		};
		image.src = url;
		var loader = this.$( ".ui-preloader" );
		loader.show();
		this.adjust( loader );
		this.setOverlay();
	},
	
	 // display gallery content;
	show: function(){
		this.$( ".ui-gallery" )
			.show();
	},
	
	hide: function(){
		this.$( ".ui-overlay" )
			.hide(); 
		this.$( ".ui-gallery" )
			.hide();	
	},
	
	hideOverlay: function(){
		this.$( ".ui-overlay" )
			.hide();	
	},
    
    /**
	 * declarative only, provides a brief 
	 * pause before displaying image;
	 * @param	elObject}	ref to new image;	
	 */
	loaded: function( el ){
	    var self = this;
        setTimeout( function(){
                self.showContent( el );
            }, 500, el );
	},
	
	showContent: function( elem ){
		// console.log( "showContent(); " + image );
		this.$( ".ui-preloader" ).hide();
		var gallery = this.$( ".ui-gallery" );
		var main = this.$( ".gutter", gallery );
		this.addPrimary( main, elem );
		this.addSecondary( main );
		gallery.show();
		this.adjust( gallery );
	},
	
	addPrimary: function( elem, content ){
		// add new image...;
		elem.prepend( content );
		// ..and fade in;
	    /*this.$( content+":last", elem )
	        .css( "opacity", 0 )
	        .fadeTo( "slow", 1 ); */
	},
	
	addSecondary: function( elem ){
		this.secondary.header.appendTo( elem );
		this.secondary.paras.appendTo( elem );
	},
    
    /**
     * center the gallery in the browser on load of 
     * new image, resize of browser and page scroll;
     */
    adjust: function( elem ){
		var self = this;
        var width = elem.width();
        var height = elem.height();
        var l = this.scrollX() + 
			( this.width()/2 ) - ( width/2 );
        var t = this.scrollY() + 
			( this.height()/2 ) - ( height/2 );
        l = ( l < 0 ) ? 0 : l;
        t = ( t < 0 ) ? 0 : t;  
        elem.css({ left: l, top: t });
        /*
			window.onresize = document.onscroll = window.onscroll = function(){
				self.adjust.call( self );
			};
		*/
    },
    
    /**
     * reset overlay size on browser resize, scroll etc;
     */
    setOverlay: function(){
		this.$(".ui-overlay").css({
			width:	document.body.scrollWidth + "px",
			height:	document.body.scrollHeight + "px",
			opacity: .75
		}).show();
	},
    
    scrollX: function(){
	    var de = document.documentElement;
	    return self.pageXOffset ||
	        ( de && de.scrollLeft ) ||
	            document.body.scrollLeft;
	},
	
	scrollY: function(){
	    var de = document.documentElement;
	    return self.pageYOffset ||
	        ( de && de.scrollTop ) ||
	            document.body.scrollTop;
	},
	
	width: function(){
		var de = document.documentElement;
		return self.innerWidth || 
			( de && de.clientWidth ) ||
				document.body.clientWidth;
	},
	
	height: function(){
		var de = document.documentElement;
		return self.innerHeight || 
			( de && de.clientHeight ) ||
				document.body.clientHeight;
	}
});