/*
 *                                                                            
 *  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                                 
 *                                                                            
 *  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.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;
		}
	}

}
