/*
Title:      jquery.EveryoneForever
Description:EF site core
Developer:  Antenna RF (http://theantenna.net)
Date:       January 2010 
Version:    0.0.4
Usage:             
Notes:      
To Do:      proper deep linking when Posterous API matures
License:    All licenses held by:
            Universal Everything Ltd
            Registered in England # 0557 4344
            Registered Office - 16 / S7 1PB
*/

(function($) {
	
	$.everyoneforever = function(){}
	
	// defaults
	$.everyoneforever.defaults = {
		defaultTag:'everything'
	};

	$.fn.everyoneforever = function( options )
	{
		var 
			TWIT_SHARE = "http://twitter.com/home?status=Everyone+Forever-+%TITLE%+%LINK%",
			FACE_SHARE = "http://www.facebook.com/sharer.php?u=%LINK%&t=Everyone+Forever-+%TITLE%",
			TUMB_SHARE = "http://tumblr.com/share?v=3&u=%LINK%&t=Everyone+Forever-+%TITLE%&s=",
			DELI_SHARE = "http://delicious.com/save?url=%LINK%&title=Everyone+Forever-+%TITLE%",
		
			opts = $.extend($.everyoneforever.defaults, options), // defaults
			$this = this, // instance
			$items = $('#items'),
			$temp = $('#temp'),
			$lightbox = $('#lightbox'),
			$window = $(window),
			loadmore,
			hasItems = false, // items in the grid
			firstLaunch,
			scrollTop = 0, 
			itemsHeight = 0,
			urlParams = {};
		
		var parseHash = function(params)
		{
			params = params||{tag:opts.defaultTag}; //{tag:urlParams.tag}; // keep old tag unless overwritten

			// load params from url
			var hash = location.hash.toString().replace(/\?.*/,'');
			
			if(hash.indexOf('/')>-1 ){
				var newParams = hash.split('/').slice(1),
					re = new RegExp( "^" + opts.pseudoID + "\\d+" );
				
				$.each(newParams,function(i,param){
					if( re.test(param) ) params.pid = param.slice(2);
					else if(this.length) params.tag = param;
				})
			}

			urlParams = params;
		};
					
		var initialize = function()
		{
			// hashchange events / back button
			$(window).bind( 'hashchange', function(e,params){
				
				firstLaunch = params!=undefined;
				var oldTag = urlParams? urlParams.tag : opts.defaultTag;
				
				parseHash(params);
				
				var isItem = urlParams.pid,
					isOpen = $lightbox.hasClass('open');
				
				if( isOpen && !isItem) // going from lb to index
					closeLightbox();
				else if(!isOpen && !isItem){ // changing from one index to another
					getItems();
					$('a[href="#/'+oldTag+'"]').removeClass('active');
					$('a[href="#/'+urlParams.tag+'"]').addClass('active');
				}
				else if(!isOpen && isItem) // launch lb
				{
					launchLightbox(urlParams.pid);
					if(firstLaunch) getItems(); // first time: need to get items behind LB
				}
					
			}).trigger('hashchange', {tag:opts.defaultTag} ); // first time
			
			$('#overview-close').click(function(e,noAnim){
				
				e.preventDefault();
				var spd = noAnim? 0 : 500;
				
				$('#overview-wrapper').css('min-height','');
				$('#overview').toggle(spd, function(){
					$('#overview-open').show(spd);
					$(window).trigger('scroll.loadmore');
				});
				
				$(this).hide();
				
				$.cookie('overview-off', true, { expires:365} );
			});
			
			$('#overview-open').click(function(e){
				
				e.preventDefault();
				
				//$('#overview-wrapper').css('min-height',22);
				$('#overview').toggle(500, function(){ $('#overview-close').show(500) } );
				
				$(this).hide();
				
				$.cookie('overview-off', null );
				
			}).hide();
			
			if( $.cookie('overview-off') ) $('#overview-close').trigger('click',true);
			
			$('#lightbox-close').click(function(e){
				if(!firstLaunch) // firstlaunch = normal hash change
				{
					e.preventDefault();
					window.history.go(-1);
				}
			});
			
			$('#lightbox-share').click(function(e){
				e.preventDefault();
				$('#lightbox-sharenav').show();
			});
			$('#lightbox-sharenav').mouseleave(function(e){
				$('#lightbox-sharenav').hide();
			});
			
			$('#foot-share').click(function(e){
				e.preventDefault();
				$('#foot-sharenav').show();
			});
			$('#foot-sharenav').mouseleave(function(e){
				$('#foot-sharenav').hide();
			});
				
			// setup soundmanager swf
			$.playable(WWW+'static/swf/', {playAlone : true});
			
			// on grid change
			$items.bind('gridchange',function(e){
				
				//keep track of #items height
				//log('grid change', $items.height());
				$items.height($items.matrixLayout.info().maxHeight);

				//trigger event for LB listener
				$items.trigger('onGetItems');
			});
		

			getTags();
			
			return $this;
		};
		

		
		// GET TAGS ------------------------------------------------------------------
		var getTags = $this.everyoneforever.getTags = function()
		{
			//log('getting', TAG_API);
			
			$.ajax({
				   
				type: "GET",
				url: TAG_API,
				//cache:false,
				dataType:'json',
				success: function(data){
					
					//log('tags',data);
					
					var $tags = $('.tags').empty();
					
					$.each(data.tag,function(i){
						
						var active = this.tag_string == urlParams.tag;
						
						$('<a class="tag" href="#/'+this.tag_string+'" ><span>'+this.tag_string+'</span></a>')
							.addClass(active? 'active' : '')
							.click(function(e) // filter on tag
							{ 
								var $this = $(this);
								
								if(!$this.hasClass('active')) // filter on this tag
								{
									$('.tag.active').removeClass('active');
								}
								else // turn off this filter
								{
									location.hash ='#/'+$.everyoneforever.defaults.defaultTag;
									e.preventDefault();
								}
								
								$this.toggleClass('active');
								
							}).appendTo($tags);
						
					});
					
				},
				error: function(){
					log(arguments);
				}
			});
			
			return $this;
		}
		
		
		
		
		// GET ITEMS -----------------------------------------------------------------
		var getItems = $this.everyoneforever.getItems = function()
		{
			var page = 1,
				count = 0;
			
			hasItems = false;
			$('.item',$items).remove();
			$items.height('');
			
			// called onload
			$('body').unbind('load.loadmore').bind('load.loadmore',function(e,data){
				
				//$('.navigation').empty();
				$('#loader').hide();
				
				log('pipe returned', data);
				
				if(!data || !data.post) return log('no data');
				data.post = [].concat(data.post);
				
				page ++;
				
				// attach new items 
				var tag = $('a.tag.active').attr('id'), // check if filtered
					target = hasItems? $temp : $items;
				
				count = 0;
				
				// LOOP ITEMS ----------------------------------------------------------------
				$.each(data.post,function(i){
					
					//log(this,this.media);
					var that = this,
						tags = $.map($.isArray(this.tag)?this.tag:[this.tag],function(v){
							return (v && v!=opts.defaultTag? v : null); // remove default tag
						}),
						href = '#/'+(tags? tags[0]+'/':'')+ opts.pseudoID +this.id,
						$t = $('<div/>'),
						date = new Date(this.date),
						total = 0,
						width = 294, // 294 + 16 +10 margin = 320 (40px grid)
						className = 'text', //updated
						$title = $('<a href="'+href+'" class="title">'+this.title+'</a>'),
						$link = $title; // jq set of links that open item

					this.body = typeof this.body !='string'? '' : this.body; // confirm is a string
					this.copy = $('<div class="copy"/>').html(scaleObjects(
							$.trim( this.body ) // whitespace
								.replace( /(<img[^>]*\/>)/g,'') // Removing all imgs (reattached later)
								// Removing posterous links
								.replace(new RegExp("<a href='http://"+POSTEROUS_ID+"\.post[^<]*</a>",'g'),'') 
								.replace(/<p>|<\/p>/g,'') // Removing all p tags (not inner)
								.replace(/style="[^"]*"/g,'') // Removing all styling
					,294));
					// format copy slightly
					$('a',this.copy).attr('target','_blank');
					$('.downloadFlyout, a[href^=\'http://everyoneforever.post\']',this.copy).remove();
					
					this.media = this.media? $.isArray(this.media)? this.media : [this.media] : []; // list of media
					
					this.objects = $('object',this.copy).remove().map( function(index, e){
						that.media.push({type:'embed',element:e});
						return e;
					});
					
					this.tags = tags; this.href = href;
					
					
					// LOOP MEDIA ----------------------------------------------------------------
					$.each(this.media,function(i,o){
						//log(this);
						switch(this.type){
							
							case 'embed' :
								var $e = $(this.element);
								//this.element = $(this.element).prependTo($t);
								$('<div class="object">').css('height',$e.attr('height')+'px')
									.append($e).prependTo($t);
								className = 'embed';
								return false;
								
							case 'video' :	
								var $img = $('<img class="squared" src="' + this.thumb + '" />');
								
								// size images into square
								if( !$img.height() ) $img.css('visibility','hidden').load(function(e){
									scaleToSquare( $img );
								});
								else scaleToSquare( $img );
								
								$link = $link.add (
									$('<a  href="' + href + '"><div class="icon"></div></a>')
									.append( $img )
								);
								
								$('<div class="video-img-wrapper"></div>')
									.append( $link )	
									.prependTo($t);
								
								//width = 294; //Math.max(294,width);
								
								className = 'video quicktime';
								return false;
								
							case 'image' :
								// landscape imgs wider
								//width = this.medium.width > this.medium.height? 494 : 294;
								
								$link = $link.add(
									$('<a href="'+href+'" ></a>').append(
											
										$('<img class="main" height="'
											+ scaleHeight(this.medium.width, this.medium.height, width)
											+ '" width="'+width+'" src="'+this.medium.url+'" />')
											
									).prependTo($t)
								);
								
								className = 'image';
								return false;
								
							case 'audio':
								this.element = $('<a class="audio" href="'+this.url+'"><span class="label"></span></a>')
									.prependTo($t)
									.playable()
									.after('<div class="clear"></div>');
								
								return false;
						}
						
					});
					
					
					
					// CREATING & APPENDING ------------------------------------------------------
				
					if(!this.media.length) // TEXT ONLY ITEMS SHOW COPY
					{
						$t.html(this.copy)
							.append( this.tag!='quote'?'<div class="hr">..........................................................................</div>':'')
								;
					} 
					
					$t.append($title)
					  .append('<p class="meta">Added by ' + (this.author||'guest') + '<br/>' +$.relativeDate(date) + 'ago</p>');
					
					// click to launch extra content
					$link
						.click(function(e){
							//e.preventDefault();
							launchLightbox ( that );
						})
						.mouseenter(function(e){
							//$(this).closest('.item').stop(true,true).animate({ backgroundColor: "#FFFFFF" }, 'fast');
							$(this).closest('.item').addClass('hover').stop(true,true)
								.css({ backgroundColor: "#FFFFFF" });
						})
						.mouseleave(function(e){
							$(this).closest('.item').removeClass('hover').stop(true,true)
								.animate({ backgroundColor: "#000000" }, 'def');
						});
									
					// Special pod style					
					// if(this.tag=='quote')
					// {
					// 	//width = 262;
					// 	$('<div class="tail"></div>').appendTo($t);
					// }
					// else
					if(this.media.length>1)
					{
						$('<img class="earmark" src="'+STAT+'gfx/earmark.png"/>').appendTo($t);	
						className += ' hasMore';
					}
					
					// Append item
					$t.addClass('item '+'tag-'+this.tag+' '+className )
						.css({width:width})
						.appendTo(target);
				});
				
				// GRID + LAYOUT -------------------------------------------------------------
				
				if(!hasItems) // first group
				{
					$items.matrixLayout('#items .item');
					hasItems = true;
					
					// fade in if onscreen
					var c = 1,
						ymin = $window.scrollTop(),
						ymax = $window.height();
					
					$('#items .item').each(function(i){
						
						var $t = $(this),
							ttop = $t.offset().top;
						
						// if onscreen , fade (only if page not scrolled due to browser late scroll update)
						if( ymin==0 && ttop < ymax && ttop+$t.outerHeight(true) > ymin
							// && !$t.hasClass('embed')
						){
							//log($t);
							// var top = $t.position().top;
							// $t.css({opacity:0,top:-$t.offset().top-$t.outerHeight(true)});
							// $t.delay(c++*100).animate({top:top,opacity:1});
							
							$t.hide().delay(c++*100).fadeIn(300);
								//.animate({top:top})
						} 
					});	
				}
				else // adding content to group
				{
					log('adding more');
					$items.matrixLayout.addAfter('#temp .item');
				}
					
				
			});
			
			
			
			// LOADMORE ------------------------------------------------------------------
			loadmore = $('body').loadmore({
				
				ajaxConfig:{dataType:'json', cache:true},
				
				getURL: function(data) // function to determine URL from response data
				{
					return (!data || data.post)? POSTS_API + urlParams.tag +'/'+page : false;
				},
				
				preload: function() // preload
				{
					//$('.navigation').html('Loading more...');
					$('#loader').show(); 
				},
				
				timeout: function() // timeout
				{
					//$('.navigation').html('Taking longer than usual...');
				},
				
				nomore: function() // nomore
				{
					log('nomore');
					//$('.navigation').html('No more posts');
					$('#loader').hide();
				}
				
			});
				
			return $this;
		}
		
		
		
		
		// LIGHTBOX ------------------------------------------------------------------
		var launchLightbox = function(that) // id or data object
		{
			// if id str passed try to launch by finding item on page
			if(typeof that=='string')
			{
				var href = "#/" +
					(urlParams.tag != $.everyoneforever.defaults.defaultTag? urlParams.tag+'/':'') +
					opts.pseudoID + that;
				
				// trying to launch item before data loaded - try to launch after data
				if(!$("#items a[href='"+href+"']").eq(0).click().length)
					$items.one('onGetItems',function(e){
						//log(href,$("#items a[href='"+href+"']"));
						$("#items a[href='"+href+"']").eq(0).click();
					});
					
				return;
			} 
			fillLightbox(that);
			
			loadmore.loadmore.disabled = true; // dont loadmore on reach bottom
			
			scrollTop = $window.scrollTop();
			$lightbox.addClass('open').css({top:0}).show();
				
			// hide all items offscreen for correct scrollbar height
			$items.css({marginTop:-$items.outerHeight(true)-10000});

			$('#lightbox-content').hide().fadeIn();
			
			if(firstLaunch && urlParams.tag){
				$('#lightbox-close').attr('href','#/'+urlParams.tag);
			}
		}
		
		var fillLightbox = function(that){
			var href = WWW + that.href,
				title = escape(that.title),
				$copy = $('#lightbox-copy').html(that.copy.html()),
				$lb = $('#lightbox-content'),
				hasTxt = false;
				
			$('#lightbox-title').text(that.title);
			$('#lightbox-credit').text('Added by ' + (that.author||'guest') );
			$('#lightbox-tag').text(that.tags? ' / Tagged ' + that.tags.join(', ') : '');	
			$("#lightbox-sharenav-tw").attr('href', TWIT_SHARE.replace(/%TITLE%/,title).replace(/%LINK%/,href) );
			$("#lightbox-sharenav-fb").attr('href', FACE_SHARE.replace(/%TITLE%/,title).replace(/%LINK%/,href) );
			$("#lightbox-sharenav-dl").attr('href', DELI_SHARE.replace(/%TITLE%/,title).replace(/%LINK%/,href) );
			$("#lightbox-sharenav-tm").attr('href', TUMB_SHARE.replace(/%TITLE%/,title).replace(/%LINK%/,href) );
			
			// check if any text nodes
			$copy.contents().each(function(){
				if($(this).text().match(/[\w\d]+/)){
					hasTxt = true;
					return false;
				}
			});
			
			//if(!hasTxt) $copy.add($copy.next()).hide(); // hide the hr after copy
			//else $copy.add($copy.next()).show();
			
			if(!hasTxt) $copy.add($copy.next()).hide(); // hide the hr after copy
			else {
				$copy.add($copy.next()).show();

				if(that.copy.height()>84) $copy.addClass('columns');
			}
			
			
			$.each(that.media,function(i,o){
				
				switch(this.type)
				{
					case 'embed':
						// html string
						
						var str =  $("<p>").append($(this.element).clone()).html();

						$('<div>').replaceAll(this.element).replaceWith(str);
						
						$(scaleObjects(str,640)).appendTo($lb);
						break;
						
					case 'image':
						$('<img width="'+this.medium.width+'" height="'+this.medium.height+'" src="'+this.medium.url+'" />').appendTo($lb);
						break;
						
					case 'video':
						var url = this.url,
							img = $('<img src="'+this.thumb+'" />').appendTo($lb),
							fn = function(){
							
								var $t = img,//$(this),
									w = $t.width(),
									h = $t.height()+16;
									//div = $('<div class="wrapper"/>');
							
									$('<object CLASSID="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" width="'+w+'" height="'+h+'" CODEBASE="http://www.apple.com/qtactivex/qtplugin.cab">'+
									'<param name="src" value="'+url+'">'+
									'<param name="qtsrc" value="'+url+'">'+
									'<param name="autoplay" value="false">'+
									'<param name="loop" value="false">'+
									'<param name="scale" value="tofit">'+
									'<param name="controller" value="true">'+
									'<embed src="'+url+'" qtsrc="'+url+'" width="'+w+'"+ height="'+h+'" scale="tofit" autoplay="false" loop="false" controller="true" pluginspage="http://www.apple.com/quicktime/" bgcolor="#000000"></embed>'+
									'</object>')
										.insertAfter($t);
									
							//	$('<a href="'+url+'">Video</a>').insertAfter($t)
							// 	.media({
							// 		width: w, height: h+16,
							// 		attrs: { scale: 'toFit' }, params: { scale: 'toFit'},
							// 		//autoplay:  true, caption: false 
							// });
							
							$t.remove();
						}
						
						if(!img.height())img.load(fn);
						else fn();
						
						break;
					
					case 'audio':

						if(this.element) // switch player element with marker
						{
							this.element.data('marker',$('<div class="audio-marker"></div>').insertBefore(this.element))
								.appendTo($lb);
						} 
						else $('<a class="audio" href="'+this.url+'"><span class="label"></span></a>').appendTo($lb).playable();
				}
				
			});
		}
		
		var closeLightbox = function(e){
											
			//e.preventDefault();
			
			var $lb = $('#lightbox-content');
			
			loadmore.loadmore.disabled = false;
			
			// put audio players back in their items or stop playing
			$('.audio',$lb).each(function(){
				var $t = $(this);
				if($t.data('marker')) $t.data('marker').replaceWith(this);
				else $t.trigger('onstop.playable');
			})
			
			$items.css({marginTop:'0'}); 
			setTimeout(function(){
				$window.scrollTop(scrollTop); // delayed due to #hash change affecting scroll
				$lightbox.removeClass('open')
					.css({top:$window.scrollTop(),height:$window.height()}).fadeOut();
			},20);
			$('#lightbox-content').empty();
			
		}
		
		
		
		
		// MISC ----------------------------------------------------------------------
		var scaleObjects = function(str,nw)
		{
			var w = str.match(/width="(\d+)/),
				h = str.match(/height="(\d+)/);
			
			if(!w || !h) return str;
			
			return str.replace(/width="\d+/g,'width="'+nw)
				.replace(/height="\d+/g,'height="'+ scaleHeight(Number(w[1]),Number(h[1]),nw) );
		}
		
		function scaleToSquare($t)
		{
			var container = $t.closest('.item'),
				containerIsHidden = container.css('display')=='none';
			
			// dims dont work in safari when hidden
			if(containerIsHidden) container.show();
			
			var 
				img_ratio = $t.width() / $t.height(),
				win_ratio = 1; //$win.width() / $win.height();
			
			
			if( img_ratio < win_ratio )
				$t.width(294).css({marginTop:-($t.height()/2)+147});
				
			else
				$t.height(294).css({marginLeft:-($t.width()/2)+147});
			
			$t.css('visibility','');
			if(containerIsHidden) container.hide();
		}
				
		var scaleHeight = function(w,h,nw)
		{
			return Math.round( Number(h) / (Number(w) / nw ) );
		}
		
		//
		return initialize();
	};
	
})(jQuery);