package jp.hasc.hasctool.core.blockdiagram.model;

import java.lang.reflect.Constructor;
import java.util.LinkedHashMap;
import java.util.Map;

import jp.hasc.hasctool.core.blockdiagram.BlockDiagramExecutor;
import jp.hasc.hasctool.core.util.CoreUtil;

import org.apache.commons.beanutils.PropertyUtils;

import com.thoughtworks.xstream.annotations.XStreamAlias;

/**
 * @author iwasaki
 */
public class BeanBlock extends AbstractBlock {
	private static final long serialVersionUID = 1L;
	
	@XStreamAlias("class")
	private String runtimeClassName;
	
	private LinkedHashMap<String,Object> properties=null;
	
	public Map<String, Object> properties() {
		return getOrCreateProperties();
	}
	
	public Object getProperty(String name) {
		return getOrCreateProperties().get(name);
	}
	
	private LinkedHashMap<String, Object> getOrCreateProperties() {
		if (properties==null) properties=new LinkedHashMap<String,Object>();
		return properties;
	}

	
	public void setProperty(String name, Object value) {
		if (value==null) {
			getOrCreateProperties().remove(name);
		}else{
			getOrCreateProperties().put(name, value);
		}
	}
	
	public PortReference getPortByName(String name) {
		return new PortReference(getName(), name);
	}

	public PortReference getPortByNameAndIndex(String name, int index) {
		return new PortReference(getName(), name+"["+index+"]");
	}

	@Override
	public Object newRuntimeInstance(BlockDiagramExecutor exec) {
		//
		try {
			// construct
			Class<?> runtimeClass = Class.forName(runtimeClassName);
			Constructor<?> c = runtimeClass.getConstructor();
			Object bean=c.newInstance();
			
			// set properties
			if (properties!=null) {
				for(Map.Entry<String,Object> e:properties.entrySet()) {
					PropertyUtils.setProperty(bean, e.getKey(), e.getValue());
				}
			}
			
			return bean;
		} catch (Exception ex) {
			CoreUtil.throwAsRuntimeException(ex);
			return null;
		}
	}

	public String getRuntimeClassName() {
		return runtimeClassName;
	}

	public void setRuntimeClassName(String className) {
		this.runtimeClassName = className;
	}
	
	// IPropertySource関係は、jp.hasc.hasctool.ui.views.grapheditor.BeanBlockObject へ移動した
}
