(function () {
	'use strict';

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

	ufPropertiesValue.$inject = ['x2js'];

	function ufPropertiesValue(x2js) {
		let propertiesValueList = [];
		let coreList = [];
		let curConfigInfo;
		let 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: any) {
				let 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:any,value:any) {
			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) {
			let 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) {
				let 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) {
			let matchedCore = _.find(configInfo.cores, function(curCore:any) {
				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
		};
	}

})();
