/*******************************************************************************
 * 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.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.eclipse.jface.databinding.BindingException;
import org.eclipse.jface.databinding.ChangeEvent;
import org.eclipse.jface.databinding.IChangeListener;
import org.eclipse.jface.databinding.ITree;
import org.eclipse.jface.databinding.TreeModelDescription;

/**
 * This class is a JavaBean implementation for a ITree.  It is a ITree facade that is built
 * from a <code>TreeModelDescription</code>
 */
public class JavaBeanTree implements ITree {
	
	/**
	 * Keep track of element parents, and children
	 * @since 3.2
	 */
	private class TreeNode {
		private Object parent;
		private List children;
		
		/**
		 * @param parent
		 */
		public TreeNode(Object parent) {
			this.parent=parent;
		}

		/**
		 * @return children
		 */
		public List getChildren() {
			return children==null? Collections.EMPTY_LIST: children;
		}

		/**
		 * @param children
		 */
		public void setChildren(List children) {
			this.children = children;
		}

		/**
		 * @return parent
		 */
		public Object getParent() {
			return parent;
		}
	}
	
	private final static int READ = 0;
	
	private final static int WRITE = 1;

	private TreeModelDescription modelDescription;
	
	private Object[]  rootElements;
	
	private HashMap descriptors = new HashMap();
	
	private ITree.ChangeSupport changeSupport = null;
		
	private HashMap nodes = new HashMap();
	
	private boolean updating = false;
	
	
	private PropertyChangeListener elementListener = new PropertyChangeListener() {
		public void propertyChange(java.beans.PropertyChangeEvent event) {
			if (!updating && changeSupport!=null) {	
				String[] properties = modelDescription.getChildrenProperties(event.getSource().getClass());
				// Determine if the change is on a children Property, in which case
				// that level of the tree has changed.
				if (properties!=null && event.getPropertyName()!=null && 
						Arrays.asList(properties).contains(event.getPropertyName())) {
					// Assume children have changed
					changeSupport.fireTreeChange(ChangeEvent.REPLACE, null, getChildren(event.getSource()), event.getSource(), -1);
				}
				else {
					// Assume a property has changed that may change the way this element
					// is rendered in a viewer, use our tracking to figure out the index.
					TreeNode node = (TreeNode)nodes.get(event.getSource());
					if (node!=null) {
						int index = -1;
						Object[] children = getChildren(node.getParent());
						if (children!=null) {
							index = Arrays.asList(children).indexOf(event.getSource());
						}
						if (index<0) index = ChangeEvent.POSITION_UNKNOWN;
					    changeSupport.fireTreeChange(ChangeEvent.CHANGE, null, event.getSource(), node.getParent(), index);
					}
				}
			}
		}
	};
	
	HashMap listenerSupport = new HashMap();
	
	/**
	 * @param modelDescripton
	 */
	public JavaBeanTree(TreeModelDescription modelDescripton) {
		this.modelDescription = modelDescripton;
		if (modelDescripton.getRoot()==null)
			rootElements = Collections.EMPTY_LIST.toArray();
		else
			rootElements = modelDescripton.getRoot().getClass().isArray()?
				          (Object[]) modelDescripton.getRoot():
				           new Object[] { modelDescripton.getRoot() };
		TreeNode root = new TreeNode(null);
		nodes.put(this, root);
		hookup(null, rootElements);		
	}
	
	
	// pick up the leaf most registered class that is assignable
	// from o.class.
	private Class getRelevantClass(Object o) {
		if (o==null)
			return null;
		Class leafClass = null;
		Class current = o.getClass();
		Class[] list = modelDescription.getTypes();		
		for (int i = 0; i < list.length; i++)
			if (list[i].isAssignableFrom(current)) {
				// found registered class
				if (leafClass==null)
					leafClass=list[i];
				else
					if (leafClass.isAssignableFrom(list[i]))
							leafClass=list[i]; 
			}
		return leafClass;
	}
		
	private Method[] getInvocationMethods(Class clazz, int methodType) {
		if (clazz==null)
			return null;
		String[] childrenProperties = modelDescription
				.getChildrenProperties(clazz);
		if (childrenProperties == null || childrenProperties.length == 0)
			return null;
		
		PropertyHelper[] properties = (PropertyHelper[]) descriptors.get(clazz);
		if (properties == null) {
			List newpProperties = new ArrayList();

			// Walk by properties to preserve the tree order
			for (int i = 0; i < childrenProperties.length; i++) {
				PropertyHelper property = new PropertyHelper(
						childrenProperties[i], clazz);
				if (property.getGetter() != null ||  property.getSetter() != null) {
					newpProperties.add(property);
				}
			}

			properties = (PropertyHelper[]) newpProperties
					.toArray(new PropertyHelper[newpProperties.size()]);
			descriptors.put(clazz, properties);

		}
		List methods = new ArrayList();
		for (int i = 0; i < properties.length; i++) {
			if (methodType==READ)
				methods.add(properties[i].getGetter());
			else
				methods.add(properties[i].getSetter());			
		}		
		return (Method[])methods.toArray(new Method[methods.size()]);
	}
		
