/**
 *                                                                            
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 *                                                                            
 * 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:   
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation 
 */
package org.eclipse.osbp.osgi.hybrid.api;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.vaadin.event.FieldEvents.BlurEvent;
import com.vaadin.event.FieldEvents.BlurListener;
import com.vaadin.event.FieldEvents.BlurNotifier;
import com.vaadin.event.FieldEvents.FocusEvent;
import com.vaadin.event.FieldEvents.FocusListener;
import com.vaadin.event.FieldEvents.FocusNotifier;
import com.vaadin.server.AbstractClientConnector;
import com.vaadin.ui.AbstractComponent;
import com.vaadin.ui.AbstractComponentContainer;
import com.vaadin.ui.AbstractLayout;
import com.vaadin.ui.Component;
import com.vaadin.ui.HasComponents;
import com.vaadin.ui.HasComponents.ComponentAttachDetachNotifier;
import com.vaadin.ui.HasComponents.ComponentAttachEvent;
import com.vaadin.ui.HasComponents.ComponentAttachListener;
import com.vaadin.ui.HasComponents.ComponentDetachEvent;
import com.vaadin.ui.HasComponents.ComponentDetachListener;

import org.eclipse.osbp.utils.theme.EnumCssClass;


public class RecursiveFocusBlurListener implements ComponentAttachListener, ComponentDetachListener {

	private static final Logger LOGGER = LoggerFactory.getLogger(RecursiveFocusBlurListener.class);
	private AbstractComponentContainer fParent;
	
	protected RecursiveFocusBlurListener(AbstractComponentContainer container) {
		fParent = container;
	}
	
	public static RecursiveFocusBlurListener attachFor(AbstractComponentContainer container) {
		RecursiveFocusBlurListener listener = new RecursiveFocusBlurListener(container);
		listener.recursiveAddComponentAttachDetachListener(container);
		listener.recursiveAddFocusBlurListener(container);
		return listener;
	}

	public void detach() {
		recursiveRemoveComponentAttachDetachListener(fParent);
		recursiveRemoveFocusBlurListener(fParent);
	}

	private FocusListener fFocusListener = new FocusListener() {
		@Override
		public void focus(FocusEvent event) {
			if	(event.getComponent() instanceof AbstractComponent) {
				AbstractComponent component = (AbstractComponent) event.getComponent();
				recursiveFocus((AbstractComponent)event.getComponent());
			}
		}
	};

	private void recursiveFocus(AbstractComponent component) {
		if	(component != null) {
			component.addStyleName(EnumCssClass.HAS_FOCUS.styleName());
			if	(!component.equals(fParent) && (component.getParent() instanceof AbstractComponent)) {
				recursiveFocus((AbstractComponent)component.getParent());
			}
		}
	}

	private BlurListener fBlurListener = new BlurListener() {
		@Override
		public void blur(BlurEvent event) {
			if	(event.getComponent() instanceof AbstractComponent) {
				AbstractComponent component = (AbstractComponent) event.getComponent();
				recursiveBlur((AbstractComponent)event.getComponent());
			}
		}
	};

	private void recursiveBlur(AbstractComponent component) {
		if	(component != null) {
			component.removeStyleName(EnumCssClass.HAS_FOCUS.styleName());
			if	(!component.equals(fParent) && (component.getParent() instanceof AbstractComponent)) {
				recursiveBlur((AbstractComponent)component.getParent());
			}
		}
	}
	
	private static final long serialVersionUID = 3497317619845108761L;
	
	@Override
	public void componentAttachedToContainer(ComponentAttachEvent event) {
		if	(event.getAttachedComponent() instanceof ComponentAttachDetachNotifier) {
			recursiveAddComponentAttachDetachListener((ComponentAttachDetachNotifier)event.getAttachedComponent());
		}
		if	(event.getAttachedComponent() instanceof AbstractClientConnector) {
			recursiveAddFocusBlurListener((AbstractClientConnector)event.getAttachedComponent());
		}
	}

