/*
 * ! ${copyright}
 */
sap.ui.define([
	"sap/ui/mdc/odata/v4/FilterBarDelegate",
	'sap/ui/base/ManagedObjectObserver'
], function(FilterBarDelegate, ManagedObjectObserver) {
	"use strict";

	/**
	 * Helper class for sap.ui.mdc.filterbar.vh.GenericFilterBarDelegate.
	*  This GenericFilterbarDelegate creates the propertyInfo based on the FilterItems of the Filterbar and does NOT load and analyse any metadata!
	 * <h3><b>Note:</b></h3>
	 * The class is experimental and the API/behaviour is not finalised and hence this should not be used for productive usage.
	 *
	 * @author SAP SE
	 * @private
	 * @experimental
	 * @since 1.86
	 * @alias sap.ui.mdc.filterbar.vh.GenericFilterBarDelegate
	 */
	var GenericFilterBarDelegate = Object.assign({}, FilterBarDelegate);

	/**
	 * Fetches the relevant metadata (from the FilterItems of the FiterBar) for the FilterBar and returns property info array
	 *
	 * @param {Object} oFilterBar - instance of the valuehelp FilterBar
	 * @returns {Array} array of property info
	 */
	GenericFilterBarDelegate.fetchProperties = function(oFilterBar) {
		if (!oFilterBar.__oObserver) {
			oFilterBar.__oObserver = new ManagedObjectObserver(_observeChanges);
			oFilterBar.__oObserver.observe(oFilterBar, {
				aggregations: ["filterItems"]
			});
		}

		return new Promise(function(fResolve) {
			var aFilterItems = oFilterBar.getFilterItems();
			oFilterBar.__aProperties = [];
			aFilterItems.forEach(function(oFF){
				addFilterField(oFF, oFilterBar.__aProperties);
			});

			fResolve(oFilterBar.__aProperties);
		});

	};

	function addFilterField(oFF, aProperties) {
		var sPath = oFF.getBindingPath("conditions");
		if (!sPath) {
			return;
		}
		var aPathParts = sPath.split("/");
		var sFieldPath = aPathParts[aPathParts.length - 1];

		aProperties.push({
			name: sFieldPath,
			label: oFF.getLabel() || sFieldPath,
			type: oFF.getDataType(),
			formatOptions: oFF.getDataTypeFormatOptions(),
			constraints: oFF.getDataTypeConstraints(),
			typeConfig: oFF._getFormatOptions().delegate.getTypeUtil().getTypeConfig(oFF.getDataType(), oFF.getDataTypeFormatOptions(), oFF.getDataTypeConstraints()),
			required: oFF.getRequired(),
			hiddenFilter: false,
			visible: oFF.getVisible(),
			maxConditions : oFF.getMaxConditions(),
			fieldHelp: oFF.getFieldHelp()
		});
	}

	function removeFilterField(oFF, aProperties) {
		var sPath = oFF.getBindingPath("conditions");
		if (!sPath) {
			return;
		}

		function _getProperty(sName) {
			var oNamedProperty = null;
			aProperties.some(function(oProperty) {
				if (oProperty.name === sName) {
					oNamedProperty = oProperty;
				}
				return oNamedProperty !== null;
			});

			return oNamedProperty;
		}

		function _removeProperty(sName) {
			var nIdx = -1;
			aProperties.some(function(oProperty, index) {
				if (oProperty.name === sName) {
					nIdx = index;
				}
				return nIdx !== -1;
			});

			if (nIdx >= 0) {
				aProperties.splice(nIdx, 1);
			}

			return nIdx;
		}

		var aPathParts = sPath.split("/");
		var sFieldPath = aPathParts[aPathParts.length - 1];
		if (_getProperty(sFieldPath)) {
			_removeProperty(sFieldPath);
		}
	}



	function _observeChanges(oChanges) {
		var oFilterBar, aProperties;

		if (oChanges.name === "filterItems") {
			if (oChanges.mutation === "insert") {
				var oNewFF = oChanges.child;
				oFilterBar = oNewFF.getParent();
				aProperties = oFilterBar.__aProperties;
				addFilterField(oNewFF, aProperties);
				return;
			}
			if (oChanges.mutation === "remove") {
				var oRemoveFF = oChanges.child;
				oFilterBar = oRemoveFF.getParent();
				aProperties = oFilterBar.__aProperties;
				removeFilterField(oRemoveFF, aProperties);
				return;
			}
		}
	}

	GenericFilterBarDelegate.cleanup = function(oFilterBar) {

		if (oFilterBar.__oObserver) {
			oFilterBar.__oObserver.disconnect();
			delete oFilterBar.__oObserver;
			delete oFilterBar.__aProperties;
		}

	};

	return GenericFilterBarDelegate;
});

@@ -1182,16 +1182,27 @@
 eChanges
+.bind(this)
 );%0A%09%09%09oF
@@ -1470,25 +1470,36 @@
 dFilterField
-(
+.call(this, 
 oFF, oFilter
@@ -1518,24 +1518,35 @@
 rties);%0A%09%09%09%7D
+.bind(this)
 );%0A%0A%09%09%09fReso
@@ -1579,16 +1579,27 @@
 es);%0A%09%09%7D
+.bind(this)
 );%0A%0A%09%7D;%0A
@@ -2040,40 +2040,12 @@
 ig: 
-oFF._getFormatOptions().delegate
+this
 .get
@@ -3433,17 +3433,28 @@
 terField
-(
+.call(this, 
 oNewFF, 

change delegate propagation