package org.seasar.jsf.component;

import java.util.ArrayList;
import java.util.List;

import javax.faces.component.UIComponentBase;
import javax.faces.context.FacesContext;

import org.seasar.framework.beans.BeanDesc;
import org.seasar.framework.beans.PropertyDesc;
import org.seasar.framework.beans.factory.BeanDescFactory;
import org.seasar.jsf.util.BindingUtil;

/**
 * @author higa
 *  
 */
public class UIElement extends UIComponentBase {

	public static final String COMPONENT_TYPE = "org.seasar.jsf.Element";

	public static final String COMPONENT_FAMILY = "javax.faces.Output";

	public static final String DEFAULT_RENDERER_TYPE = "org.seasar.jsf.Element";

	private String tagName;
	
	private List bindingPropertyNames = new ArrayList();
	
	private BeanDesc beanDesc;

	public UIElement() {
		setRendererType(DEFAULT_RENDERER_TYPE);
		beanDesc = BeanDescFactory.getBeanDesc(getClass());
	}

	/**
	 * @see javax.faces.component.UIComponent#getFamily()
	 */
	public String getFamily() {
		return COMPONENT_FAMILY;
	}
	
	public String getTagName() {
		return tagName;
	}
	
	public void setTagName(String tagName) {
		this.tagName = tagName;
	}
	
	public void setAttribute(String name, String value) {
		if (BindingUtil.isValueReference(value)) {
			BindingUtil.setValueBinding(this, name, value);
			bindingPropertyNames.add(name);
		} else {
			if (beanDesc.hasPropertyDesc(name)) {
				PropertyDesc pd = beanDesc.getPropertyDesc(name);
				if (pd.hasWriteMethod()) {
					pd.setValue(this, value);
				}
			} else {
				getAttributes().put(name, value);
			}
		}
	}
	
	public String[] getBindingPropertyNames() {
		return (String[]) bindingPropertyNames.toArray(new String[bindingPropertyNames.size()]);
	}

	public Object saveState(FacesContext context) {
		Object[] values = new Object[3];
		values[0] = super.saveState(context);
		values[1] = tagName;
		values[2] = bindingPropertyNames;
		return values;
	}

	public void restoreState(FacesContext context, Object state) {
		Object values[] = (Object[]) state;
		super.restoreState(context, values[0]);
		tagName = (String) values[1];
		bindingPropertyNames = (List) values[2];
	}
}