/*******************************************************************************
 * Copyright (c) 2000, 2010 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ui.texteditor;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.ListenerList;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;


/**
 * Preference store that composes multiple preference stores in a
 * chain and serves a preference value from the first preference store in the
 * chain that contains the preference.
 * <p>
 * This preference store is read-only i.e. write access
 * throws an {@link java.lang.UnsupportedOperationException}.</p>
 *
 * @since 3.0
 */
public class ChainedPreferenceStore implements IPreferenceStore {

	/** Child preference stores. */
	private IPreferenceStore[] fPreferenceStores;

	/** Listeners on this chained preference store. */
	private ListenerList fClientListeners= new ListenerList(ListenerList.IDENTITY);

	/** Listeners on the child preference stores. */
	private List<PropertyChangeListener> fChildListeners= new ArrayList<>();

	/**
	 * Listener on the chained preference stores. Forwards only the events
	 * that are visible to clients.
	 */
	private class PropertyChangeListener implements IPropertyChangeListener {

		/** Preference store to listen too. */
		private IPreferenceStore fPreferenceStore;

		/**
		 * Initialize with the given preference store.
		 *
		 * @param preferenceStore the preference store
		 */
		public PropertyChangeListener(IPreferenceStore preferenceStore) {
			setPreferenceStore(preferenceStore);
		}

		@Override
		public void propertyChange(PropertyChangeEvent event) {
			IPreferenceStore childPreferenceStore= getPreferenceStore();
			handlePropertyChangeEvent(childPreferenceStore, event);
		}

		/**
		 * Registers this listener on the preference store.
		 */
		public void register() {
			getPreferenceStore().addPropertyChangeListener(this);
		}

		/**
		 * Unregisters this listener from the preference store.
		 */
		public void unregister() {
			getPreferenceStore().removePropertyChangeListener(this);
		}

		/**
		 * Returns the preference store.
		 *
		 * @return the preference store
		 */
		public IPreferenceStore getPreferenceStore() {
			return fPreferenceStore;
		}

		/**
		 * Sets the preference store.
		 *
		 * @param preferenceStore the preference store to set
		 */
		public void setPreferenceStore(IPreferenceStore preferenceStore) {
			fPreferenceStore= preferenceStore;
		}

	}

	/**
	 * Sets the chained preference stores.
	 *
	 * @param preferenceStores the chained preference stores to set
	 */
	public ChainedPreferenceStore(IPreferenceStore[] preferenceStores) {
		Assert.isTrue(preferenceStores != null && preferenceStores.length > 0);
		fPreferenceStores= new IPreferenceStore[preferenceStores.length];
		System.arraycopy(preferenceStores, 0, fPreferenceStores, 0, preferenceStores.length);
		// Create listeners
		for (int i= 0, length= fPreferenceStores.length; i < length; i++) {
			PropertyChangeListener listener= new PropertyChangeListener(fPreferenceStores[i]);
			fChildListeners.add(listener);
		}
	}

	@Override
	public void addPropertyChangeListener(IPropertyChangeListener listener) {
		if (fClientListeners.size() == 0) {
			registerChildListeners();
		}
		fClientListeners.add(listener);
	}

	@Override
	public void removePropertyChangeListener(IPropertyChangeListener listener) {
		fClientListeners.remove(listener);
		if (fClientListeners.size() == 0) {
			unregisterChildListeners();
		}
	}

	@Override
	public boolean contains(String name) {
		return getVisibleStore(name) != null;
	}

	@Override
	public void firePropertyChangeEvent(String name, Object oldValue, Object newValue) {
		firePropertyChangeEvent(new PropertyChangeEvent(this, name, oldValue, newValue));
	}

	/**
	 * Fire the given property change event.
	 *
	 * @param event the property change event
	 */
	private void firePropertyChangeEvent(PropertyChangeEvent event) {
		Object[] listeners= fClientListeners.getListeners();
		for (int i= 0; i < listeners.length; i++)
			 ((IPropertyChangeListener) listeners[i]).propertyChange(event);
	}

	@Override
	public boolean getBoolean(String name) {
		IPreferenceStore visibleStore= getVisibleStore(name);
		if (visibleStore != null)
			return visibleStore.getBoolean(name);
		return BOOLEAN_DEFAULT_DEFAULT;
	}

