(function () {
	'use strict';

	angular.module('uniflash').directive('ufConfigNew', ufConfigNew);

	function ufConfigNew() {

		var directive = {
			restrict: 'E',
			templateUrl: 'target_setup/configNew.html',
			controller: ufConfigNewController,
			controllerAs: 'vm',
			scope: {}
		};

		return directive;
	}


	ufConfigNewController.$inject = ['$q', '$state', '$rootScope', '$log', 'ufTargetConfig', 'ticHighlightSrv', '$timeout', 'ticAnalyticsSrv', 'menuContribSrv', 'ticAlerts', 'ufTargetSetupSrv', 'ufAddOnTargetSrv', 'ufSession'];

	function ufConfigNewController($q, $state, $rootScope, $log, ufTargetConfig: uniflash.target_config.TargetConfig, ticHighlightSrv, $timeout, ticAnalyticsSrv, menuContribSrv, ticAlerts, ufTargetSetupSrv, ufAddOnTargetSrv, ufSession) {
		var vm = this;
		vm.ticHighlightSrv = ticHighlightSrv;
		vm.ufTargetSetupSrv = ufTargetSetupSrv;
		vm.ufAddOnTargetSrv = ufAddOnTargetSrv;
		vm.ufTargetSetupSrv.reset();
		vm.connectionFilter = '';

		vm.showMainNewConfig = true;
		vm.showNewConfig = true;

		vm.useDefaultConnection = true;
		vm.deviceListReady = false;
		vm.editStarted = false;
		vm.editClicked = false;

		var devices: uniflash.target_config.DeviceSetup[];

		menuContribSrv.editMenu('Save Session', true);

		ufTargetConfig.getDevices()
			.then((newDevices: uniflash.target_config.DeviceSetup[]) => {
				devices = newDevices;
				filterDeviceList();
				vm.deviceListReady = true;
			});

		function filterDeviceList() {
			// remove CC3200/CC32xx entries
			let removedEntriesDeviceList = _.filter(devices, function (device: any) {
				return ((device.id.toLowerCase().indexOf('cc3200') === -1) &&
					(device.id.toLowerCase().substring(0, 6) !== 'cc32xx'));
			});

			// filter the device list by category
			var categoryDeviceList = _.filter(removedEntriesDeviceList, function (device) {
				if (!device.id) { return false; }	// weird case where the device ID is not available
				if (vm.ufTargetSetupSrv.deviceCategoryFilter === 'All') { return true; }
				else if (vm.ufTargetSetupSrv.deviceCategoryFilter === 'C2000') {
					return ((device.id.toLowerCase().indexOf('tms320f28') !== -1) ||
						(device.id.toLowerCase().indexOf('tms320c28') !== -1) ||
						(device.id.toLowerCase().indexOf('tms320r28') !== -1) ||
						(device.id.toLowerCase().indexOf('f28plc') !== -1) ||
						(device.id.toLowerCase().indexOf('f28m3') !== -1));
				} else if (vm.ufTargetSetupSrv.deviceCategoryFilter === 'MSP') {
					return ((device.id.toLowerCase().indexOf('msp430') !== -1) ||
						(device.id.toLowerCase().indexOf('msp432') !== -1) ||
						(device.id.toLowerCase().indexOf('rf430') !== -1) ||
						(device.id.toLowerCase().indexOf('cc430') !== -1));
				} else if (vm.ufTargetSetupSrv.deviceCategoryFilter === 'Safety') {
					return ((device.id.toLowerCase().substring(0, 6) === 'tms470') ||
						(device.id.toLowerCase().substring(0, 6) === 'tms570') ||
						(device.id.toLowerCase().substring(0, 3) === 'rm4') ||
						(device.id.toLowerCase().substring(0, 3) === 'rm5'));
				} else if (vm.ufTargetSetupSrv.deviceCategoryFilter === 'Wireless') {
					return ((device.id.toLowerCase().substring(0, 4) === 'cc13') ||
						(device.id.toLowerCase().substring(0, 4) === 'cc25') ||
						(device.id.toLowerCase().substring(0, 4) === 'cm25') ||
						(device.id.toLowerCase().substring(0, 4) === 'cc26') ||
						(device.id.toLowerCase().substring(0, 4) === 'cc32'));
				} else if (vm.ufTargetSetupSrv.deviceCategoryFilter === 'Tiva') {
					return ((device.id.toLowerCase().indexOf('stellaris') !== -1) ||
						(device.id.toLowerCase().indexOf('tiva') !== -1));
				} else if (vm.ufTargetSetupSrv.deviceCategoryFilter === 'UCD') {
					return (device.id.toLowerCase().substring(0, 3) === 'ucd');
				} else if (vm.ufTargetSetupSrv.deviceCategoryFilter === 'mmWave') {
					return ((device.id.toLowerCase().substring(0, 3) === 'awr') ||
						(device.id.toLowerCase().substring(0, 3) === 'iwr'));
				} else if (vm.ufTargetSetupSrv.deviceCategoryFilter === 'PGA') {
					return (device.id.toLowerCase().substring(0, 3) === 'pga');
				} else if (vm.ufTargetSetupSrv.deviceCategoryFilter === 'Bootloader') {
					return (device.id.toLowerCase().indexOf('bootloader') !== -1);
				}

				return true;
			});

			// sort by name
			var orderedDeviceList = categoryDeviceList.sort(function (a: any, b: any) { return a.id.localeCompare(b.id); });

			orderedDeviceList = _.filter(orderedDeviceList, function (device: any) {
				return !ufSession.isG2DeviceSpecialHandling(device.id);
			});

			// filter the device list by user search
			vm.filteredDevices = _.filter(orderedDeviceList, function (device: any) {
				return device.id.toLowerCase().indexOf(vm.ufTargetSetupSrv.deviceFilter.toLowerCase()) !== -1;
			});

			// if a connection has been selected, filter the device list to only include ones that have matching connection support
			if (ufTargetSetupSrv.setConnectionIndex >= 0 && !ufTargetSetupSrv.deviceSelected && !ufTargetSetupSrv.lpSelected) {
				vm.filteredDevices = _.filter(vm.filteredDevices, function (device: any) {
					return _.find(device.connectionIndices, function (index) {
						return index === ufTargetSetupSrv.setConnectionIndex;
					})
				});
			}
		}

		function setConnections(device) {
			if (device) {
				return ufTargetConfig.getConnections(device.connectionIndices).then(function (connections) {
					if (device.defaultConnectionIndex !== undefined) {
						let translatedIndex;
						for (var i = 0; i < device.connectionIndices.length; i++) {
							if (device.connectionIndices[i] == device.defaultConnectionIndex) {
								translatedIndex = i;
								break;
							}
						}

						device.defaultConnection = connections[translatedIndex];
					}

					// remove Data Snapshot and UART for now
					let removedEntriesConnectionList = _.filter(connections, function (connection: any) {
						return ((connection.id !== 'Data Snapshot Viewer') &&
							(connection.id !== 'UARTConnection') &&
							(connection.id.toLowerCase().indexOf('texas instruments xds560') === -1) &&
							(connection.id.toLowerCase().indexOf('xds100v1') === -1));
					});
					// sort by name
					let sortedConnectionList = removedEntriesConnectionList.sort(function (a: any, b: any) { return a.id.localeCompare(b.id); });

					device.connections = sortedConnectionList;
				});
			} else {
				$q.resolve([]);
			}
		}

		vm.deviceClicked = function (device) {
			vm.ufTargetSetupSrv.selectedDevice = device;
			vm.editClicked = false;
			vm.ufTargetSetupSrv.deviceSelected = true;
			vm.ufTargetSetupSrv.lpSelected = false;
			vm.selectedDeviceChanged();
			vm.ufTargetSetupSrv.hideDeviceSelectionOptions = true;
			vm.ufTargetSetupSrv.hideConnectionSelectionOptions = false;
		};

		vm.selectedDeviceChanged = function () {
			vm.configurables = [];
			ufTargetConfig.resetConfigurables();
			if (vm.ufTargetSetupSrv.selectedDevice) {
				return setConnections(vm.ufTargetSetupSrv.selectedDevice).then(function () {
					if (vm.ufTargetSetupSrv.setConnectionIndex !== -1) {
						const cachedConnection = vm.ufTargetSetupSrv.selectedConnection;
						vm.filterConnectionList();
						if (vm.filteredConnectionList.length === 1) {
							// override the selected connection if there is only one valid connection after filtering
							vm.ufTargetSetupSrv.selectedConnection = vm.filteredConnectionList[0];
						} else {
							vm.ufTargetSetupSrv.selectedConnection = cachedConnection;
						}
						vm.ufTargetSetupSrv.hideConnectionSelectionOptions = true;
					} else if (vm.ufTargetSetupSrv.selectedDevice.defaultConnectionIndex !== undefined && vm.useDefaultConnection) {
						vm.filterConnectionList();
						vm.ufTargetSetupSrv.selectedConnection = vm.ufTargetSetupSrv.selectedDevice.defaultConnection;
					} else {
						vm.filterConnectionList();
						if (vm.filteredConnectionList.length === 1) {
							vm.ufTargetSetupSrv.selectedConnection = vm.filteredConnectionList[0];
						} else {
							vm.ufTargetSetupSrv.selectedConnection = '';
						}
					}
				});
			} else {
				vm.filteredConnectionList = [];
				vm.ufTargetSetupSrv.selectedConnection = '';
			}
		};

		vm.deviceFilterChanged = function () {
			filterDeviceList();
		};

		vm.deviceDisplayToggled = function () {
			ufTargetSetupSrv.isDeviceEntryExpanded = !ufTargetSetupSrv.isDeviceEntryExpanded;

			_.each(vm.launchpads, function (lp) {
				lp.showPreview = ufTargetSetupSrv.isDeviceEntryExpanded;
			});
			_.each(devices, function (device) {
				device.showPreview = ufTargetSetupSrv.isDeviceEntryExpanded;
			});
			_.each(vm.ufAddOnTargetSrv.getDeviceList(), function (device) {
				device.showPreview = ufTargetSetupSrv.isDeviceEntryExpanded;
			});
		};

		vm.filterConnectionList = function () {
			// filter list with user filter string (case insenstive)
			vm.filteredConnectionList = _.filter(vm.ufTargetSetupSrv.selectedDevice.connections, function (connection: any) { return (connection.id.toLowerCase().indexOf(vm.connectionFilter.toLowerCase()) !== -1); });

			// remove all non-serial connections for mmWave devices
			if ((vm.ufTargetSetupSrv.selectedDevice.id.toLowerCase().indexOf('awr') !== -1) || (vm.ufTargetSetupSrv.selectedDevice.id.toLowerCase().indexOf('iwr') !== -1)) {
				vm.filteredConnectionList = _.filter(vm.filteredConnectionList, function (connection: any) {
					return (connection.id.toLowerCase().indexOf('serial') !== -1);
				});
				vm.ufTargetSetupSrv.selectedDevice.connections = vm.filteredConnectionList;
			}

			if (!vm.filteredConnectionList) {
				vm.ufTargetSetupSrv.selectedConnection = '';
			}
		};

		vm.connectionClicked = function (connection) {
			vm.configurables = [];
			ufTargetConfig.resetConfigurables();
			vm.ufTargetSetupSrv.selectedConnection = connection;
			vm.ufTargetSetupSrv.hideConnectionSelectionOptions = true;
			vm.editClicked = false;
		};

		vm.startClicked = function () {
			ticAnalyticsSrv.record("Configuration", {
				"device": vm.ufTargetSetupSrv.selectedDevice.xmlFile,
				"connection": vm.ufTargetSetupSrv.selectedConnection.xmlFile,
				"lp": vm.ufTargetSetupSrv.lpSelected
			});
			$log.debug('Target Configuration. Device: ' + vm.ufTargetSetupSrv.selectedDevice.xmlFile + ', Connection: ' + vm.ufTargetSetupSrv.selectedConnection.xmlFile + ', LP: ' + vm.ufTargetSetupSrv.lpSelected);

			if (!ufSession.isG2DeviceSpecialHandling(vm.ufTargetSetupSrv.selectedDevice.id)) {
				$state.go('main.Program', {
					deviceXMLFile: vm.ufTargetSetupSrv.selectedDevice.xmlFile,
					connectionXMLFile: vm.ufTargetSetupSrv.selectedConnection.xmlFile,
					coreName: null,
					forceSessionInit: true,
					lp: vm.ufTargetSetupSrv.lpSelected
				});
			} else {
				ticAlerts.showError('G2 Devices are only supported on Windows.');
			}
		};

		vm.showLaunchPad = true;
		vm.showLP = true;

		var devices: uniflash.target_config.DeviceSetup[];

		ufTargetConfig.getLaunchPads().then(function (launchpads) {
			launchpads = _.filter(launchpads, function (lp: any) {
				return !ufSession.isG2DeviceSpecialHandling(lp.name);
			});
			vm.launchpads = launchpads;
		});

		ufTargetConfig.getDevices()
			.then((newDevices: uniflash.target_config.DeviceSetup[]) => {
				devices = newDevices;
			});

		function setConnectionsLP(device) {
			if (device) {
				return ufTargetConfig.getConnections(device.connectionIndices).then(function (connections) {
					device.connections = connections;
				});
			} else {
				$q.resolve([]);
			}
		}

		vm.configureLP = function (lp) {
			vm.editClicked = false;
			vm.configurables = [];
			ufTargetConfig.resetConfigurables();
			if ((vm.selectedLp === lp) && vm.ufTargetSetupSrv.lpSelected) {
				return;
			}

			vm.selectedLp = lp;
			if (lp.moduleName) {
				// special case for devices that start different modules (ie; Image Creator)
				vm.ufTargetSetupSrv.selectedConnection = '';
				vm.ufTargetSetupSrv.selectedDevice = _.find(vm.ufAddOnTargetSrv.deviceList, function (curDevice: any) {
					return (curDevice.name.toLowerCase() === lp.device.toLowerCase());
				});

				vm.ufAddOnTargetSrv.selectDevice(vm.ufTargetSetupSrv.selectedDevice);

				vm.ufTargetSetupSrv.deviceSelected = false;
				vm.ufTargetSetupSrv.lpSelected = true;
				vm.ufTargetSetupSrv.hideDeviceSelectionOptions = true;
			} else {
				vm.ufTargetSetupSrv.deviceSelected = false;
				vm.ufTargetSetupSrv.lpSelected = true;
				vm.ufTargetSetupSrv.hideDeviceSelectionOptions = true;

				vm.ufTargetSetupSrv.selectedDevice = _.find(devices, function (curDevice: any) {
					return (curDevice.xmlFile.toLowerCase() === lp.device.toLowerCase());
				});

				var promise;
				if (vm.ufTargetSetupSrv.selectedDevice.id.toLowerCase().indexOf('msp430') !== -1) {
					promise = vm.selectedDeviceChanged();

					promise.then(function () {
						vm.ufTargetSetupSrv.selectedConnection = _.find(vm.ufTargetSetupSrv.selectedDevice.connections, function (curConnection: any) {
							return (curConnection.xmlFile.toLowerCase() === lp.connection.toLowerCase());
						});
					});
				} else {
					promise = setConnectionsLP(vm.ufTargetSetupSrv.selectedDevice);
					promise.then(function () {
						vm.ufTargetSetupSrv.selectedConnection = _.find(vm.ufTargetSetupSrv.selectedDevice.connections, function (curConnection: any) {
							return (curConnection.xmlFile.toLowerCase() === lp.connection.toLowerCase());
						});
					});
				}
			}
		};

		vm.getFilteredLPList = function () {
			return _.filter(vm.launchpads, function (lp: any) {
				let lpModName = lp.name + " (launchpad)";

				var match1 = ((lpModName.toLowerCase().indexOf(vm.ufTargetSetupSrv.deviceFilter.toLowerCase()) !== -1) ||
					//(lp.device.toLowerCase().indexOf(vm.ufTargetSetupSrv.deviceFilter.toLowerCase()) !== -1) ||
					(lp.connection.toLowerCase().indexOf(vm.ufTargetSetupSrv.deviceFilter.toLowerCase()) !== -1));
				var match2 = ((vm.ufTargetSetupSrv.deviceCategoryFilter === 'All') || (vm.ufTargetSetupSrv.deviceCategoryFilter === lp.category));

				// if a connection has been selected (and device is not selected), filter the device list based on matching connection
				var match3 = true;
				if (ufTargetSetupSrv.selectedConnection && !ufTargetSetupSrv.deviceSelected && !ufTargetSetupSrv.lpSelected) {
					match3 = (ufTargetSetupSrv.selectedConnection.xmlFile === lp.connection);
				}

				return (match1 && match2 && match3);
			});
		};

		vm.toggleDeviceView = function () {
			if (vm.ufTargetSetupSrv.lpSelected || (vm.ufTargetSetupSrv.deviceSelected && vm.ufTargetSetupSrv.selectedDevice.id)) {
				vm.ufTargetSetupSrv.hideDeviceSelectionOptions = !vm.ufTargetSetupSrv.hideDeviceSelectionOptions;
			}
		};

		vm.toggleConnectionView = function () {
			if ((!vm.ufTargetSetupSrv.lpSelected || (vm.ufTargetSetupSrv.selectedDevice.id.toLowerCase().indexOf('msp430') !== -1)) && vm.ufTargetSetupSrv.selectedConnection) {
				vm.ufTargetSetupSrv.hideConnectionSelectionOptions = !vm.ufTargetSetupSrv.hideConnectionSelectionOptions;
			}
		};

		vm.getConnectionMainClass = function () {
			let rtnClass = '';

			if (vm.lpOrDeviceSelected() || ufTargetSetupSrv.selectedConnection) {
				if ((!vm.ufTargetSetupSrv.lpSelected || (vm.ufTargetSetupSrv.selectedDevice.id.toLowerCase().indexOf('msp430') !== -1)) && vm.ufTargetSetupSrv.selectedConnection) {
					rtnClass += 'tic-clickable ';
				}
				rtnClass += 'active ';
			} else {
				rtnClass += 'disabled ';
			}

			return rtnClass;
		};

		vm.lpOrDeviceSelected = function () {
			return (vm.ufTargetSetupSrv.lpSelected || (vm.ufTargetSetupSrv.deviceSelected && vm.ufTargetSetupSrv.selectedDevice.id));
		};

		vm.clearDeviceSelection = function () {
			vm.selectedLp = '';
			vm.ufTargetSetupSrv.selectedDevice = '';
			vm.ufTargetSetupSrv.selectedConnection = '';
			vm.ufTargetSetupSrv.lpSelected = false;
			vm.ufTargetSetupSrv.deviceSelected = false;
			vm.ufTargetSetupSrv.hideDeviceSelectionOptions = false;
			vm.ufTargetSetupSrv.hideConnectionSelectionOptions = false;
			vm.ufTargetSetupSrv.setConnectionIndex = -1;
		};

		vm.isOnChip = function (deviceName, deviceType) {
			return (((deviceType === undefined) || (deviceType !== 'Serial')) &&
				(deviceName.toLowerCase().substring(0, 3) !== 'awr') &&
				(deviceName.toLowerCase().substring(0, 3) !== 'iwr') &&
				(deviceName.toLowerCase().slice(-12) !== '(bootloader)'));
		};

		$rootScope.$on('UpdateDeviceList', function (event, data) {
			vm.deviceFilterChanged();
		});

		vm.configurables = [];
		vm.parsedConfigurables;
		vm.getConfiguables = function () {
			vm.editStarted = true;
			vm.editClicked = true;
			ufTargetConfig.getConfigurables(vm.ufTargetSetupSrv.selectedDevice.xmlFile, vm.ufTargetSetupSrv.selectedConnection.xmlFile)
				.then(function () {
					let list = ufTargetConfig.getParsedConfigurablesList();
					vm.configurables = list;
					vm.editStarted = false;
				});
		};

		vm.configurableValueChanged = function (configurable) {
			ufTargetConfig.configurableValueChanged(configurable);
		};

		vm.deviceExist = function (deviceName) {
			// make sure deviceName is available in list of devices, or addOn device list
			const foundDevice = _.some(devices, function (curDevice: any) {
				return (curDevice.xmlFile.toLowerCase() === deviceName.toLowerCase());
			});
			const foundDevice2 = _.some(ufAddOnTargetSrv.deviceList, function (curDevice: any) {
				return (curDevice.name.toLowerCase() === deviceName.toLowerCase());
			});
			return foundDevice || foundDevice2;
		};

		vm.hasConfigurables = function (configurableList) {
			if (configurableList.length === 0) { return false; }
			return true;
		};

		vm.formatDeviceID = function (deviceName) {
			const index = deviceName.indexOf('(');
			if (index > 0) {
				deviceName = deviceName.substring(0, index);
			}
			return deviceName;
		};
	}

})();
