/*******************************************************************************
 * Copyright (c) 2005 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.jface.internal.databinding.beans;

import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;


/**
 * This is a helper that will hook up and listen for <code>PropertyChangeEvent</code> events
 * for a set of target JavaBeans
 * 
 * @since 3.2
 */
public class ListenerSupport {

	/**
	 * @since 3.2
	 */
	 static class IdentityWrapper {
		final Object o;
		IdentityWrapper(Object o) {
			this.o = o;
		}
		public boolean equals(Object obj) {
			if(obj.getClass()!=IdentityWrapper.class) {
				return false;
			}
			return o==((IdentityWrapper)obj).o;
		}
		public int hashCode() {
			return System.identityHashCode(o);
		}
	}
	
	private Set elementsListenedTo = new HashSet();
	
	private PropertyChangeListener listener;
	
	/**
	 * @param listener is the callback that will be called
	 * 		when a <code>PropertyChangeEvent</code> is fired on any
	 * 		of the target objects.
	 */
	public ListenerSupport (PropertyChangeListener listener) {
		this.listener=listener;
	}
	
	
	/**
	 * Start listen to target (if it supports the JavaBean property change listener pattern)
	 * 
	 * @param target
	 */
	public void hookListener(Object target) {
		Method addPropertyChangeListenerMethod = null;
		try {
			addPropertyChangeListenerMethod = target.getClass().getMethod(
					"addPropertyChangeListener", //$NON-NLS-1$
					new Class[] { PropertyChangeListener.class });
		} catch (SecurityException e) {
			// ignore
		} catch (NoSuchMethodException e) {
			// ignore
		}
		if (addPropertyChangeListenerMethod != null) {
			try {
				addPropertyChangeListenerMethod.invoke(target,
						new Object[] { listener });
				elementsListenedTo.add(new IdentityWrapper(target));
				return;
			} catch (IllegalArgumentException e) {
				// ignore
			} catch (IllegalAccessException e) {
				// ignore
			} catch (InvocationTargetException e) {
				// ignore
			}
		}
	}
		
	/**
	 * Add listeners for new targets (those this instance of<code>ListenerSupport</code> does not 
	 * already listen to),
	 * Stop to listen to those object that this instance listen to and is one of the object in targets 
	 * 
	 * @param targets 
	 */
	public void setHookTargets(Object[] targets) {		
		Set elementsToUnhook = new HashSet(elementsListenedTo);
		if (targets!=null) {
			for (int i = 0; i < targets.length; i++) {
				Object newValue = targets[i];
				IdentityWrapper identityWrapper = new IdentityWrapper(newValue);
				if(!elementsToUnhook.remove(identityWrapper)) 				
					hookListener(newValue);
			}
		}
			
		for (Iterator it = elementsToUnhook.iterator(); it.hasNext();) {
			Object o = it.next();
			if (o.getClass()!=IdentityWrapper.class)
				o = new IdentityWrapper(o);
			elementsListenedTo.remove(o);
			unhookListener(o);
		}							
	}
	
	/**
	 * Stop listen to target
	 * 
	 * @param target
	 */
	public void unhookListener(Object target) {
		if (target.getClass()==IdentityWrapper.class)
			target = ((IdentityWrapper)target).o;
		
		Method removePropertyChangeListenerMethod = null;
		try {
			removePropertyChangeListenerMethod = target.getClass().getMethod(
					"removePropertyChangeListener", //$NON-NLS-1$
					new Class[] { PropertyChangeListener.class });
		} catch (SecurityException e) {
			// ignore
		} catch (NoSuchMethodException e) {
			// ignore
		}
		if (removePropertyChangeListenerMethod != null) {
			try {
				removePropertyChangeListenerMethod.invoke(target,
						new Object[] { listener });
				elementsListenedTo.remove(new IdentityWrapper(target));
				return;
			} catch (IllegalArgumentException e) {
				// ignore
			} catch (IllegalAccessException e) {
				// ignore
			} catch (InvocationTargetException e) {
				// ignore
			}
		}
	}
	
	
	/**
	 * 
	 */
	public void dispose() {
		if (elementsListenedTo!=null) {
			Object[] targets = elementsListenedTo.toArray();		
			for (int i = 0; i < targets.length; i++) {		
				unhookListener(targets[i]);
			}			
			elementsListenedTo=null;
			listener=null;
		}
	}
	
	/**
	 * @return elements that were registred to
	 */
	public Object[] getHookedTargets() {
		Object[] targets = null;
		if (elementsListenedTo!=null && elementsListenedTo.size()>0) {
			Object[] identityList = elementsListenedTo.toArray();
			targets = new Object[identityList.length];
			for (int i = 0; i < identityList.length; i++) 
				targets[i]=((IdentityWrapper)identityList[i]).o;							
		}
		return targets;
	}
}
