(function () {
    'use strict';
    angular.module('uniflash').service('ufPropertiesValue', ufPropertiesValue);
    ufPropertiesValue.$inject = ['x2js'];
    function ufPropertiesValue(x2js) {
        var propertiesValueList = [];
        var coreList = [];
        var curConfigInfo;
        var targetRead = false;
        // reset variables
        function reset() {
            propertiesValueList = [];
            coreList = [];
        }
        // initialize the value list, based on the default value of the properties list
        function initialize(propertyJSON, configInfo, core) {
            curConfigInfo = configInfo;
            var propertiesValue = [];
            targetRead = false;
            for (var i = 0; i < propertyJSON.PropertyList.property.length; i++) {
                var curProp = propertyJSON.PropertyList.property[i];
                // set the core selection value to CPU2 if the core information from XML contains CPU2 string
                if (curProp._id === 'FlashCoreSelection' && (core.name.indexOf("CPU2") !== -1)) {
                    if (configInfo.partnum.indexOf("F2838") !== -1) {
                        curProp.defaultValue = 'CPU2'; // TENOR
                    }
                    else {
                        curProp.defaultValue = 'CPU2 (Slave)'; // SOPRANO
                    }
                }
                var propertyValue = {
                    'id': curProp._id,
                    'value': curProp.defaultValue,
                    'modified': false,
                    'disabled': false,
                    'valueType': curProp.valueType
                };
                propertiesValue.push(propertyValue);
            }
            propertiesValueList.push({ 'name': core.name, 'valueObj': propertiesValue });
            coreList.push(core.name);
        }
        //update the values based on the properties name value pairs input
        //used as a call back function by the ds service, upon connect, ds service will get all the props and call this function.
        function updateFromDS(valuesMap, core, type) {
            _.each(getValuesByCore(core), function (prop) {
                var convertedValue = convertValueToOrig(prop.valueType, valuesMap[prop.id]);
                if (!!convertedValue && convertedValue !== prop.value && (type !== 'lprf' || convertedValue !== '--')) {
                    prop.value = convertedValue;
                }
            });
            targetRead = true;
        }
        // private function for converting value to necessary type
        function convertValueToOrig(type, value) {
            if (type === 'Boolean') {
                return (value === 'true' ? true : false);
            }
            if (type === 'Numeric') {
                return parseInt(value);
            }
            return value;
        }
        // private function for converting value to string
        /*
        function convertValueToStr(type:any,value:any) {
            if ( type === 'Numeric' ) {
                return parseInt(value);
            }
        return value;
        }
        */
        // get the values object the given property ID and core
        function getValueObj(propId, core) {
            var propertiesValueObj = [];
            propertiesValueObj = getValuesByCore(core);
            return _.find(propertiesValueObj, function (curProp) {
                return (curProp.id === propId);
            });
        }
        // use to load a list from a session
        function setPropertiesValueList(list) {
            propertiesValueList = list;
        }
        // return the full value list
        function getPropertiesValueList() {
            return propertiesValueList;
        }
        // get the values map for a given core
        function getPropertiesValuesMap(core) {
            var valuesMap = {};
            // no symbols are loaded, so we should turn off the auto run to label settings 
            valuesMap['AutoRunToLabelOnRestart'] = false;
            valuesMap['AutoRunToLabelOnReset'] = false;
            _.each(getValuesByCore(core), function (property) {
                if (property.modified) {
                    valuesMap[property.id] = property.value;
                }
            });
            return valuesMap;
        }
        // save all values for all cores to JSON 
        function saveValuesAsJson(modOnly) {
            var rtnJSON = {};
            _.each(coreList, function (core) {
                var corePath = getCorePath(core, curConfigInfo);
                rtnJSON[corePath] = {};
                _.each(getValuesByCore(core), function (property) {
                    if (property.modified || !modOnly) {
                        rtnJSON[corePath][property.id] = property.value;
                    }
                });
            });
            return JSON.stringify(rtnJSON);
        }
        // given a name of a core, decode the core path string
        function getCorePath(core, configInfo) {
            var matchedCore = _.find(configInfo.cores, function (curCore) {
                return (core === curCore.name);
            });
            return matchedCore.pathName;
        }
        // get values for a given core
        function getValuesByCore(core) {
            var valuesProperties = _.find(propertiesValueList, function (curPropertiesValue) { return (curPropertiesValue.name === core); });
            if (valuesProperties) {
                return valuesProperties.valueObj;
            }
            else {
                return null;
            }
        }
        function readFromTarget() {
            return targetRead;
        }
        return {
            reset: reset,
            initialize: initialize,
            updateFromDS: updateFromDS,
            getValueObj: getValueObj,
            setPropertiesValueList: setPropertiesValueList,
            getPropertiesValueList: getPropertiesValueList,
            getPropertiesValuesMap: getPropertiesValuesMap,
            saveValuesAsJson: saveValuesAsJson,
            readFromTarget: readFromTarget
        };
    }
})();
