// Guidebook UI Base 1.0
// Written by Pete Lada
// Dec 7th, 2011

/*
This will include only functions which are abstracted enough to apply to multiple different sites (i.e. Gears & Corp).
*/


if(!GBUI){
	var GBUI = {};
}

/* Tooltip
-----------------------------------------------------------------------------------------------------------*/ 


//constructor
GBUI.tooltip = function(el, options){
	
	var that = this;
	
	that.options = {
		ttClass: 'gui-tooltip',
		bottom: '10',
		layout: '<div><span></span></div>',
		zindex: 15
	}
	
	for (i in options) that.options[i] = options[i];
	
	that.start(el);
};

// Prototype
GBUI.tooltip.prototype = {
	
	start: function(el){
		var that = this,
			title = el.attr('title'),
			offset = el.attr('data-tooltip-offset') || 0,
			tip,
			pos,
			classN = that.options.ttClass;
		
		if ( el.parents("#overlay").length == 1 ) { 
			classN += ' in-overlay';
		}
		
		//create & layout tooltip
		tip = $(that.options.layout).addClass(classN).appendTo('body').append(title);
		
		// Remove Title Attr
		el.removeAttr("title");
		
		// indicate that element has tooltip bound to it
		el.data('tooltip', 'true');
		
		// Assign tips
		that.assign(tip, el, offset);
	},
	
	assign: function(tip, el, offset){
		var that = this;
		// Show/hide TT
		el.bind('mouseover', function(e){	
			// in case position has changed
			pos = that.getPosition(el, tip, that.options, offset);
			//show tip
			tip.css({display:'block', position:'absolute', left: pos.left, top: pos.top, 'z-index': that.options.zindex});
			if(pos.position === 'right'){
				tip.addClass('right');
			}
		});
		
		el.bind('mouseout', function(e){
			tip.hide(); 
		});
	},
	
	getPosition: function(el, tip, conf, offset){
		var top = el.offset().top - tip.innerHeight() - conf.bottom;		
		var containerRight = $('#header').offset().left+1000;
		var left = parseInt(el.offset().left) + parseInt(offset);
		var position = 'left';
		if(left+tip.innerWidth() > containerRight){
			position = 'right';
			left = left + el.innerWidth() - tip.innerWidth();
			//tip.find('span').css('right', (el.innerWidth()/2)+'px');
		}else{
			//tip.find('span').css('left', (el.innerWidth()/2)+'px');
		}
		
		// set an offset if the width of the element is less than 10 (about the size of the arrow)
		if(el.width() < 15){
			if(position === 'left')
				left -= 12;
			else
				left += 12;
		}
		
		return {'top': top, 'left': left, 'position': position};	
	}
}

GBUI.tooltip.init = function(options){
	
	$('[title]').each(function(){
		var x = new GBUI.tooltip($(this), options);
	});
}

GBUI.tooltip.hideAll = function(){
	$('.gui-tooltip').hide();
}




/* Form Placeholder Text
-----------------------------------------------------------------------------------------------------------*/

/* Constructor */
GBUI.placeholder = function(el, options){
	
	var that = this;
	
	that.el = $(el);
	
	that.options = {
		color: "#666",
		zindex: 9999
	};
	
	// custom options
	for (i in options) that.options[i] = options[i];
	
	that.start();

}

/* Prototype */
GBUI.placeholder.prototype = {
	
	start: function(){
		var that = this,
			text = that.el.attr('data-placeholder');
		that.buildOverlay(text);
	},
	
	getCoords: function(){
		var that = this,
			left = that.el.position().left,
			top = that.el.position().top,
			height = that.el.outerHeight(),
			width = that.el.outerWidth();
		return({'left':left, 'top':top, 'height':height, 'width':width});
	},
	
	buildOverlay: function(text){
			
		var that = this,
			classN = 'placeholder-overlay';
		var pl = that.el.parent();
		
		// Only insert placeholder if one doesn't exist
		if( that.el.hasClass('has-placeholder') === true){
			return;
		}
		
		// sets parent container to have a relative position if it doesn't already - this allows the absolute placeholder to position correctly. 
		if(that.el.parent().css('position') !== 'absolute'){
				that.el.parent().css('position', 'relative');
		}
		
		if ( that.el.parents("#overlay").length == 1 ) { 
			classN += ' in-overlay';
		}
		
		var overlay = $('<div></div>').append('<span>' + text + '</span>').addClass(classN).prependTo(pl);

		
		if(that.el.val() !== ''){ overlay.hide(); }
		
		that.refresh(overlay);
		that.assignHelpers(overlay);
		that.el.addClass('has-placeholder');
	},
	assignHelpers: function(overlay){
		var that = this;
		// Assign focus to element (usually input)
		
		that.el.bind('focus', function(){
			setTimeout(function(){
				if(that.el.val() === ''){
					overlay.fadeTo('fast', .5);
				}
			}, 100);
		});
		
		
		overlay.bind('click',function(e){
			e.stopPropagation();
			that.el.focus();
		});
		
		that.el.bind('keyup blur', function(e){
			if(e.keyCode !== 9){
				setTimeout(function(){
					if(that.el.val() !== '')
						overlay.hide();
					else
						overlay.fadeTo('fast', 1);
				}, 100);
			}	
		});
	
		
	},
	refresh: function(overlay){
		var that = this,
		pos = that.getCoords(), 
		font = that.el.css('font-size');

		overlay.css({
			'left': pos.left,
			'top': pos.top,
			'width': pos.width,
			'height': pos.height,
			'z-index': that.options.zindex,
			'line-height': pos.height + 'px',
			'font-size': font
		});
		
		if(that.el.is('textarea') === true ){
			overlay.css({
				'line-height': 'normal',
				'top': pos.top+6+'px'
			});
		}
	}
	
	
	
};

