// Can be used with fb or twitter
var BaseFriend = new Class({
	initialize: function (userName, userId, photoURL) {
		this.userName = userName;
		this.userId   = userId;
		this.photoURL = photoURL;
	}
});


var FacebookFriend = new Class({
	Extends: BaseFriend,
	initialize: function (responseItem) {
		this.parent(
			responseItem.name,
			responseItem.id,
			'http://graph.facebook.com/' + responseItem.id + '/picture'
		);
	}
});

var TwitterFollower = new Class({
	Extends: BaseFriend,
	initialize: function (responseItem) {
		this.parent(
			responseItem.n,
			responseItem.n,
			responseItem.p
		);
	}
});

var Recipient = new Class({
	initialize: function (friend, videoId, message) {
		this.friend       = friend;
		this.videoId      = videoId;
		this.message      = message;
		this.sendStatus   = null;
		this.sendResponse = null;
	}
});

var BaseSocial = new Class({
	Implements: Events,
	initialize: function () {
		this.baseURL           = environment.baseUrl;
		this.friends           = [];
		this.isLoggedIn        = false;
		this.retrievedFriends  = false;     
		this.currRecipientList = [];
	},
	getSendStatusMessage: function () {
		var srnd  = SocialConnect.getSerenadeFromId(this.currRecipientList[0].videoId),
			title = srnd.title,
			i,
			rec,
			mess    = "",
			success = [],
			fail    = [];
			
		if (this.currRecipientList[0].sendStatus === "error") {
			// Send permissions were revoked
			if (this.currRecipientList[0].sendResponse.message.indexOf("#200") > -1) {
				mess = "Your privacy settings may have blocked sending a serenade. Try sending this URL instead: " + srnd.longurl;
				return mess;
			}
		}
			
		for (i = 0; i < this.currRecipientList.length; i++) {
			rec = this.currRecipientList[i];
			
			if (rec.sendStatus !== 'error') {
				success.push(rec.friend.userName);
			} else {
				fail.push(rec.friend.userName);
			}
		}
		
		if (success.length > 0) {
			mess = "“" + title + "” was successfully sent to ";
		} else {
			mess += "There was an error sending “" + title + "” to ";
		}
		
		for (i = 0; i < success.length; i++) {
			mess += success[i];
			
			if (i === success.length - 1) {
				mess += ".";
			} else if (i === success.length - 2) {
				mess += ", and ";
			} else {
				mess += ", ";
			}
		}
		
		if (fail.length === 0) {
			mess += " Congratulations, you just sweetened their day.";
		} else {
			if (success.length !== 0) {
				mess += " There was an error sending to ";
			}
			
			for (i = 0; i < fail.length; i++) {
				mess += fail[i];
				
				if (i === fail.length - 1) {
					mess += ".";
				} else if (i === fail.length - 2) {
					mess += " and ";
				} else {
					mess += ", ";
				}
			}
			
			if (fail.length > 1) {
				mess += " Those recipients’";
			} else {
				mess += " That recipient’s";
			}
			
			mess += " privacy settings may have blocked your serenade. Send them this URL instead: " + srnd.longurl;
		}
		
		return mess;
	}
});

