// FwpConnect API
// Configured to use 1 or more network adapter classes (currently only FacebookAdapter is implemented)
// Configured to use 1 handler handle communication with registration server
// Remote handler depends on JQuery library for ajax call

FwpConnect = {

	init: function() {
		// create adapters for each network
		FwpConnect.adapters = {};
		var facebook = FwpConnect.networks.facebook;
		if (facebook) {
			FwpConnect.adapters.facebook = new FwpConnect.FacebookAdapter(facebook);
		}
	},
	
	connect: function(networkName, callback) {
		FwpConnect.adapters[networkName].connect(callback);
	},
	
	logout: function(callback) {
		// get total count of networks
		var networkCount = 0;
		for (name in FwpConnect.adapters) {
			networkCount++;
		}
		
		// log out of each
		var logoutCount = 0;
		for (name in FwpConnect.adapters) {
			FwpConnect.adapters[name].logout(function(network) {
				// when ALL adapters have completed logout, invoke callback
				logoutCount++;
				//alert('logged out of ' + network + ', ' + logoutCount + '/' + networkCount);
				if (logoutCount == networkCount) {
					//alert('invoking ' + callback);
					callback();
				}
			});
		}
	},
	
	// Delete network cookies without actually logging user out of networks.
	// Synchronous; no callback
	logoutInternal: function() {
	    //alert('FwpConnect.logoutInternal');
		for (name in FwpConnect.adapters) {
			FwpConnect.adapters[name].logoutInternal();
		}
	},
	
	// only call this if the user is logged in and network logged out
	// in that case will check if the user has a linked network account
	getLinkStatus: function(networkName, callback) {
		this.adapters[networkName.toLowerCase()].getLinkStatus(callback);
	},
	
	logError: function(network, action, message) {
		FwpConnect.handler.logError(network, action, message);
	},

	// private functions
	setCookie: function(name,value,expires,path,domain,secure,escapeVal){
		var cookie = name + "=" + ( (escapeVal) ? escape( value ) : value )+
		( ( expires ) ? ";expires=" + expires.toGMTString() : "" ) +
		( ( path ) ? ";path=" + path : "" ) +
		";domain=" + FwpConnect.cookieDomain +
		( ( secure ) ? ";secure" : "" );
		//alert("set cookie " + cookie);
		document.cookie = cookie;
	},
	
	deleteCookie: function(name) {
		FwpConnect.setCookie(name, '', new Date(), "/");
	}
	
};


/////////////////////////////////////////////////////////////////////
// Facebook Adapter /////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////

FwpConnect.FacebookAdapter = function(config) {
	this.networkName = "Facebook";
	for (var name in config) {
		this[name] = config[name];
	}
	var thisRef = this; // handle this scope change in nested functions
	try {
		FB.init(this.apiKey, this.xdReceiverUri, {
			ifUserConnected: function(uid) {
				FB.Facebook.get_sessionState().waitUntilReady( function() {
					if (!thisRef.loggedIn) {
						thisRef.login(uid);
					}
				});				
			}, 
			ifUserNotConnected: function() {
				if( FwpConnect.product == 'iwon' ) {
					//if user is not connected do something here for iwon?
				} else {
					if (thisRef.loggedIn) {
						thisRef.logoutInternal();
						thisRef.onDisconnect(thisRef.networkName);
					}
				}
			}
		});
	}
	catch (exception) {
		FwpConnect.logError("Facebook", "init", exception.message || exception);
	} 
};

FwpConnect.FacebookAdapter.prototype.connect = function(callback) {
	this.tempOnLogin = callback;
	try {
		FB.ensureInit ( function (exception) {
			if(exception) {
				FwpConnect.logError("Facebook", "FB.connect:ensureInit", exception);
			}
			try {
				FB.Connect.requireSession();
			}
			catch (exc) {
				FwpConnect.logError("Facebook", "requireSession", exc.message || exc);
			}
		});
	}
	catch (exc) {
		FwpConnect.logError("Facebook", "connect:ensureInit", exc.message || exc);
	}
};