GBUI.placeholder.init = function(options){
	$('[data-placeholder]').each(function(){
		var x = new GBUI.placeholder($(this), options);
	});
};

GBUI.placeholder.check = function(){
	$('[data-placeholder]').each(function(){
		if($(this).val() !== ''){
			$(this).parent().find('.placeholder-overlay').hide();
		}
	});
}






/* Twitter
-----------------------------------------------------------------------------------------------------------*/ 

GBUI.twitter = function(){
	
	var defaults = {
		account: 'guidebook',
		count: 1,
		el: 'document.body',
		layout: '<div></div>',
		tweetClass: 'tweet',
		loadingText: 'Loading Tweets…'
	},
	
	// regex to create links within the twitter text (links urls and @usernames)
	createLinks = function(text) {
		var url_regexp = /(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
		var linkedText = text.replace( url_regexp, '<a target="_blank" href="$1://$2$3$4$5$6">$1://$2$3$4$5$6</a>');
		linkedText = linkedText.replace(/(^|\s)@(\w+)/g, '$1<a target="_blank" href="http://www.twitter.com/$2">@$2</a>');
		return linkedText;
	},
	
	// Tweet class
	Tweet = function(text, options){
		var l = $(options.layout).addClass(options.tweetClass).appendTo(options.el).append(createLinks(text));
	},
	
	getTweets = function(options){
		var url='http://search.twitter.com/search.json?callback=?&q=from%3A' + options.account + '&include_entities=true';

		$.getJSON(url,function(json){
			$(options.el).html('');
			$.each(json.results, function(i,tweet){
				if(i<=options.count-1){
					var t = new Tweet(tweet.text, options);
				}
			});
			
		});
	},
	
	init = function(options){
		var newOptions = $.extend(defaults, options);
		var loading = $('<div></div>').append(newOptions.loadingText).appendTo(options.el);
		getTweets(newOptions);
	};
	
	return init;
	
}();


/* Overlay
-----------------------------------------------------------------------------------------------------------*/ 

GBUI.overlay = function(){
	
	var defaults = {
		exposeColor: '#fff',
		overlayClass: 'gbui-overlay',
		loadingClass: 'loading',
		loadingText: 'Loading…',
		animation: 'none'
	},
	
	// Trigger Class
	Trigger = function(el, options, type){
		var trigger = $(el),
			url = trigger.attr('href'),
			oClass = '';
		if(trigger.attr('data-overlay-type')){
			oClass = trigger.attr('data-overlay-type');
		}
		trigger.click(function(e){
			e.preventDefault();
			var o = new Overlay(options, url, type, oClass);
			trigger.data('overlay', o);
		});
	},
	
	// Overlay class
	Overlay = function(options, url, type, oClass, callback){
		var overlay = $('<div></div>').addClass(options.overlayClass).addClass(type).addClass(oClass).attr('id','overlay').appendTo(document.body).hide();
				
		animate('in', overlay, options, function(){
			load(overlay, url, options, callback);
			
			$(document).bind('keydown', function(event){
				if(event.keyCode === 27){
					close(overlay);
				}
			});
		});
		
		if($('#gbui-expose-mask').length === 0){
			var expose = $('<div></div>').attr('id', 'gbui-expose-mask').click(function(){
				if(type !== 'modal'){
					close(overlay);
				}
			}).css('opacity', '.8').appendTo(document.body);
		}else{
			$('#gbui-expose-mask').show().unbind().click(function(){
				if(type !== 'modal'){
					close(overlay);
				}
			});
		}
	},
	
	open = function(options, url, type, oClass, callback){
		if(!callback){
			callback = null;
		}
		var x = new Overlay(options, url, type, oClass, callback);
	},
	
	animate = function(direction, overlay, options, callback){

		if(options.animation === 'fade' && direction === 'in'){
			$(overlay).fadeIn('fast', function(){
				callback();
			});
		}
		else if(options.animation === 'fade' && direction === 'out'){
			$(overlay).fadeOut('fast', function(){
				callback();
			});
		}
		else{
			if(direction === 'in'){
				$(overlay).show();
			}else{
				$(overlay).hide();
			}
			callback();
		}
	},
	
	load = function(overlay, url, options, callback){
		var loading = $('<div></div>').append(options.loadingText).addClass(options.loadingClass).appendTo(overlay);
		$.ajax({
			url: url,
			complete: function(data){
				if(data.statusText === 'error'){
					$(overlay).html('<div class="' + options.loadingClass + '">Uh oh, something went wrong! We\'re working on fixing this. <br/><br/><a href="javascript:GBUI.overlay.close(\'.overlay\');">Close overlay and try again.</a></div>');
				}else{
					$(overlay).html(data.responseText);
					if(callback != null){
						callback();
					}
					createCloseButtons(overlay);
				}
			}
		});
	},
	
	createCloseButtons = function(overlay){
		$(overlay).find('.close-overlay').click(function(){
			close(overlay);
		});
	},
	
	close = function(overlay){
		if(!overlay){
			return;
		}
		animate('out', overlay, defaults, function(){
			$(overlay).remove();
			$('#gbui-expose-mask').hide();
		});
		$(document).unbind();
	},

	getOverlay = function(trigger){
		console.log($(trigger).data('overlay'));
	},
	
	allocateOverlays = function(options){
		
		$('[rel=overlay]').each(function(){
			var o = new Trigger($(this), options, 'overlay');
		});
		
		$('[rel=overlay-modal]').each(function(){
			var o = new Trigger($(this), options, 'modal');
		});
		
	},
	
	closeAll = function(){
		$('.gbui-overlay').remove();
		$('#expose-mask').hide();
	},
	
	init = function(options){
		defaults = $.extend(defaults, options);
		allocateOverlays(defaults);
	};	
	
	return {init: init, close: close, open: open, closeAll: closeAll}
	
}();


/* Rotating Content with paging indicators
-----------------------------------------------------------------------------------------------------------*/ 

GBUI.rotate = function(){
	var settings, currentIndex = 0, heroes = [], timer, active = true,
	defaults = {
		el: '#hero',
		delay: 3000,
		animationSpeed: 700,
		pagingIndicators: true
	},
	
	Hero = function(el, id){
		$(el).attr('data-rotate-id', id);
		heroes.push(id);
	},
	
	verifyId = function(id){
		if(id < heroes.length){
			return true;
		}else{
			return false;
		}
	},
	
	PagingIndicator = function(el, paging, id){
		var title = '',	
			p = $('<a>&bull;</a>');
		
		if(el.attr('data-title')){
			title = el.attr('data-title');
			p.attr('title', title);
		}
		
		p.click(function(){
			if(currentIndex === id){
				return;
			}
			clearTimeout(timer);
			if(active !== true){
				rotate(id);
			}
		}).attr('data-rotate-id', id).appendTo(paging);
	},
	
	changeIndicator = function(id){
		var holder = settings.pagingHolder || settings.el;
		$(holder).find('.paging-navigation a').each(function(){
			if(parseInt($(this).attr('data-rotate-id')) === id){
				$(this).addClass('selected');
			}else{
				$(this).removeClass('selected');
			}
		});
	}, 
	
	rotate = function(to){
	
		changeIndicator(to);
		active = true;
		
		$(settings.el).find('.item-rotate').each(function(){
		
			if($(this).css('display') === 'block'){
				$(this).fadeOut(settings.animationSpeed);
			}
		
			if(parseInt($(this).attr('data-rotate-id')) === to){
				$(this).fadeIn(settings.animationSpeed, function(){
					currentIndex = to;
					timer = setTimeout(function(){
						if(verifyId(to+1) === true){
							clearTimeout(timer);
							rotate(to+1);
						}else{
							clearTimeout(timer);
							rotate(0);
						}
					}, settings.delay);
					active = false;
				});
			}
		});
	},
	
	createPagingHolder = function(){
		var holder = settings.pagingHolder || settings.el;
		var x = $('<div></div>').addClass('paging-navigation').appendTo(holder);
		return x;
	},
	
	init = function(options){
		heroes = [], currentIndex = 0;
		clearTimeout(timer);
		settings = $.extend(defaults, options);
		var paging = createPagingHolder();
		$(settings.el).find('.item-rotate').each(function(i){
			var t = new Hero($(this), i);
			if(settings.pagingIndicators === true){
				var x = new PagingIndicator($(this), paging, i);
			}
		});
		rotate(0);
		
	};
	
	return init;
	

}();
