(function () {
    'use strict';
    angular.module('uniflash').service('propertiesActionSrv', propertiesActionSrv);
    propertiesActionSrv.$inject = ['$state', '$log', 'ufSession', 'ufDsProgressDialog', 'ufContext', 'ticAnalyticsSrv'];
    function propertiesActionSrv($state, $log, ufSession, ufDsProgressDialog, ufContext, ticAnalyticsSrv) {
        var propertiesAction = [];
        var orderIndex = 0;
        // add an action to the action list
        function addAction(action) {
            propertiesAction.push({ 'order': orderIndex,
                'action': action });
            orderIndex++;
            var 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) {
            var index = 0, prevIndex = 0;
            var length = dssStrs.length;
            var actionArr = [];
            if (dssStrs.indexOf(';') > -1) {
                while ((index = dssStrs.indexOf(';', index)) > -1) {
                    index++;
                    var 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) {
            var dotIndex1 = dssStr.indexOf('.');
            var dotIndex2 = dssStr.indexOf('.', dotIndex1 + 1);
            var openBracketIndex = dssStr.indexOf('(');
            var action = dssStr.substring(openBracketIndex, dssStr.length);
            var startQuoteIndex = action.indexOf('"');
            var 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
        };
    }
})();
