(function() {
	MSGI.namespace('subscriber');

	
	
	//------------------------------------------------------------------------------------------
	// Login & Registration
	//------------------------------------------------------------------------------------------

	MSGI.subscriber.create = function(subscriber, callback) {
		MSGI.service.send('subscriber_create', subscriber, callback);
	};
	
	MSGI.namespace('subscriber.create', {
		EMAIL_ALREADY_EXISTS: -1,        // email already exists
		ERROR_CREATE_SUBSCRIBER: -2      // error on create user
	});
	
	MSGI.subscriber.authenticate = function(callback) {
		MSGI.service.send("subscriber_authenticate", function(response) {
			var authenticated = (!response.error && response.result == true);
			callback(authenticated);
		});
	};

	MSGI.subscriber.exists = function(email, callback) {
		var data = { 'email': email };
		MSGI.service.send('subscriber_exists', data, function(response) {
			if (response.error) throw(response.error.message);
			callback(response.result);
		});
	};

	MSGI.subscriber.login = function(subscriber, callback) {
		// FIXME: seriously, logging in twice sets cookies properly, so do it in the code instead.
		MSGI.service.send('subscriber_login', subscriber, function() {
			MSGI.service.send('subscriber_login', subscriber, callback);
		});
	};


	MSGI.namespace('subscriber.login', {
		NO_EMAIL: -1,               // email does not exists
		EMAIL_NO_PASS_IN_DB: -2,    // email exists but no password exists in the db
		EMAIL_NO_PASS_MATCH: -3     // email exists but password does not match
	});

	MSGI.subscriber.logout = function(callback) {
		MSGI.service.send('subscriber_logout', function(response) {
			callback(response.result == 'success');
		});
	};

	MSGI.subscriber.emailResetPassword = function(subscriber, callback) {
		MSGI.service.send('subscriber_emailResetPassword', subscriber, callback);
	};

	MSGI.namespace('subscriber.emailResetPassword', {
		EMAIL_DOES_NOT_EXIST: -1,
		UNABLE_TO_CHANGE_PASSWORD: -2,
		UNABLE_TO_SEND_EMAIL: -3
	});



	//------------------------------------------------------------------------------------------
	// Locations
	//------------------------------------------------------------------------------------------
	
	(function() {
		function toArray(locations) {
			// if locations is a single ID, wrap it in an array now
			if (!$.isArray(locations)) locations = [locations];
			
			// convert array of IDs to an array of hashes (each with a location_id) 
			return $.map(locations, function(id) {
				return { 'location_id': id.toString() };
			});
		}

		MSGI.subscriber.getLocations = function(callback) {
			MSGI.service.send('subscriber_getLocations', function(response) {
				if (response.error) throw(response.error.message);
				callback(response.result);
			});
		};

		MSGI.subscriber.addLocations = function(locations, callback) {
			locations = toArray(locations);
			if (!locations.length) return callback();
			
			MSGI.service.send('subscriber_addLocation', locations, function(response) {
				if (response.error) throw(response.error.message);
				callback(response.result);
			});
		};

		MSGI.subscriber.removeLocations = function(locations, callback) {
			locations = toArray(locations);
			if (!locations.length) return callback();

			MSGI.service.send('subscriber_removeLocation', locations, function(response) {
				if (response.error) throw(response.error.message);
				callback(response.result);
			});
		};
	})();

	

	//------------------------------------------------------------------------------------------
	// Alerts
	//------------------------------------------------------------------------------------------

	MSGI.subscriber.getAlerts = function(callback) {
		MSGI.service.send('subscriber_getAlerts', function(response) {
			if (response.error) throw(response.error.message);
			callback(response.result);
		});
	};

	MSGI.subscriber.updateAlerts = function(alerts, callback) {
		MSGI.service.send('subscriber_updateAlerts', alerts, function(response) {
			if (response.error) throw(response.error.message);
			callback(response.result == 'success');
		});
	};

	
	
	//------------------------------------------------------------------------------------------
	// Mobile / Wireless
	//------------------------------------------------------------------------------------------

	MSGI.subscriber.getWireless = function(callback) {
		MSGI.service.send('subscriber_getWireless', function(response) {
			callback(response.error ? null : response.result);
		});
	};

	MSGI.subscriber.enableMobileAlerts = function(number, provider, callback) {
		var data = { "number": number, "service_provider": provider};
		MSGI.service.send('subscriber_enableWireless', data, function(response) {
			if (response.error) throw(response.error.message);
			callback();
		});
	};

	MSGI.subscriber.updateMobileNumber = function(number, provider, callback) {
		var data = { "number": number, "service_provider": provider};
		MSGI.service.send('subscriber_updateWireless', data, function(response) {
			if (response.error) throw(response.error.message);
			callback();
		});
	};

	
	
	//------------------------------------------------------------------------------------------
	// Sweepstakes
	//------------------------------------------------------------------------------------------
	
	MSGI.subscriber.enterSweepstakes = function(sweepstakes_id, callback) {
		MSGI.channel.getCurrent(function(id) {
			var params = { 'channel_id': id.toString(), 'sweepstakes': [ sweepstakes_id.toString()] };
			MSGI.service.send('subscriber_enterSweepstakes', params, function(response) {
				callback(response.result == 'success');
			});
		});
	};
	
	MSGI.subscriber.getEnteredSweepstakes = function(callback) {
		MSGI.service.send('subscriber_getEnteredSweepstakes', function(response) {
			if (response.error) throw(response.error.message);
			callback(response.result);
		});
	};



	//------------------------------------------------------------------------------------------
	// Miscellaneous
	//------------------------------------------------------------------------------------------

	MSGI.subscriber.inviteFriend = function(email, callback) {
		var params = { 'email': email, 'slug': MSGI.getChannelSlugFromURL() }
		MSGI.service.send('subscriber_inviteFriend', params, callback);
	};
	
	MSGI.namespace('subscriber.inviteFriend', {
		'EMAIL_INVALID': -1,
		'EMAIL_UNSENT': -2
	});

	MSGI.subscriber.updatePersonalInfo = function(info, callback) {
		MSGI.service.send('subscriber_updatePersonalInfo', info, callback);
	};

	MSGI.namespace('subscriber.updatePersonalInfo', {
		UNABLE_TO_UPDATE: -1
	});

	MSGI.subscriber.updateEmail = function(email, callback) {
		MSGI.service.send('subscriber_updateEmail', email, callback);
	};

	MSGI.namespace('subscriber.updateEmail', {
		INVALID_INPUT: -1,
		EMAIL_ALREADY_EXISTS: -2,
		UNABLE_TO_UPDATE: -3
	});

	MSGI.subscriber.updatePassword = function(password, callback) {
		MSGI.service.send('subscriber_updatePassword', password, callback);
	};

	MSGI.namespace('subscriber.updatePassword', {
		INVALID_INPUT: -1,
		UNABLE_TO_UPDATE: -2
	});

	/**
	 * Unsubscribes a Subscriber from emails
	 * @param {object} options 
	 *  { "email":"",
	 *    "opt-outs": [0,1,2,3,4,5],
	 *    "reasons":[0,1,2,"I want to unsubscribe"] }
	 * @param {function} callback the function to be executed
	 */
	MSGI.subscriber.optOut = function(options, callback) {
		MSGI.service.send('subscriber_optOut', options, callback);
	};

	MSGI.namespace('subscriber.optOut', {
		ENTERTAINMENT: 0, // MSG Entertainment checkbox
		KNICKS: 1,        // NY Knicks checkbox
		RANGERS: 2,       // NY Rangers checkbox
		LIBERTY: 3,       // NY Liberty checkbox
		ALL: 4,           // All MSG checkbox
		BIGNIGHT: 5,      // Big Night Invite checkbox

		TOO_MANY_EMAILS: 0, // opt-out reason: too many emails
		NOT_AREA: 1,        // opt-out reason: do not live in an area where events are held
		NOT_INTERESTED: 2,  // opt-out reason: not interested in the offers received
		OTHER: 'I want to unsubscribe' // opt-out reason: user input
 	});

	MSGI.subscriber.getAccountInfo = function(callback) {
		MSGI.service.send('subscriber_getAccountInfo', function(response) {
			if (response.error) throw(response.error.message);
			callback(response.result);
		});
	};

	MSGI.subscriber.getEventsWithPromosAndDiscounts = function(callback) {
		MSGI.service.send('subscriber_getEventsWithPromosAndDiscounts', function(response) {
			if (response.error) throw(response.error.message);
			callback(response.result);
		});
	};

	
	
	//------------------------------------------------------------------------------------------
	// Subscriber methods for Admin Tool
	//------------------------------------------------------------------------------------------
	
	MSGI.namespace('subscriber.admin', {
		
		/**
		 * Creates Subscriber via the admin tool
		 * @param params {object} Subscriber to save.
		 * @param callback {function} Subscribes id is provided to callback function.
		 */
		create: function(params, callback) {
			MSGI.service.send('subscriber_createByAdministrator', params, function(response) {
				if (response.error) throw(response.error.message);
					callback(response.result);
			});
		},
		
		/**
		 * Updates Subscribers info via the admin tool
		 * @param params {object} Subscriber to save.
		 * @param callback {function} "Success" is provided to callback function.
		 */ 
		update: function(params, callback) {
			params.id = params.id.toString();
			MSGI.service.send('subscriber_updateByAdministrator', params, function(response) {
				if (response.error) throw(response.error.message);
					callback(response.result);
			});
		},
		
		getInfo: function(params, callback) {
			MSGI.service.send('subscriber_getAccountInfoByAdministrator', params, function(response) {
				if (response.error) throw(response.error.message);
					callback(response.result);
			});
		},
		
		/**
		 * Gets Subscribers alerts.
		 * @param id {number} Subscribers ID.
		 * @param callback {function} Array of alerts is provided to callback.
		 */		
		getAlerts: function(params, callback) {
			MSGI.service.send('subscriber_getAlertsByAdministrator', params, function(response) {
				if (response.error) throw(response.error.message);
					callback(response.result);
			});
		},
		
		/**
		 * Updates Subscribers alerts.
		 * @param params {object} Subscribers alerts.
		 * @param callback {function} "Success" is provided to callback function.
		 */		
		updateAlerts: function(params, callback) {
			params.id = params.id.toString();
			MSGI.service.send('subscriber_updateAlertsByAdministrator', params, function(response) {
				if (response.error) throw(response.error.message);
					callback(response.result);
			});
		},
		
		/**
		 * Searches subscribers by their email address.
		 * @param params {object} search criteria object.
		 * @param callback {function} The search result is provided to the callback function.
		 */
		search: function(params, callback) {
			MSGI.service.send('subscriber_search', params, function(response) {
				if (response.error) throw(response.error.message);
					callback(response.result);
			});
		},
		
		
		/**
		 * Soft Delete of a subscriber.
		 * @param params {array} string array of ids.
		 * @param callback {function} The result is provided to the callback function.
		 */
		remove: function(ids, callback) {
			MSGI.service.send('subscriber_disable', ids, function(response) {
				if (response.error) throw(response.error.message);
					callback(response.result);
			});
		},
		
		removeWithPrompt: function(ids, callback) {
			if(ids.length && confirm('Are you sure you want to delete ' + (ids.length == 1 ?  'this item' : (ids.length + ' items')) +'?')) {
				MSGI.subscriber.admin.remove(ids, callback);
			}
		},
		
		/**
		 * Gets subscribers selected locations
		 * @param id {Integer} Subscribers id.
		 * @param callback {function} The result is provided to the callback function.
		 */
		getLocations: function(id, callback) {
			MSGI.service.send('subscriber_getLocationsByAdministrator',{id: id.toString()}, function(response) {
				if (response.error) throw(response.error.message);
					callback(response.result);
			});
		}
	});

})();

