/**
 * Common GTANET javascript.
 */var GTANet = (function() {
	var MEDIA_DIR = 'http://media.gtanet.com/common/';
	/**
 * Enable AJAX voting for the Poll module. * * To restrict to specific polls, pass in a jQuery object of the  * DOM node(s) below which to search for polls. By default, body * is used. * * @param jQuery|HTMLElement container * @return void
 */var Poll = function(container){
	// Add click listener to the relevant polls	var me = this;	var polls = $(container ? container : 'body').find('.poll-options').each(function(i, el)	{
		$(el).click(function(e) { me._optionClicked(e, $(this)); })
			 .parent().find('input').hide().parent('label').css({cursor:'pointer'});	});};/**
 * Handle clicks on the poll option. * * Check we clicked on an option, submit the AJAX post and * show the spinner. * * @param jQuery event * @param jQuery optionsUl options ul * @return void
 */Poll.prototype._optionClicked = function(event, optionsUl){
	if (event.target.tagName != 'LABEL' || $(event.target).children('input').attr('type') != 'radio') {		return false;	}	var clicked = $(event.target).children('input');

	// Ensure the chosen input is checked and submit the form	clicked.attr('checked', true);	var form = clicked.parents('form');		var me = this;	optionsUl.slideUp(200, function(){		me._optionsHidden(optionsUl);	});	$.post(location.href, form.serialize() + '&ajax=1', function(results)	{		me._response(optionsUl, results);	});};/**
 * Save results from POST response. * * @param jQuery poll div * @param string results HTML for results * @return void
 */Poll.prototype._response = function(poll, results){	var dom = $(results);	poll.data('results', dom.find('ul.poll-results').children());	this._showResultsWhenReady(poll);};/**
 * Flag the options as hidden when animation finishes. * * @param jQuery poll * @return void
 */Poll.prototype._optionsHidden = function(poll){	poll.data('hidden', true);	this._showResultsWhenReady(poll);};/**
 * Display results when ready. * * @param jQuery poll * @return void
 */Poll.prototype._showResultsWhenReady = function(poll){	if (poll.data('hidden') && poll.data('results')) {		poll.removeClass('poll-options').addClass('poll-results').html(poll.data('results')).slideDown();	}};

/**
 * Create a fancy gallery using the Galleriffic plugin.
 *
 * @param jQuery div
 * @return void
 */
var Gallery = function(div)
{
	$(div).hide();
	if ($.fn.galleriffic) {
		this.init(div);
	} else {
		var me = this;
		$.getScript(MEDIA_DIR + 'javascript/jquery.galleriffic.js', function() {
			$.getScript(MEDIA_DIR + 'javascript/jquery.history.js', function() {
				me.init(div);
			});
		});
		$('<link />').attr({
			type: 'text/css',
			rel: 'stylesheet',
			href: MEDIA_DIR + 'css/galleriffic.css'
		}).appendTo($('head')); 
	}
};
/**
 * Set up gallery when scripts have loaded.
 */
Gallery.prototype.init = function(div)
{
	// Keep track of how many galleries we've got so we can produce unique IDs
	if (typeof Gallery.counter == 'undefined') {
		Gallery.counter = 0;
	}
	var counter = Gallery.counter++;

	// Take out existing thumbs
	var contents = div.children().detach();
	this._div    = div;
	
	// Add extra divs for galleriffic
	this._controlsDiv  = $('<div class="gallery-controls" />').appendTo(div);
	this._loadingDiv   = $('<div class="gallery-loading" />').appendTo(div);
	this._slideshowDiv = $('<div class="gallery-slideshow" />').appendTo(div);
	this._captionDiv   = $('<div class="gallery-captions" />').appendTo(div);
	this._thumbsDiv    = $('<div class="gallery-thumbs navigation" />').appendTo(div);
	
	// Add page links
	this._firstPage    = $('<a class="pageLink first" href="#" title="First Page"></a>').appendTo(this._thumbsDiv);
	this._prevPage     = $('<a class="pageLink prev" href="#" title="Previous Page"></a>').appendTo(this._thumbsDiv);
	this._lastPage     = $('<a class="pageLink last" href="#" title="Last Page"></a>').appendTo(this._thumbsDiv);
	this._nextPage     = $('<a class="pageLink next" href="#" title="Next Page"></a>').appendTo(this._thumbsDiv);

	// Put thumbs back in right place
	contents.appendTo(this._thumbsDiv);

	// ID the new divs since galleriffic only takes selector strings
	this._controlsDiv.attr('id', 'gcontrols' + counter);
	this._loadingDiv.attr('id', 'gloading' + counter);
	this._slideshowDiv.attr('id', 'gslideshow' + counter);
	this._captionDiv.attr('id', 'gcaption' + counter);
	
	// Initialize
	var me = this;
	var gallery = this._thumbsDiv.galleriffic({
		delay:                     2500,
		numThumbs:                 8,
		preloadAhead:              5,
		enableTopPager:            false,
		enableBottomPager:         true,
		maxPagesToShow:            6,
		imageContainerSel:         '#gslideshow' + counter,
		controlsContainerSel:      '#gcontrols' + counter,
		captionContainerSel:       '#gcaption' + counter,
		loadingContainerSel:       '#gloading' + counter,
		renderSSControls:          true,
		renderNavControls:         true,
		playLinkText:              '',
		pauseLinkText:             '',
		prevLinkText:              '',
		nextLinkText:              '',
		nextPageLinkText:          '',
		prevPageLinkText:          '',
		enableHistory:             true,
		autoStart:                 false,
		syncTransitions:           true,
		defaultTransitionDuration: 900,
		pagePrevNext: 		       false,
		onPageTransitionOut:       function(callback) {
			this.fadeTo('fast', 0.0, callback);
		},
		onPageTransitionIn:        function() {
			this.fadeTo('fast', 1.0);
		}
	});
	
	// Create fullsize button
	this._fullsize = $('<a class="fs-control" href="#" title="View fullsize"></a>').insertAfter(this._slideshowDiv);
	this._fullsize.click(function(e) {
		$(this).attr({target: '_blank', href: gallery.currentImage.fullsize ? gallery.currentImage.fullsize : gallery.currentImage.slideUrl});
		gallery.pause();
	});

	// Make the page buttons work
	this._prevPage.click(function(e) {
		gallery.previousPage();
		e.preventDefault();
	});
	this._nextPage.click(function(e) {
		gallery.nextPage();
		e.preventDefault();
	});
	this._firstPage.click(function(e) {
		gallery.gotoIndex(0);
		e.preventDefault();
	});
	this._lastPage.click(function(e) {
		gallery.gotoIndex(gallery.find('li').length-1);
		e.preventDefault();
	});
	
	// Plug in to the history plugin and show the right image
	$.historyInit(function(hash) {
		if(hash) {
			$.galleriffic.gotoImage(hash);
		} else {
			gallery.gotoIndex(0);
		}
	});
	$("a[rel='history']").live('click', function(e) {
		if (e.button != 0) return true;
		var hash = this.href;
		hash = hash.replace(/^.*#/, '');
		$.historyLoad(hash);
		return false;
	});
	
	// Store galleriffic api
	this._div.data('galleriffic', gallery);
	
	// And show div
	this._div.show();
};

/**
 * Convert GMT times to local time zone.
 *
 * @param jQuery container defaults to body
 * @param string format see http://php.net/date
 * @return void
 */
var LocaliseTime = function(container, format)
{
	var format = format ? format : 'l jS F H:i';
	$(container ? container : 'body').find('span.localise-date').each(function(i, el) {
		var el   = $(el);
		var bits = el.attr('rel').match(/([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})\s+([0-9]{2}):([0-9]{2})/);
		var d    = new Date();
		d.setUTCFullYear(bits[1]);
		d.setUTCMonth(parseInt(bits[2])-1);
		d.setUTCDate(bits[3]);
		d.setUTCHours(bits[4]);
		d.setUTCMinutes(bits[5]);
		d.setUTCSeconds(0);
		
		var thisFormat  = el.attr('data-format') ? el.attr('data-format') : format;
		var currentText = el.html();
		var newText     = date(thisFormat, d.valueOf()/1000);
		var local       = '<span class="explain" title="Based on your computer\'s clock.">your time</span>';
		
		el.html(newText + ' ' + local + ' (' + currentText + ')');
	});
};
 

/**
 * Add social media buttons inside a given element.
 *
 * @param jQuery element
 * @param string url
 * @param string text
 * @return void
 */
var Shareable = function(element, url, text)
{
	// Save parameters
	this._container = element;
	this._url 		= url;
	this._text		= text;
	
	// Create share button
	this._shareButton = $('<div class="gn-social" />').css({
		width: '24px', 
		height: '24px', 
		backgroundImage: 'url(' + MEDIA_DIR + 'images/share/share.png)',
		backgroundRepeat: 'no-repeat',
		backgroundPosition: '0 -24px',
		position: 'relative',
		cursor: 'pointer',
	}).attr('title', 'Share').appendTo(this._container);
	
	// Fade in on mouseover
	this._shareButton.mouseover(function(e) {
		if (e.target==this)
			$(this).css({backgroundPosition: '0 0'});
	}).mouseout(function(e) {
		if (e.target==this)
			$(this).css({backgroundPosition: '0 -24px'});
	});
	
	// Attach instance to the control element
	this._shareButton.data('Shareable', this);
	
	// Create platform buttons as static property (never need more than one of these)
	if (!Shareable._platformsDiv) {
		var div = $('<div />').css({
			position:'absolute', 
			overflow:'hidden', 
			zIndex:10000, 
			top: '4px', 
			height: '16px'
		});
		this._twitter = this._createButton('twitter', 'Twitter').css({float: 'left'}).appendTo(div);
		this._facebook = this._createButton('facebook', 'Facebook').css({float: 'left'}).appendTo(div);
		this._reddit = this._createButton('reddit', 'Reddit').css({float: 'left'}).appendTo(div);
		this._plus = this._createButton('google', 'Google+').css({float: 'left'}).appendTo(div);
		
		var clickHandler = function(){Shareable.share($(this));};
		this._twitter.click(clickHandler);
		this._facebook.click(clickHandler);
		this._reddit.click(clickHandler);
		this._plus.click(clickHandler);
		
		Shareable._platformsDiv = div;
	}
	
	// Create a handler for closing this div
	var closeHandler = function(e)
	{
		var target = $(e.target);
		if (!target.hasClass('gn-social') && !target.parents('.gn-social')[0]) {
			Shareable._platformsDiv.hide();
			$(window).unbind('click', closeHandler);
		}
	};
	
	// Show platforms on click
	this._shareButton.click(function(e) {
		var over = $(this);
		var div  = Shareable._platformsDiv;
		if (div.parent()[0] == over[0] && div.is(':visible')) {
			if (e.target == this) {
				Shareable._platformsDiv.hide();
			}
			return;
		}
		div.hide().appendTo(over).css({
			width: 0,
			left: 0
		}).show().animate({
			width: '84px', 
			left: '-89px'
		});
		$(window).bind('click', closeHandler);
	});
};
/**
 * Create a button
 *
 * @ignore
 * @param string icon
 * @param string title
 * @return jQuery
 */
Shareable.prototype._createButton = function(icon, title)
{
	if (!title) {
		var title = '';
	}
	return $('<div />').css({
		width: '16px', 
		height: '16px', 
		backgroundImage: 'url(' + MEDIA_DIR + 'images/share/' + icon + '.png)',
		backgroundRepeat: 'no-repeat',
		cursor: 'pointer',
		marginLeft: '5px'
	}).attr('title', title);
};
/**
 * Share!
 *
 * @param jQuery clicked
 * @return void
 */
Shareable.share = function(clicked)
{
	var instance = clicked.parents('.gn-social').data('Shareable');
	if (!instance) {
		return false;
	}
	var url  = encodeURIComponent(instance._url);
	var text = encodeURIComponent(instance._text);
	
	var share = function(url, x, y)
	{
		var x = x ? x : 400;
		var y = y ? y : 400;
		var top = ((screen.height - y) / 2) - 50;
		var left = (screen.width - x) / 2;
		var win = window.open(url, 'share', 'scrollbars=1,menubar=0,toolbar=0,width=' + x + ',height=' + y + ',top=' + top + ',left=' + left);
		win.focus();
	};
	
	switch (clicked.attr('title')) {
		case 'Twitter':
			var tweetUrl = 'https://twitter.com/share?url=' + url + '&related=gtanet&via=gtanet&text=' + text + encodeURIComponent(' #GTAV');
			share(tweetUrl, 500, 300);
			break;
			
		case 'Facebook':
			var faceUrl = 'http://www.facebook.com/sharer/sharer.php?u=' + url + '&t=' + text;
			share(faceUrl, 500, 300);
			break;
		
		case 'Reddit':
			var redUrl = 'http://www.reddit.com/submit?url=' + url;
			share(redUrl, 900, 500);
			break;
			
		case 'Google+':
			var gooUrl = 'https://plusone.google.com/_/+1/confirm?hl=en&url=' + url;
			share(gooUrl, 500, 300);
			break;
	}
};
/**
 * Make members public.
 */return {	Poll:    Poll,
	Gallery: Gallery,
	LocaliseTime: LocaliseTime,
	Shareable: Shareable};})();

