angular.module('starter.services', [])

.factory('bluetoothBle', function($rootScope, $ionicPlatform, $ionicLoading, $ionicPopup) {
	console.log("Entrée dans bluetoothBle factory");

	// Espace de stockage dans le téléphone
	var permanentStorage = window.localStorage;

	var serviceUUID_groveBleUart = "0000ffe0-0000-1000-8000-00805f9b34fb";
	var characteristicUUID_groveBleUart = "0000ffe1-0000-1000-8000-00805f9b34fb";

	var bluetoothBleStatus = new Array();
	var bluetoothBleIn = "";
	var bluetoothBleId = null;
	var bluetoothBleConnected = true;
	var bluetoothBleAutoConnectMode = false;

	function stringToBytes(string) {
		var array = new Uint8Array(string.length);
		for (var i = 0, l = string.length; i < l; i++) {
			array[i] = string.charCodeAt(i);
		}
		return array.buffer;
	};

	function bytesToString(buffer) {
		return String.fromCharCode.apply(null, new Uint8Array(buffer));
	};

	var setStatus = function(status) {
		bluetoothBleStatus.push({status: status});
		$rootScope.$broadcast('updateStatus');
	};

	setStatus( "Initialisation bluetoothBle service" );

	var onData = function(buffer) {
		var str = bytesToString(buffer);
		bluetoothBleIn = str;
		$rootScope.$broadcast('newData');
	};

	var connectToBleModule = function()
	{
		var name = window.localStorage.getItem("moduleName");
		if (name == null)
		{
			name = "ARDUINO"; // Nom par défaut
			window.localStorage.setItem("moduleName", name);
		}
		ble.scan([], 15,
			function(device) {
				if (device.name == name) {
					setStatus(name + " détecté.");
					ble.stopScan();
					$ionicLoading.show({
						template: "Tentative de connexion ...",
						duration: 1500
					});
					ble.connect(device.id,
						function(success) {
							bluetoothBleConnected = true;
							$rootScope.$broadcast('updateConnectionState');
							$ionicLoading.show({
								template: name + " connecté.",
								duration: 2000
							});
							setStatus("Android connecté.");
							bluetoothBleId = device.id;
							window.localStorage.setItem("lastBleMAC", device.id);
							ble.write(bluetoothBleId, serviceUUID_groveBleUart, characteristicUUID_groveBleUart, stringToBytes("Android\r\n"), function(){ setStatus("Envoi de \"Android\""); }, function(){ setStatus("Echec de l'envoi"); });
							ble.startNotification(device.id, serviceUUID_groveBleUart, characteristicUUID_groveBleUart, onData, function(failure) { setStatus("Erreur : " + JSON.stringify(failure)); });
						},
						function(failure) { setStatus(name + " n'a pas été détecté."); }
					);
				}
			},
			function(failure) { setStatus("Erreur : " + JSON.stringify(failure)); }
		);
	}

	var controlConnection = function()
	{
		ble.isConnected(bluetoothBleId,
			function(success) {
				if (!bluetoothBleConnected) $rootScope.$broadcast('updateConnectionState');
				bluetoothBleConnected = true;
				/*
				$ionicLoading.show({
					template: "Arduino est bien connecté ...",
					duration: 500
				});
				*/
			},
			function(failure) {
				if (bluetoothBleConnected)
				{
					bluetoothBleConnected = false;
					$rootScope.$broadcast('updateConnectionState');
					$ionicLoading.show({
						template: "La connexion a été perdue ...",
						duration: 1500
					});
				}
				// On tente de se connecter à nouveau
				if (bluetoothBleAutoConnectMode) connectToBleModule();
			}
		);
	}

	var autoConnectTimer = setInterval(controlConnection, 2500);

	var setAutoConnectMode = function(mode)
	{
			if (mode == 0) bluetoothBleAutoConnectMode = false; else bluetoothBleAutoConnectMode = true;

	}

	$ionicPlatform.ready(
		function() {
			connectToBleModule();
		}
	);

	// Forcer la déconnexion en quittant
	$ionicPlatform.registerBackButtonAction(
		function (event) {
			event.preventDefault();
			$ionicPopup.confirm({
				title: 'Avertissement',
				template: 'Etes-vous certain de vouloir quitter ?'
			}).then(function(res){
				if( res ){
					ble.disconnect(bluetoothBleId, function(){ setStatus("Déconnexion OK"); } , function(){ setStatus("Echec de la déconnexion"); });
					navigator.app.exitApp();
				}
			})
		}, 1000
	);

	return {
		AUTO_CONNECT: 1,
		MANUAL_CONNECT: 0,
		setAutoConnectMode: function(mode) { setAutoConnectMode(mode);
		},
		send: function(str) {
			ble.write(bluetoothBleId, serviceUUID_groveBleUart, characteristicUUID_groveBleUart, stringToBytes(str), function(){ setStatus("Envoi de \"" + str + "\""); }, function(){ setStatus("Echec de l'envoi de \"" + str + "\""); });
		},
		receive: function() {
			var result = bluetoothBleIn;
			bluetoothBleIn = "";
			return result;
		},
		getStatus: function() {
			var result = null;
			if (bluetoothBleStatus.length > 0)
			{
				result = bluetoothBleStatus[0];
				bluetoothBleStatus.shift();
			}
			return result;
		},
		getConnectionState: function () {
			var result = bluetoothBleConnected;
			return (result);
		},
		disconnect: function() {
			$ionicLoading.show({
				template: "Déconnexion en cours ...",
				duration: 1500
			});
			ble.disconnect(bluetoothBleId, function(){ setStatus("Déconnexion OK"); } ,  function(){ setStatus("Echec de la déconnexion"); });
		},
		connect: function() {
			connectToBleModule();
		},
		getBleModuleName: function(name) {
			return ( window.localStorage.getItem("moduleName") );
		},
		setBleModuleName: function(name) {
			window.localStorage.setItem("moduleName", name);
			ble.disconnect(bluetoothBleId, function(){ setStatus("Déconnexion OK"); } ,  function(){ setStatus("Echec de la déconnexion"); });
			connectToBleModule();
		}
	};
});