	private Method[] getReadMethods(Object element) {		
		Class clazz = getRelevantClass(element);
		if (clazz==null) return null;
		
		Method[] methods = getInvocationMethods(clazz, READ);		
		return methods;
	}
	
	
	private Method[] getWriteMethods (Object element) {
		Class clazz = getRelevantClass(element);
		if (clazz==null) return null;
		Method[] methods = getInvocationMethods(clazz, WRITE);		
		return methods;
	}
	
	private void hookup (Object parent, Object[] children) {
		Object key = parent==null?JavaBeanTree.this:parent;
		
		ListenerSupport support = (ListenerSupport) listenerSupport.get(key);
		if (support==null) {
			support = new ListenerSupport(elementListener);
			listenerSupport.put(key, support);
		}			
		support.setHookTargets(children);
		// Track a child's index
		trackChildren(parent, children);
	}
		
	public Object[] getChildren(Object parentElement) {
		if (parentElement==null) 
			return rootElements;
		
		
		Method[] getters = getReadMethods(parentElement);
		if (getters==null)
			return Collections.EMPTY_LIST.toArray();
		
		List children = new ArrayList();
		
		try {
			for (int i = 0; i < getters.length; i++) {
				Object list = getters[i].invoke(parentElement, new Object[0]);
				if (list!=null) {
					if (getters[i].getReturnType().isArray()) 					
						children.addAll(Arrays.asList((Object[])list));
					else
					    children.addAll((Collection) getters[i].invoke(parentElement, new Object[0]));
				}
			}
		} catch (IllegalArgumentException e) {
			throw new BindingException(e.getLocalizedMessage());	
		} catch (IllegalAccessException e) {
			throw new BindingException(e.getLocalizedMessage());			
		} catch (InvocationTargetException e) {
			throw new BindingException(e.getLocalizedMessage());			
		} 
		Object[] result = children.toArray();
		hookup(parentElement, result);
		trackChildren(parentElement, result);
		return result;
	}
	
	private void trackChildren(Object parentElement, Object[] children) {
		Object key = parentElement==null?JavaBeanTree.this : parentElement;
		TreeNode node = (TreeNode) nodes.get(key);
		Set removed = new HashSet(node.getChildren());
		List newList = children==null? new ArrayList(): Arrays.asList(children);
		if (children!=null)
			for (int i=0; i<children.length; i++) {
				if (!removed.remove(children[i])) {
					// new child
					TreeNode child = new TreeNode(parentElement);
					nodes.put(children[i], child);
				}				
			}
		for (Iterator itr=removed.iterator(); itr.hasNext();)
			nodes.remove(itr.next());
		node.setChildren(newList);
	}

	public void setChildren(Object parentElement, Object[] children) {
		if (parentElement==null) 
			throw new BindingException ("Changing root element/s is not supported"); //$NON-NLS-1$
		
		Method[] setters = getWriteMethods(parentElement);
		// TODO we can try to figure out (by type) which methods to invoke on which object
		if (setters==null || setters.length!=1)
			throw new BindingException("Can not determine children set method for: "+parentElement.getClass().getName()); //$NON-NLS-1$
		
		Method setter = setters[0];
		Class[] parameters = setter.getParameterTypes();
		Object arg;
		if (parameters[0].isArray())
			arg = children;
		else
			arg = Arrays.asList(children);		
		try {
			setter.invoke(parentElement, new Object[] { arg } );
		} catch (IllegalArgumentException e) {
			throw new BindingException(e.getLocalizedMessage());		
		} catch (IllegalAccessException e) {
			throw new BindingException(e.getLocalizedMessage());	
		} catch (InvocationTargetException e) {
			throw new BindingException(e.getLocalizedMessage());	
		}
		hookup(parentElement, children);		
		if (changeSupport!=null)
		   changeSupport.fireTreeChange(ChangeEvent.REPLACE, null, children, parentElement, -1);
	}

	public boolean hasChildren(Object element) {
		Object[] children = getChildren(element);
		return (children!=null && children.length>0);
	}

	public Class[] getTypes() {		
		return modelDescription.getTypes();
	}

	public void addTreeChangeListener(IChangeListener listener) {
		if (listener==null)
			return;
		if (changeSupport==null)
			changeSupport = new ITree.ChangeSupport(this);
		changeSupport.addTreeChangeListener(listener);		
	}

	public void removeTreeChangeListener(IChangeListener listener) {
		if (listener==null || changeSupport==null)
			return;
		
		changeSupport.removeTreeChangeListener(listener);		
	}

	public void dispose() {
		if (listenerSupport!=null) {
		  for (Iterator itr=listenerSupport.values().iterator(); itr.hasNext();) 
		   ((ListenerSupport)itr.next()).dispose();
		  listenerSupport=null;
		  descriptors=null;
		  changeSupport=null;
		  modelDescription=null;
		}
	}



}