/**
 * date() from php.js
 */
function date(format,timestamp){var that=this,jsdate,f,formatChr=/\\?([a-z])/gi,formatChrCb,_pad=function(n,c){if((n=n+'').length<c){return new Array((++c)-n.length).join('0')+n;}
return n;},txt_words=["Sun","Mon","Tues","Wednes","Thurs","Fri","Satur","January","February","March","April","May","June","July","August","September","October","November","December"];formatChrCb=function(t,s){return f[t]?f[t]():s;};f={d:function(){return _pad(f.j(),2);},D:function(){return f.l().slice(0,3);},j:function(){return jsdate.getDate();},l:function(){return txt_words[f.w()]+'day';},N:function(){return f.w()||7;},S:function(){var j=f.j();return j>4||j<21?'th':{1:'st',2:'nd',3:'rd'}[j%10]||'th';},w:function(){return jsdate.getDay();},z:function(){var a=new Date(f.Y(),f.n()-1,f.j()),b=new Date(f.Y(),0,1);return Math.round((a-b)/864e5)+1;},W:function(){var a=new Date(f.Y(),f.n()-1,f.j()-f.N()+3),b=new Date(a.getFullYear(),0,4);return _pad(1+Math.round((a-b)/864e5/7),2);},F:function(){return txt_words[6+f.n()];},m:function(){return _pad(f.n(),2);},M:function(){return f.F().slice(0,3);},n:function(){return jsdate.getMonth()+1;},t:function(){return(new Date(f.Y(),f.n(),0)).getDate();},L:function(){return new Date(f.Y(),1,29).getMonth()===1|0;},o:function(){var n=f.n(),W=f.W(),Y=f.Y();return Y+(n===12&&W<9?-1:n===1&&W>9);},Y:function(){return jsdate.getFullYear();},y:function(){return(f.Y()+"").slice(-2);},a:function(){return jsdate.getHours()>11?"pm":"am";},A:function(){return f.a().toUpperCase();},B:function(){var H=jsdate.getUTCHours()*36e2,i=jsdate.getUTCMinutes()*60,s=jsdate.getUTCSeconds();return _pad(Math.floor((H+i+s+36e2)/86.4)%1e3,3);},g:function(){return f.G()%12||12;},G:function(){return jsdate.getHours();},h:function(){return _pad(f.g(),2);},H:function(){return _pad(f.G(),2);},i:function(){return _pad(jsdate.getMinutes(),2);},s:function(){return _pad(jsdate.getSeconds(),2);},u:function(){return _pad(jsdate.getMilliseconds()*1000,6);},e:function(){throw'Not supported (see source code of date() for timezone on how to add support)';},I:function(){var a=new Date(f.Y(),0),c=Date.UTC(f.Y(),0),b=new Date(f.Y(),6),d=Date.UTC(f.Y(),6);return 0+((a-c)!==(b-d));},O:function(){var a=jsdate.getTimezoneOffset();return(a>0?"-":"+")+_pad(Math.abs(a/60*100),4);},P:function(){var O=f.O();return(O.substr(0,3)+":"+O.substr(3,2));},T:function(){return'UTC';},Z:function(){return-jsdate.getTimezoneOffset()*60;},c:function(){return'Y-m-d\\Th:i:sP'.replace(formatChr,formatChrCb);},r:function(){return'D, d M Y H:i:s O'.replace(formatChr,formatChrCb);},U:function(){return jsdate.getTime()/1000|0;}};this.date=function(format,timestamp){that=this;jsdate=((typeof timestamp==='undefined')?new Date():(timestamp instanceof Date)?new Date(timestamp):new Date(timestamp*1000));return format.replace(formatChr,formatChrCb);};return this.date(format,timestamp);}