FwpConnect.FacebookAdapter.prototype.login = function(uid) {
	// Cookie status is stale, log in user with facebook info
	var fields = 'birthday,sex,name,first_name,last_name,pic_square_with_logo,pic';
	var thisRef = this;
	try {
		FB.Facebook.apiClient.users_getInfo(uid, fields, function(result, exception) {
			if (exception) {
				FwpConnect.logError("Facebook", "FB.login:usersGetInfo", exception);
			} else {
				//moved logged state change inside the success callback function and we only need to set it once
				thisRef.loggedIn = FwpConnect.networks.facebook.loggedIn = true;
				
				var userInfo = result[0];
				var params = {
					product: FwpConnect.product,
					network: thisRef.networkName,
					networkUserId: uid,
					birthday: userInfo.birthday,
					gender: userInfo.sex.toUpperCase(),
					displayName: userInfo.name,
					firstName: userInfo.first_name,
					lastName: userInfo.last_name,
					photoUrlSmall: userInfo.pic_square_with_logo,
					photoUrl: userInfo.pic
				};
				// workaround due to fact that same callback is invoked by facebook
				// for initial connected status and user connect action, but we need
				// to invoke different callback handler for apps
				FwpConnect.fbUserInfo = params;
				var onLogin = thisRef.tempOnLogin;
				if (onLogin) {
					thisRef.tempOnLogin = null;
				} else {
					onLogin = thisRef.onLogin;
				}
				if( FwpConnect.product != 'zwinky' ) { 
					FwpConnect.handler.networkLogin(params, function(isFirstTime) {
						onLogin(params, isFirstTime);
					});
				} else {
					onLogin();
				}
				if( FwpConnect.product == 'iwon' ) {
					if(typeof launchGameObject != "undefined") {
						urchinTracker("/clicks/fbconnect/gameplayer/login/"+ launchGameObject.gameId + "/" + launchGameObject.signedIn );
					} else {
						urchinTracker("/clicks/fbconnect/pick7Invite/login");
					}
				}
			}
		});
	}
	catch (exc) {
		FwpConnect.logError("Facebook", "login:usersGetInfo", exc.message || exc);
	} 
};

// facebook status is already logged out, need to delete the cookie and invoke callback
FwpConnect.FacebookAdapter.prototype.logoutInternal = function() {
	//alert('logoutInternal');

	// set loggedin flag
	this.loggedIn = false;
	
	// call handler which will delete cookie
	// call is syncrhonous, no callback
	FwpConnect.handler.networkLogout(this.networkName);
};

// user initiates logout, make facebook api call to log out
FwpConnect.FacebookAdapter.prototype.logout = function(callback) {
		
	var thisRef = this;
	try {
		FB.ensureInit ( function (exception) {
			if (exception) {
				FwpConnect.logError("Facebook", "FB.logout:ensureInit", exception);
			}
			if (thisRef.loggedIn) {
				// Log out of facebook
				try {
					FB.Connect.logout(function(complete, exception) {
						if (exception) {
							FwpConnect.logError("Facebook", "FB.logout", exception);
						}
						if (complete) {
							thisRef.logoutInternal();
							callback(thisRef.networkName);
						}
					});
				}
				catch (exc) {
					FwpConnect.logError("Facebook", "logout", exc.message || exc);
				}
			} else {
				// If not logged in to facebook then need to invoke callback now
				callback(thisRef.networkName);
			}
		}); 
	}
	catch (exc) {
		FwpConnect.logError("Facebook", "logout:ensureInit", exc.message || exc);
	}
};

FwpConnect.FacebookAdapter.prototype.getLinkStatus = function(callback) {
	if( FwpConnect.product != 'zwinky' ) {
		if (this.loggedIn) {
			callback();
		} else if (this.isLinked) {
			callback(this.isLinked);
		} else {
			var thisRef = this;
			FwpConnect.handler.getLinkStatus(this.networkName, function(isLinked) {
				thisRef.isLinked = isLinked;
				callback(isLinked);
			});
		}
	} else {
		var thisRef = this;
		FwpConnect.handler.getLinkStatus(this.networkName, function(sData) {
			thisRef.isLinked = sData.isLinked;
			thisRef.hasMatch = sData.hasMatch || false;
			thisRef.isZwinkyLinked = sData.isZwinkyLinked || false;
			thisRef.linkedNetworkId = sData.linkedNetworkId || 0;
			callback(sData);
		});
	}
}

////////////////////////////////////////////////////////////////////////////////
// Remote Handler  /////////////////////////////////////////////////////////////
// This is used to handle remote ajax calls and cookie management,
// Other handlers could be substituted - use FwpConnect.handler = <your handler>
////////////////////////////////////////////////////////////////////////////////