	@Override
	public void componentDetachedFromContainer(ComponentDetachEvent event) {
		if	(event.getDetachedComponent() instanceof ComponentAttachDetachNotifier) {
			recursiveRemoveComponentAttachDetachListener((ComponentAttachDetachNotifier)event.getDetachedComponent());
		}
		if	(event.getDetachedComponent() instanceof AbstractComponent) {
			recursiveRemoveFocusBlurListener((AbstractComponent)event.getDetachedComponent());
		}
	}
	
	private void recursiveAddComponentAttachDetachListener(ComponentAttachDetachNotifier container) {
		AbstractComponent ccontainer = (AbstractComponent) container;
		//ccontainer.setImmediate(true);
		Collection<?> attachListeners = ccontainer.getListeners(ComponentAttachEvent.class);
		if	(!attachListeners.contains(this)) {
			container.addComponentAttachListener(this);
		}
		Collection<?> detachListeners = ccontainer.getListeners(ComponentDetachEvent.class);
		if	(!detachListeners.contains(this)) {
			container.addComponentAttachListener(this);
		}
		if	(container instanceof HasComponents) {
			Iterator<Component> iterator = ((HasComponents)container).iterator();
			while	(iterator.hasNext()) {
				Component component = iterator.next();
				if	(component instanceof ComponentAttachDetachNotifier) {
					recursiveAddComponentAttachDetachListener((ComponentAttachDetachNotifier)component);
				}
			}
		}
	}
	
	private void recursiveRemoveComponentAttachDetachListener(ComponentAttachDetachNotifier container) {
		container.removeComponentAttachListener(this);
		container.removeComponentAttachListener(this);
		if	(container instanceof HasComponents) {
			Iterator<Component> iterator = ((HasComponents)container).iterator();
			while	(iterator.hasNext()) {
				Component component = iterator.next();
				if	(component instanceof AbstractComponentContainer) {
					recursiveRemoveComponentAttachDetachListener((AbstractComponentContainer)component);
				}
			}
		}
	}

	private Map<Class<?>,Method> fAddFocusListenerMethods = new HashMap<>(); 
	private Map<Class<?>,Method> fRemoveFocusListenerMethods = new HashMap<>(); 
	private Map<Class<?>,Method> fAddBlurListenerMethods = new HashMap<>(); 
	private Map<Class<?>,Method> fRemoveBlurListenerMethods = new HashMap<>(); 
	
	private static Set<String> fFocusListenerLogList = new HashSet<>(); 
	private static Set<String> fBlurListenerLogList = new HashSet<>(); 