var Facebook = new Class({
	Extends: BaseSocial,
	initialize: function () {
		this.parent();
		
		this.appId               = environment.appId; 
		this.appURL              = environment.appUrl;
		this.requiredPermissions = 'read_stream, publish_stream';
		this.isRequestingLogIn   = false;
		this.isConnected         = false;
		this.currRecipientIndex  = 0;
		this.me                  = null;
	},
	initAPI: function () {
		// Async load the fb js file.
		var e    = document.createElement('script'),
		    that = this;
		
		e.async = true;
		e.src   = 'http://connect.facebook.net/en_US/all.js';
		$('fb-root').appendChild(e);
		
		window.fbAsyncInit = function () {
			that.onInit();
			
			FB.Event.subscribe('auth.login', function (response) {
				
			});
			
			FB.Event.subscribe('auth.logout', function (response) {
				that.isConnected      = false;
				that.isLoggedIn       = false;
				that.retrievedFriends = false;
			});
			
			FB.init({
				appId: that.appId,
				//status: true, // check login status
				cookie: true
			});
			FB.Canvas.setSize({width: 760, height: 1000});
		};
	},
	onInit: function () {
		$(document.body).addClass('fb-load');
	},
	login: function () {
		// disabled as facebook never calls back on window close
		if (this.isRequestingLogIn) {

			return;
		}
		
		//this.isRequestingLogIn = true;
		
		// Logged in, connected, no friends yet
		if (this.isLoggedIn && this.isConnected && !this.retrievedFriends) {

			this.buildFriendList();
			return;
		}
		if (!this.isLoggedIn) {
			// Not logged? get status
			var that = this;

			FB.getLoginStatus(function (response) {
				that.onGetLoginStatus(response);
			});
		} else {

			this.connect();
		}
	},
	logout: function () {
		FB.logout(function (response) {
			/*if (response.session) {
			// user successfully logged in
			} else {
			// user cancelled logged
			}*/
		});
	},
	connect: function () {
		var that = this;
		
		FB.login(function (response) {
			if (response.session) {
				that.isLoggedIn   = true;
				that.isConnected  = true;
				if (response.perms) {
					that.buildFriendList();
					
					// user is logged in, but did not grant any permissions
				} else {
					that.isRequestingLogIn = false;
				}
			} else {
				that.isRequestingLogIn = false;
				this.isLoggedIn        = false;
			}
		}, {perms: that.requiredPermissions});
	},
	onGetLoginStatus: function (response) {

		if (response.session) {
			this.isLoggedIn = true;
		}
		
		if (response.status === "connected") {
			this.isConnected = true;
			this.buildFriendList();
			
			// Not connected, trigger login
		} else {
			this.connect();
		}
	},
	buildFriendList: function () {
		var that = this;
		
		// First get you
		if (!this.me) {
			this.getMe();
			return;
		}
		
		FB.api('/me/friends', function (response) {
			var fr,
			    i;
			
			that.isRequestingLogIn = false;
			
			if (!response || response.error) {
				// Error
			} else {
				that.friends = [];
				
				for (i = 0; i < response.data.length; i++) {
					fr = new FacebookFriend(response.data[i]);
					that.friends.push(fr);
				}
				
				SocialConnect.alphaSortFriends(that.friends);
				
				that.retrievedFriends = true;
				that.fireEvent('loggedIn');
			}
		});
	},
	getMe: function () {
		var that = this;
		
		FB.api('me', function (response) {
			that.onGetMe(response);
		});
	},
	onGetMe: function (resp) {
		if (!resp || resp.error) {
			// Error
		} else {
			this.me = resp;
			// Continue building
			this.buildFriendList();
		}
	},
	// User id can be "me" to post on site user's wall
	sendSerenadeToRecipient: function (recipient) {
		var that         = this,
		    srnd         = SocialConnect.getSerenadeFromId(recipient.videoId),
		    uid          = recipient.friend.userId,
		    message,
		    graphAttribs;
		
		if (recipient.message === null) {
			// Replace sender and recipt
			message = srnd.fbmessage.replace("{s}", this.me.name).replace("{r}", recipient.friend.userName);
		} else {
			message = recipient.message;
		}
		
			/*
		var theLink = that.appURL + "?id=" + recipient.videoId;
		graphAttribs = {
			message: message,
			picture: 'http://www.serenadingunicorn.com/' + srnd.fbthumb,
			link: that.appURL + "?id=" + recipient.videoId,
			name: srnd.title,
			actions: {"name": "Facebook App", "link": theLink},
			caption: "Wallpost Serenade from Serenading Unicorn",
			description: srnd.fbdescription
		};
	
		source: 'http://www.serenadingunicorn.com/' + "media/swf/UnicornVideoPlayer.swf?videoid=" + recipient.videoId + "&locid=fb",
		*/
		graphAttribs = {
			message: message,
			picture: that.baseURL + srnd.fbthumb,
			source: that.baseURL + "media/swf/UnicornVideoPlayer.swf?videoid=" + recipient.videoId + "&locid=fb",
			link: that.appURL + "?id=" + recipient.videoId,
			name: srnd.title,
			caption: "Wallpost Serenade from Serenading Unicorn",
			description: srnd.fbdescription
		};
		
		
		
		FB.api('/' + uid + '/feed', 'post', graphAttribs, function (response) {
			
			var sendStatus,
			    sendResponse;
			
			if (!response || response.error) {
				sendStatus   = 'error';
				sendResponse = response.error;
			} else {
				sendStatus   = 'success';
				sendResponse = null;
			}
			
			that.onSendSerenadeToRecipient(sendStatus, sendResponse);
		});
	},
	onSendSerenadeToRecipient: function (sendStatus, sendResponse) {
		var recipient = this.getCurrRecipient();
		
		recipient.sendStatus   = sendStatus;
		recipient.sendResponse = sendResponse;
		
		this.currRecipientIndex++;
		
		if (this.currRecipientIndex === this.currRecipientList.length) {
			Tracking.sendFB(this.currRecipientList.length);
			
			this.fireEvent('sendComplete');
		} else {
			this.sendNextRecipient();
		}
	},
	// Pass an array of recipient items
	sendRecipientList: function (recipientList) {
		this.currRecipientList  = recipientList;
		this.currRecipientIndex = 0;
		
		this.sendNextRecipient();
	},
	sendNextRecipient: function () {
		this.sendSerenadeToRecipient(this.getCurrRecipient());
	},
	getCurrRecipient: function () {
		return this.currRecipientList[this.currRecipientIndex];
	}
});