FwpConnect.RemoteHandler = function() {
	this.remoteHost = '';
};

FwpConnect.RemoteHandler.prototype.networkLogin = function(params, onLogin) {
	var thisRef = this;
	if( FwpConnect.product != 'iwon' ) {
		$.post(this.remoteHost + "/networkLogin.jhtml", params, function (data, status) {
			if (status == "success") {
				// parse JSON response
				if(FwpConnect.product == "zwinky"){
					var dataObj = eval("(" + data + ")");
					thisRef.setCookies(dataObj);
					try{
						if(zwinkyPage && zwinkyPage == "zwinkychatv2"){
							sUsername = dataObj.linkedUserName;
						}
						setDataController("1");
					}
					catch(e){}
				}
				else{
					var dataObj = eval("(" + data + ")");
					thisRef.setCookies(dataObj);
				}	

				// invoke callback
				onLogin(dataObj.firstTime);
				//This is used to modify the dataController to show that the useris logged in.
			}
		});
	} else {
		onLogin( params );// Do something here for IWON after they have logged in
	}
};

FwpConnect.RemoteHandler.prototype.networkLogout = function(networkName) {
	// delete the cookie
	FwpConnect.deleteCookie(networkName + 'UserInfo');	
};

FwpConnect.RemoteHandler.prototype.getLinkStatus = function(networkName, callback) {
	var thisRef = this;
	if( FwpConnect.product != 'zwinky' ) {
		$.post(this.remoteHost + "/getLoggedOutCookie.jhtml", {network: networkName}, function (data, status) {
			if (status == "success") {
				// parse JSON response
				var dataObj = eval("(" + data + ")");
				thisRef.setCookies(dataObj);
				
				// invoremembeke callback
				callback(dataObj.isLinked);
			}
		});
	} else {
		if( typeof(FwpConnect.fbUserInfo) == 'object' ) {
			$.post(this.remoteHost + "/getLinkStatus.jhtml", {network: networkName, networkId: FwpConnect.fbUserInfo.networkUserId}, function (data, status) {
				if (status == "success") {
					// invoremembeke callback
					var dataObj = eval("(" + data + ")");
					callback(dataObj);
				}
			});
		} else {
			var linkedNetworkID = "\"linkedNetworkId\":" + FwpConnect.adapters.facebook.linkedNetworkId;
			var isZwinkyLinked = "\"isZwinkyLinked\":" + FwpConnect.adapters.facebook.isZwinkyLinked;
			var isLinked = "\"isLinked\":" + FwpConnect.adapters.facebook.isLinked;
			var hasMatch = "\"hasMatch\":" + FwpConnect.adapters.facebook.hasMatch;
			//{"linkedNetworkId":100000136844475,"isZwinkyLinked":true,"isLinked":true,"hasMatch":true}
			var tempObj = eval("({" +  linkedNetworkID +","+ isZwinkyLinked +","+ isLinked +","+ hasMatch + "})");
			callback(tempObj);
		}
	}
};

FwpConnect.RemoteHandler.prototype.setCookies = function(dataObj) {
	this.isLinked = dataObj.isLinked;//store linked status
	
	// set the cookie
	for (var index in dataObj.cookies) {
		var cookie = dataObj.cookies[index];
		var expiry = new Date(new Date().getTime() + cookie.expiry * 1000);
		FwpConnect.setCookie(cookie.name, cookie.value, expiry, "/", null, null, false);
	}
}

FwpConnect.RemoteHandler.prototype.logError = function(network, action, message) {
	if( FwpConnect.product != 'iwon' ) {
		$.post(this.remoteHost + "/logError.jhtml", {network:network, action:action, message:message}, function (data, status) {});
	} else {
		if(typeof launchGameObject != "undefined") {
			urchinTracker( "/clicks/fbconnect/gameplayer/error/"+action.toLowerCase().replace(' ','_')+"/"+ message.toLowerCase().replace(' ','_')  );
		} else {
			urchinTracker( "/clicks/fbconnect/pick7Invite/error/"+action.toLowerCase().replace(' ','_')+"/"+ message.toLowerCase().replace(' ','_')  );
		}
	}
}

// use this as default handler
FwpConnect.handler = new FwpConnect.RemoteHandler();