/*
 *                                                                            
 *  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 2.0        
 *  which accompanies this distribution, and is available at                  
 *  https://www.eclipse.org/legal/epl-2.0/                                 
 *                                 
 *  SPDX-License-Identifier: EPL-2.0                                 
 *                                                                            
 *  Initial contribution:                                                      
 *     Loetz GmbH & Co. KG
 * 
 */
package org.eclipse.osbp.abstractstatemachine;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import org.eclipse.osbp.ui.api.statemachine.IEventSource;
import org.eclipse.osbp.ui.api.statemachine.IStateMachine;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService.ThemeResourceType;

import com.vaadin.server.Resource;

public abstract class AbstractEventSource extends
		AbstractStateMachineParticipant implements IEventSource,
		IEventSource.Enabler {

	protected boolean ready;

	@Override
	public void init() {
	}

	@Override
	public void setStatemachine(IStateMachine statemachine) {
		super.setStatemachine(statemachine);
		statemachine.registerEnabler(this);
	}

	@Override
	public void enable(IEventSource.Enabler listener, String id, Boolean enabled) {
		Method method = setter(listener, id + "Enabled", Boolean.class);
		if (method == null) {
			return;
		}
		try {
			method.invoke(listener, enabled);
		} catch (IllegalAccessException | IllegalArgumentException
				| InvocationTargetException e) {
			LOGGER.error("{}", e);
			return;
		}
	}

	@Override
	public void append(Enabler listener, String id, String key) {
		Method get = getter(listener, id);
		Class<?> retType = getReturnType(listener, id);
		if (get == null) {
			return;
		}
		try {
			Object content = get.invoke(listener);
			if (retType.isAssignableFrom(String.class)) {
				String got = null;
				if(content != null) {
					got = (String)content;
					if(got.contains(".") && ".".equals(key)) {
						got = got.substring(0, got.indexOf(key)) + key;
					} else {
						got += key;
					}
				} else {
					got = key;
				}
				setter(listener, id, String.class).invoke(listener, got);
			} else if (retType.isAssignableFrom(Double.class)) {
			} else {
				return;
			}
		} catch (IllegalAccessException | IllegalArgumentException
				| InvocationTargetException e) {
			LOGGER.error("{}", e);
		}
	}

	@Override
	public void remove(Enabler listener, String id, int pos) {
		Method get = getter(listener, id);
		Method set = setter(listener, id, String.class);
		if (get == null || set == null) {
			return;
		}
		try {
			String got = (String) get.invoke(listener);
			if (got == null || got.isEmpty()) {
				return;
			}
			if (pos > got.length() - 1 || pos < 0) {
				set.invoke(listener, got.substring(0, got.length() - 1));
			} else {
				set.invoke(listener,
						got.substring(0, pos - 1) + got.substring(pos + 1));
			}
		} catch (IllegalAccessException | IllegalArgumentException
				| InvocationTargetException e) {
			LOGGER.error("{}", e);
		}
	}

	@Override
	public void caption(IEventSource.Enabler listener, String id, String value) {
		Method method = setter(listener, id+"Caption", String.class);
		if (method == null) {
			return;
		}
		try {
			method.invoke(listener, value);
		} catch (IllegalAccessException | IllegalArgumentException
				| InvocationTargetException e) {
			return;
		}
	}

	@Override
	public void image(IEventSource.Enabler listener, String id, String imageName) {
		Method method = setter(listener, id + "Image", Object.class);
		if (method == null || statemachine == null) {
			return;
		}
		try {
			Resource resource = statemachine.getThemeResourceService().getThemeResource(
					imageName, ThemeResourceType.ICON);
			method.invoke(listener, (Object) resource);
		} catch (IllegalAccessException | IllegalArgumentException
				| InvocationTargetException e) {
			LOGGER.error("{}", e);
			return;
		}
	}

}
