(function() {

	'use strict';

	angular.module('uniflash').service('propertiesActionSrv',propertiesActionSrv);

	propertiesActionSrv.$inject = ['$state','$log', 'ufSession', 'ufDsProgressDialog', 'ufContext', 'ticAnalyticsSrv'];
	
	function propertiesActionSrv($state, $log, ufSession, ufDsProgressDialog, ufContext : uniflash.Context, ticAnalyticsSrv) {
		
		var propertiesAction = [];
		var orderIndex = 0;
        	
		// add an action to the action list
		function addAction(action) {
			propertiesAction.push({'order': orderIndex,
								   'action': action});
			orderIndex++;

			let dsCore = ufDsProgressDialog.getDSCore(ufContext.getCurrentCore().name);
			var parsedActionArr = parseDSSActionStrings(action);
			
			// process all action strings in the array
			return processSerially(parsedActionArr, function(curAction) {
				ticAnalyticsSrv.record('SettingsButtonPressed', {
					'call': curAction.call,
					'action': curAction.action
				});
				$log.debug('SettingsButtonPressed. Call: '+curAction.call+', Action: '+curAction.action);
				
				if ( (curAction.type === 'flash') && (curAction.call === 'performOperation') ) {
					// ie; flash.performOperation(id) format
					return dsCore.run('flashOperation', curAction.action);
				} else if ( (curAction.type === 'flash') && (curAction.action === '') ) {
					// ie; flash.erase() format
					return dsCore.run('flashOperation', curAction.call.charAt(0).toUpperCase() + curAction.call.slice(1));
				} else if ( curAction.call === 'evaluate' ) {
					return dsCore.run('evaluate', curAction.action);
				}
			});
		}
		
		// helper function for serially evaluating all items in the collection before returning 
		function processSerially(collection, predicate) {
			var toProcess = _.map(collection, function(value, index_or_key, collection) {
				return function() {
					return predicate(value, index_or_key, collection);
				};
			});

			var results = [];
			var index = 0;

			function processNext() {
				if (index !== toProcess.length) {
					var next = toProcess[index];
					++index;
					return next().then(function(result) {
						results.push(result);
						return processNext();
					});
				}
			}

			return processNext();
		}

		// parse an entire DSS action string (can contain multiple DSS calls), and then call parseDSSActionString() on each one
		function parseDSSActionStrings(dssStrs) {
			let index = 0, prevIndex = 0;
			let length = dssStrs.length;
			let actionArr = [];
			
			if ( dssStrs.indexOf(';') > -1 ) {
				while ((index = dssStrs.indexOf(';', index)) > -1) {
					index++;
					
					let curParsedAction = parseDSSActionString(dssStrs.substring(prevIndex,index));
					if ( curParsedAction.action.indexOf('GEL_Connect') === -1 ) {
						actionArr.push(curParsedAction);
					}
					prevIndex = index;
				}
			} else {
				actionArr.push(parseDSSActionString(dssStrs));
			}
			return actionArr;
		}
		
		// parse out the 'type', 'call', and 'action' string from a DSS call.
		function parseDSSActionString(dssStr) {
			let dotIndex1 = dssStr.indexOf('.');
			let dotIndex2 = dssStr.indexOf('.',dotIndex1+1);
			let openBracketIndex = dssStr.indexOf('(');
			
			let action = dssStr.substring(openBracketIndex,dssStr.length);
			let startQuoteIndex = action.indexOf('"');
			let endQuoteIndex = action.lastIndexOf('"');
			action = action.substring(startQuoteIndex+1,endQuoteIndex);
			action = action.split('\\"').join('"');

			return {'type':dssStr.substring(dotIndex1+1,dotIndex2),
					'call':dssStr.substring(dotIndex2+1,openBracketIndex),
					'action':action};
		}
		
		// delete an action from the list
		function deleteAction(index) {
			propertiesAction.splice(index, 1);
		}
		
		// remove all actions from the list
		function clearAllActions() {
			propertiesAction = [];
			orderIndex = 0;
		}
		
		// switch the order of the given actions (moving up and down a list)
		function switchActionOrder(action1,action2) {
			var action1Order = action1.order;
			var action2Order = action2.order;
			
			action1.order = action2Order;
			action2.order = action1Order;
		}
		
		// return the full action list
		function getActionList() {
			return propertiesAction;
		}

		ufSession.registerSessionDataProvider('propertyActions', {
			onSessionLoad: function(newData) {
				if (newData) {
					propertiesAction = newData.actionList;
					orderIndex = newData.orderIndex;
				} else {
					propertiesAction = [];
					orderIndex = 0;
				}
			},
			getSessionData: function() {
				return {'actionList':propertiesAction,'orderIndex':orderIndex};
			}
		});
		
		return {
			addAction : addAction,
			deleteAction : deleteAction,
			clearAllActions : clearAllActions,
			getActionList : getActionList,
			switchActionOrder : switchActionOrder
		};
	}

})();
