/*!
 * Social network + bookmarking tools
 * Copyright 2009 Mark. Sydney :: www.mark.com.au :: All Rights Reserved *
 */
/*
 	                          __
	 /'\_/`\                 /\ \
	/\      \    __      _ __\ \ \/'\
	\ \ \__\ \  /'__`\  /\`'__\ \ , <
	 \ \ \_/\ \/\ \_\.\_\ \ \/ \ \ \\`\   __
	  \ \_\\ \_\ \__/.\_\\ \_\  \ \_\ \_\/\_\
	   \/_/ \/_/\/__/\/_/ \/_/   \/_/\/_/\/_/

 * Author: Gilmore Davidson
--------------------------------------------------------------------------*/

(function (){
	var window = this,
		windowName = Math.random(1000).toString().slice(3),
		doc = document,
		loc = location,
		enc = encodeURIComponent,
		now = new Date().getTime(),
		social;

	// Default settings
	var socialOps = {
		// URL to add: can be empty (uses current URL), a string (hardcoded URL) or a callback function that returns a URL
		url: '',
		// Title of page: can be empty (uses current page title), a string (hardcoded title) or a callback function that returns a title
		title: '',
		// Description of page: can be a string (hardcoded description) or a callback function that returns a description
		description: '',
		// Default message for Twitter, can be a string or a callback function that returns a message
		twitterMessage: '',
		// Method used to open the social network, can be 'popup', 'iframe' or a callback function
		method: 'popup',
		// jQuery selector that contains the iframe
		iframeHolder: 'body',
		// ID to give the iframe
		iframeId: '',
		// Function used to show the iframe, can be a jQuery function name or a callback function
		iframeEffect: 'slideDown',
		// URL used to generate custom links instead of going straight to the social network
		proxyUrl: '',
		// Track the click with Google Analytics
		gaTrackEvent: false
	};

	function isUndefined(variable) {
		return typeof variable === 'undefined';
	}

	function isFunction(variable) {
		return typeof variable === 'function';
	}

	function getUrl(extra) {
		var u = '';
		if (isFunction(socialOps.url)) {
			u = socialOps.url.apply(this, extra);
		} else if ('' !== socialOps.url) {
			u = socialOps.url;
		} else {
			u = loc.href;
		}
		return enc(u);
	}

	function getTitle(extra) {
		var t = '';
		if (isFunction(socialOps.title)) {
			t = socialOps.title.apply(this, extra);
		} else if ('' !== socialOps.title) {
			t = socialOps.title;
		} else {
			t = doc.title;
		}
		return enc(t);
	}

	function getDescription(extra) {
		var desc = '';
		if (isFunction(socialOps.description)) {
			desc = socialOps.description.apply(this, extra);
		} else if ('' !== socialOps.description) {
			desc = socialOps.description;
		}
		return enc(desc);
	}

	function getMessage(extra) {
		var msg = '';
		if (isFunction(socialOps.twitterMessage)) {
			msg = socialOps.twitterMessage.apply(this, extra);
		} else if ('' !== socialOps.twitterMessage) {
			msg = socialOps.twitterMessage;
		}
		return enc(msg);
	}

	function openWindow(url, name, width, height) {
		name += '_' + windowName;
		var w = window.open(url, name, 'toolbar=0,status=0,resizable=1,scrollbars=1,location=0,width=' + width + ',height=' + height);
		if (!w) {
			alert('Sorry, could not open a popup to add this page to your profile.');
			return;
		}
		try {
			var wx = screen.width / 2 - width / 2,
				wy = screen.height / 2 - height / 2;
			w.moveTo(wx, wy);
		} catch (e) {}
	}

	// This requires jQuery!
	function buildIframe(url, width, height) {
		var id = socialOps.iframeId,
			holder = socialOps.iframeHolder,
			effect = socialOps.iframeEffect,
			useEffect = false,
			elem;
		// Check that jQuery exists
		if (isUndefined(jQuery)) {
			alert('jQuery object not found!');
			return;
		}
		// Create iframe if it doesn't already exist
		elem = $('#' + id);
		if (!elem.length) {
			elem = $('<iframe/>').attr('id', id).hide().appendTo(holder);
			useEffect = true;
		}
		// Set iframe dimensions
		if (elem.width() != width) {
			elem.width(width);
		}
		if (elem.height() != height) {
			elem.height(height);
		}
		// Set the source URL
		elem.attr('src', url);
		// Show the iframe if needed
		if (useEffect) {
			if (isFunction(effect)) {
				effect();
			} else {
				elem[effect]();
			}
		}
	}

	function buildProxyParams(extra) {
		return [
			'u=' + getUrl(extra),
			't=' + getTitle(extra),
			'd=' + getDescription(extra),
			'm=' + getMessage(extra),
			'tc=' + socialOps.twitterTrackCode
		].join('&');
	}

	function buildQueryString(params, extra) {
		var query = [];
		if (!isUndefined(params.url)) {
			query.push(params.url + '=' + getUrl(extra));
		}
		if (!isUndefined(params.title)) {
			query.push(params.title + '=' + getTitle(extra));
		}
		if (!isUndefined(params.description)) {
			query.push(params.description + '=' + getDescription(extra));
		}
		if (!isUndefined(params.message)) {
			query.push(params.message + '=' + getMessage(extra));
		}
		return query.join('&');
	}

	function socialise(network, url, params, width, height, extra) {
		var proxy = socialOps.proxyUrl,
			method = socialOps.method,
			fullurl = (proxy.length)
			?
				proxy
				+ network
				+ ((proxy.indexOf('?') > -1) ? '&' : '?')
				+ buildProxyParams(extra)
			:
				url
				+ ((url.indexOf('?') > -1) ? '&' : '?')
				+ buildQueryString(params, extra);
		if (isFunction(method)) {
			method.call(this, network, fullurl, width, height, socialOps, extra);
		} else if ('popup' == method || !isUndefined(params.popupOnly)) {
			openWindow(fullurl, network, width, height);
		} else if ('iframe' == method) {
			buildIframe(fullurl, width, height);
		}
		// Google Analytics event tracking
		if (socialOps.gaTrackEvent && typeof pageTracker !== undefined) {
			pageTracker._trackEvent('SocialMedia', network);
		}
	}

	// This sets up the actual object
	window.social = social = {
		setOptions: function (options) {
			for (var i in options) {
				if (options.hasOwnProperty(i)) {
					socialOps[i] = options[i];
				}
			}
		},
		facebook: function () {
			var url = 'http://www.new.facebook.com/sharer.php?src=bm&v=4&i=' + now,
				params = {
					url: 'u',
					title: 't'
				};
			socialise('facebook', url, params, 626, 436, arguments);
		},
		myspace: function () {
			var url = 'http://www.myspace.com/Modules/PostTo/Pages/',
				params = {
					url: 'u',
					title: 't',
					description: 'c',
					popupOnly: true
				};
			socialise('myspace', url, params, 800, 740, arguments);
		},
		twitter: function () {
			var url = 'http://twitter.com/home',
				params = {
					message: 'status'
				};
			socialise('twitter', url, params, 800, 600, arguments);
		},
		delicious: function () {
			var url = 'http://delicious.com/save',
				params = {
					url: 'url',
					title: 'title',
					description: 'notes'
				};
			socialise('delicious', url, params, 842, 630, arguments);
		},
		digg: function () {
			var url = 'http://digg.com/submit?phase=2',
				params = {
					url: 'url',
					title: 'title'
				};
			socialise('digg', url, params, 945, 665, arguments);
		},
		stumbleupon: function () {
			var url = 'http://www.stumbleupon.com/submit',
				params = {
					url: 'url',
					title: 'title',
					popupOnly: true
				};
			socialise('stumbleupon', url, params, 800, 600, arguments);
		},
		blogger: function () {
			var url = 'http://www.blogger.com/blog_this.pyra',
				params = {
					url: 'u',
					title: 'n',
					description: 't'
				};
			socialise('blogger', url, params, 475, 300, arguments);
		}
	};
})();