	@Override
	public boolean getDefaultBoolean(String name) {
		IPreferenceStore visibleStore= getVisibleStore(name);
		if (visibleStore != null)
			return visibleStore.getDefaultBoolean(name);
		return BOOLEAN_DEFAULT_DEFAULT;
	}

	@Override
	public double getDefaultDouble(String name) {
		IPreferenceStore visibleStore= getVisibleStore(name);
		if (visibleStore != null)
			return visibleStore.getDefaultDouble(name);
		return DOUBLE_DEFAULT_DEFAULT;
	}

	@Override
	public float getDefaultFloat(String name) {
		IPreferenceStore visibleStore= getVisibleStore(name);
		if (visibleStore != null)
			return visibleStore.getDefaultFloat(name);
		return FLOAT_DEFAULT_DEFAULT;
	}

	@Override
	public int getDefaultInt(String name) {
		IPreferenceStore visibleStore= getVisibleStore(name);
		if (visibleStore != null)
			return visibleStore.getDefaultInt(name);
		return INT_DEFAULT_DEFAULT;
	}

	@Override
	public long getDefaultLong(String name) {
		IPreferenceStore visibleStore= getVisibleStore(name);
		if (visibleStore != null)
			return visibleStore.getDefaultLong(name);
		return LONG_DEFAULT_DEFAULT;
	}

	@Override
	public String getDefaultString(String name) {
		IPreferenceStore visibleStore= getVisibleStore(name);
		if (visibleStore != null)
			return visibleStore.getDefaultString(name);
		return STRING_DEFAULT_DEFAULT;
	}

	@Override
	public double getDouble(String name) {
		IPreferenceStore visibleStore= getVisibleStore(name);
		if (visibleStore != null)
			return visibleStore.getDouble(name);
		return DOUBLE_DEFAULT_DEFAULT;
	}

	@Override
	public float getFloat(String name) {
		IPreferenceStore visibleStore= getVisibleStore(name);
		if (visibleStore != null)
			return visibleStore.getFloat(name);
		return FLOAT_DEFAULT_DEFAULT;
	}

	@Override
	public int getInt(String name) {
		IPreferenceStore visibleStore= getVisibleStore(name);
		if (visibleStore != null)
			return visibleStore.getInt(name);
		return INT_DEFAULT_DEFAULT;
	}

	@Override
	public long getLong(String name) {
		IPreferenceStore visibleStore= getVisibleStore(name);
		if (visibleStore != null)
			return visibleStore.getLong(name);
		return LONG_DEFAULT_DEFAULT;
	}

	@Override
	public String getString(String name) {
		IPreferenceStore visibleStore= getVisibleStore(name);
		if (visibleStore != null)
			return visibleStore.getString(name);
		return STRING_DEFAULT_DEFAULT;
	}

	@Override
	public boolean isDefault(String name) {
		IPreferenceStore visibleStore= getVisibleStore(name);
		if (visibleStore != null)
			return visibleStore.isDefault(name);
		return false;
	}

	@Override
	public boolean needsSaving() {
		throw new UnsupportedOperationException();
	}