	private void addFocusListener(AbstractClientConnector component) {
		Method addFocusListenerMethod = fAddFocusListenerMethods.get(component.getClass());
		if	(addFocusListenerMethod == null) {
			try {
				addFocusListenerMethod = component.getClass().getDeclaredMethod("addFocusListener", FocusListener.class);
				if	(addFocusListenerMethod != null) {
					fAddFocusListenerMethods.put(component.getClass(), addFocusListenerMethod);
					Method removeFocusListenerMethod = component.getClass().getDeclaredMethod("removeFocusListener", FocusListener.class);
					if	(removeFocusListenerMethod != null) {
						fRemoveFocusListenerMethods.put(component.getClass(), removeFocusListenerMethod);
					}
				}
			}
			catch (NoSuchMethodException | SecurityException e) {
			}
		}
		String className = component.getClass().getCanonicalName();
		if	(fFocusListenerLogList.contains(className)) {
			className = null;
		}
		else {
			fFocusListenerLogList.add(className);
		}
		if	(addFocusListenerMethod != null) {
			try {
				addFocusListenerMethod.invoke(component, new Object[] {fFocusListener});
			}
			catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				if	((className != null) && LOGGER.isWarnEnabled()) { LOGGER.warn("focuL: "+className+" could not invoke "+e.getLocalizedMessage()); }
			}
		}
		else {
			if	(!(component instanceof AbstractLayout)) {
				if	((className != null) && LOGGER.isWarnEnabled()) { LOGGER.warn("focuL: "+className+" DOESN'T IMPLEMENT FocusNotifier"); }
			}
		}
	}
	
	private void addBlurListener(AbstractClientConnector component) {
		Method addBlurListenerMethod = fAddBlurListenerMethods.get(component.getClass());
		if	(addBlurListenerMethod == null) {
			try {
				addBlurListenerMethod = component.getClass().getDeclaredMethod("addBlurListener", BlurListener.class);
				if	(addBlurListenerMethod != null) {
					fAddBlurListenerMethods.put(component.getClass(), addBlurListenerMethod);
					Method removeBlurListenerMethod = component.getClass().getDeclaredMethod("removeBlurListener", BlurListener.class);
					if	(removeBlurListenerMethod != null) {
						fRemoveBlurListenerMethods.put(component.getClass(), removeBlurListenerMethod);
					}
				}
			}
			catch (NoSuchMethodException | SecurityException e) {
			}
		}
		String className = component.getClass().getCanonicalName();
		if	(fBlurListenerLogList.contains(className)) {
			className = null;
		}
		else {
			fBlurListenerLogList.add(className);
		}
		if	(addBlurListenerMethod != null) {
			try {
				addBlurListenerMethod.invoke(component, new Object[] {fBlurListener});
			}
			catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				if	((className != null) && LOGGER.isWarnEnabled()) { LOGGER.warn("blurL: "+className+" could not invoke "+e.getLocalizedMessage()); }
			}
		}
		else {
			if	(!(component instanceof AbstractLayout)) {
				if	((className != null) && LOGGER.isWarnEnabled()) { LOGGER.warn("blurL: "+className+" DOESN'T IMPLEMENT BlurNotifier"); }
			}
		}
	}
	
	private void recursiveAddFocusBlurListener(AbstractClientConnector component) {
		Collection<?> focusListeners = ((AbstractClientConnector)component).getListeners(FocusEvent.class);
		if	(!focusListeners.contains(fFocusListener)) {
			if	(component instanceof FocusNotifier) {
				((FocusNotifier) component).addFocusListener(fFocusListener);
			}
			else {
				addFocusListener(component);
			}
			if	(component instanceof BlurNotifier) {
				((BlurNotifier) component).addBlurListener(fBlurListener);
			}
			else {
				addBlurListener(component);
			}
		}
		if	(component instanceof AbstractComponentContainer) {
			Iterator<Component> iterator = ((AbstractComponentContainer)component).iterator();
			while	(iterator.hasNext()) {
				Component child = iterator.next();
				if	(component instanceof AbstractClientConnector) {
					recursiveAddFocusBlurListener((AbstractClientConnector)child);
				}
			}
		}
	}
	
	private void recursiveRemoveFocusBlurListener(AbstractClientConnector component) {
		if	(component instanceof FocusNotifier) {
			((FocusNotifier) component).removeFocusListener(fFocusListener);
		}
		else {
			Method removeFocusListenerMethod = fRemoveFocusListenerMethods.get(component.getClass());
			if	(removeFocusListenerMethod != null) {
				try {
					removeFocusListenerMethod.invoke(component, new Object[] {fFocusListener});
				}
				catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				}
			}
		}
		if	(component instanceof BlurNotifier) {
			((BlurNotifier) component).removeBlurListener(fBlurListener);
		}
		else {
			Method removeBlurListenerMethod = fRemoveBlurListenerMethods.get(component.getClass());
			if	(removeBlurListenerMethod != null) {
				try {
					removeBlurListenerMethod.invoke(component, new Object[] {fBlurListener});
				}
				catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				}
			}
		}
		if	(component instanceof HasComponents) {
			Iterator<Component> iterator = ((HasComponents)component).iterator();
			while	(iterator.hasNext()) {
				Component child = iterator.next();
				if	(component instanceof AbstractComponent) {
					recursiveRemoveFocusBlurListener((AbstractComponent)child);
				}
			}
		}
	}
}