var Twitter = new Class({
	Extends: BaseSocial,
	initialize: function () {
		this.parent();
	},
	login: function () {
		if (this.isLoggedIn) {
			return;
		}
		
		var that = this;
		
		window.onTwitterMessage = function (e) {
			that.onTwitterMessage(e);
		};
		
		window.open(this.baseURL + 'twitter-auth.php', '_blank', 'width=808,height=423,location=0,menubar=0,scrollbars=1,status=1,toolbar=0,resizable=1');
	},
	onTwitterMessage: function (e) {
		this.isLoggedIn = true;
		this.friends    = [];
		
		var data = JSON.decode(e.data),
		    fw,
		    i;
		
		for (i = 0; i < data.length; i++) {
			fw = new TwitterFollower(data[i]);
			this.friends.push(fw);
		}
		
		this.retrievedFriends = true;
		
		SocialConnect.alphaSortFriends(this.friends);
		this.fireEvent('loggedIn');
	},
	sendRecipientList: function (recipientList) {
		this.currRecipientList = recipientList;
		
		var json = [],
		    that = this,
		    recip,
		    req,
		    srnd,
		    msg,
		    i;
		
		for (i = 0; i < recipientList.length; i++) {
			recip = recipientList[i];
			srnd  = SocialConnect.getSerenadeFromId(recip.videoId);
			
			if (recip.message === null) {
				msg = "I just sweetened @" + recip.friend.userId + "’s day with a Wallpost Serenade by Serenading Unicorn " + srnd.shorturl;
			} else { 
				msg = "@" + recip.friend.userId + " " + recip.message + " " + srnd.shorturl;
			}
			
			json.push({
				uid: recip.friend.userId,
				vid: recip.videoId,
				mess: msg
			});
		}
		
		req = new Request({
			url: this.baseURL + 'twitter-auth.php',
			method: 'post',
			data: 'rec=' + JSON.encode(json),
			onSuccess: function (responseText) {
				Tracking.sendTW(that.currRecipientList.length);
				
				that.fireEvent('sendComplete');
			}
		});
		
		req.send();
	}
});

var SocialConnect      = {};
SocialConnect.facebook = new Facebook();
SocialConnect.twitter  = new Twitter();

SocialConnect.alphaSortFriends = function (friendList) {
	friendList.sort(function (friendA, friendB) {
		if (friendA.userName.toUpperCase() === friendB.userName.toUpperCase()) {
			return 0;
		}
		
		return (friendA.userName.toUpperCase() > friendB.userName.toUpperCase()) ? 1 : -1;
	});
};

SocialConnect.getRandomSerenade = function () {
	var	networks = [];
	
	if (SocialConnect.facebook.isLoggedIn) {
		networks.push({n: 'facebook', f: SocialConnect.facebook.friends});
	}
	
	if (SocialConnect.twitter.isLoggedIn) {
		networks.push({n: 'twitter', f: SocialConnect.twitter.friends});
	}
	
	var randVideo = serenadesData.getRandom(),
		randNet   = networks.getRandom(),
	    recipient = new Recipient(randNet.f.getRandom(), randVideo.videoId);
	
	return {network: randNet.n, slide: randVideo.slide, title: randVideo.title, recipient: recipient};
};

SocialConnect.getSerenadeFromId = function (videoId) {
	var i;
	
	for (i = 0; i < serenadesData.length; i++) {
		if (serenadesData[i].videoId === videoId) {
			return serenadesData[i];
		}
	}
	
	return null;
};