	@Override
	public void putValue(String name, String value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setDefault(String name, double value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setDefault(String name, float value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setDefault(String name, int value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setDefault(String name, long value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setDefault(String name, String defaultObject) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setDefault(String name, boolean value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setToDefault(String name) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setValue(String name, double value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setValue(String name, float value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setValue(String name, int value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setValue(String name, long value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setValue(String name, String value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public void setValue(String name, boolean value) {
		throw new UnsupportedOperationException();
	}

	/**
	 * Handle property change event from the child listener with the given child preference store.
	 *
	 * @param childPreferenceStore the child preference store
	 * @param event the event
	 */
	private void handlePropertyChangeEvent(IPreferenceStore childPreferenceStore, PropertyChangeEvent event) {
		String property= event.getProperty();
		Object oldValue= event.getOldValue();
		Object newValue= event.getNewValue();

		IPreferenceStore visibleStore= getVisibleStore(property);

		/*
		 * Assume that the property is there but has no default value (its owner relies on the default-default value)
		 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=52827
		 */
		if (visibleStore == null && newValue != null)
			visibleStore= childPreferenceStore;

		if (visibleStore == null) {
			// no visible store
			if (oldValue != null)
				// removal in child, last in chain -> removal in this chained preference store
				firePropertyChangeEvent(event);
		} else if (visibleStore == childPreferenceStore) {
			// event from visible store
			if (oldValue != null) {
				// change in child, visible store -> change in this chained preference store
				firePropertyChangeEvent(event);
			} else {
				// insertion in child
				IPreferenceStore oldVisibleStore= null;
				int i= 0;
				int length= fPreferenceStores.length;
				while (i < length && fPreferenceStores[i++] != visibleStore) {
					// do nothing
				}
				while (oldVisibleStore == null && i < length) {
					if (fPreferenceStores[i].contains(property))
						oldVisibleStore= fPreferenceStores[i];
					i++;
				}

				if (oldVisibleStore == null) {
					// insertion in child, first in chain -> insertion in this chained preference store
					firePropertyChangeEvent(event);
				} else {
					// insertion in child, not first in chain
					oldValue= getOtherValue(property, oldVisibleStore, newValue);
					if (!oldValue.equals(newValue))
						// insertion in child, different old value -> change in this chained preference store
						firePropertyChangeEvent(property, oldValue, newValue);
					// else: insertion in child, same old value -> no change in this chained preference store
				}
			}
		} else {
			// event from other than the visible store
			boolean eventBeforeVisibleStore= false;
			for (int i= 0, length= fPreferenceStores.length; i < length; i++) {
				IPreferenceStore store= fPreferenceStores[i];
				if (store == visibleStore)
					break;
				if (store == childPreferenceStore) {
					eventBeforeVisibleStore= true;
					break;
				}
			}

			if (eventBeforeVisibleStore) {
				// removal in child, before visible store

				/*
				 * The original event's new value can be non-null (removed assertion).
				 * see https://bugs.eclipse.org/bugs/show_bug.cgi?id=69419
				 */

				newValue= getOtherValue(property, visibleStore, oldValue);
				if (!newValue.equals(oldValue))
					// removal in child, before visible store, different old value -> change in this chained preference store
					firePropertyChangeEvent(property, oldValue, newValue);
				// else: removal in child, before visible store, same old value -> no change in this chained preference store
			}
			// else: event behind visible store -> no change in this chained preference store
		}
	}

	/**
	 * Returns an object of the same dynamic type as <code>thisValue</code>, the returned object
	 * encapsulates the value of the <code>property</code> from the preference <code>store</code>.
	 *
	 * @param property the name of the considered property
	 * @param store the preference store
	 * @param thisValue the given value
	 * @return the other value
	 */
	private Object getOtherValue(String property, IPreferenceStore store, Object thisValue) {

		if (thisValue instanceof Boolean)
			return store.getBoolean(property) ? Boolean.TRUE : Boolean.FALSE;
		else if (thisValue instanceof Double)
			return new Double(store.getDouble(property));
		else if (thisValue instanceof Float)
			return new Float(store.getFloat(property));
		else if (thisValue instanceof Integer)
			return new Integer(store.getInt(property));
		else if (thisValue instanceof Long)
			return new Long(store.getLong(property));
		else if (thisValue instanceof String)
			return store.getString(property);

		return store.getString(property);
	}

	/**
	 * Returns the preference store from which the given property's value
	 * is visible.
	 *
	 * @param property the name of the property
	 * @return the preference store from which the property's value is visible,
	 * 	<code>null</code> if the property is unknown
	 */
	private IPreferenceStore getVisibleStore(String property) {
		IPreferenceStore visibleStore= null;

		for (int i= 0, length= fPreferenceStores.length; i < length && visibleStore == null; i++) {
			IPreferenceStore store= fPreferenceStores[i];
			if (store.contains(property))
				visibleStore= store;
		}
		return visibleStore;
	}

	/**
	 * Register the child listeners on the child preference stores.
	 */
	private void registerChildListeners() {
		Iterator<PropertyChangeListener> iter= fChildListeners.iterator();
		while (iter.hasNext()) {
			PropertyChangeListener listener= iter.next();
			listener.register();
		}
	}

	/**
	 * Unregister the child listeners from the child preference stores.
	 */
	private void unregisterChildListeners() {
		Iterator<PropertyChangeListener> iter= fChildListeners.iterator();
		while (iter.hasNext()) {
			PropertyChangeListener listener= iter.next();
			listener.unregister();
		}
	}
}
