package org.seasar.jsf.processor;

import java.util.Map;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.Tag;

import org.seasar.framework.container.S2Container;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;
import org.seasar.jsf.JsfConfig;
import org.seasar.jsf.JsfConstants;
import org.seasar.jsf.JsfContext;
import org.seasar.jsf.TagProcessor;
import org.seasar.jsf.ViewTemplate;
import org.seasar.jsf.ViewTemplateFactory;
import org.seasar.jsf.exception.TagProcessorNotFoundRuntimeException;
import org.xml.sax.Attributes;

/**
 * @author higa
 *  
 */
public class InsertProcessor extends TagProcessorImpl {

	public InsertProcessor(String inject) {
		super(inject);
	}

	public void addChild(TagProcessor child) {
		if (getProperty(JsfConstants.SRC_ATTR) != null) {
			return;
		}
		super.addChild(child);
	}
	
	public void setup(String namespaceURI, String localName, String qName,
			Attributes attributes, JsfConfig jsfConfig) {

		super.setup(namespaceURI, localName, qName, attributes, jsfConfig);
		ViewProcessor viewProcessor = (ViewProcessor) findAncestor(ViewProcessor.class);
		if (viewProcessor == null) {
			throw new TagProcessorNotFoundRuntimeException(ViewProcessor.class);
		}
		viewProcessor.addInsertProcessor(this);
	}

	public void process(JsfContext jsfContext, Tag parentTag)
			throws JspException {

		Map insertProcessorMap = getInsertProcessorMap(jsfContext.getPageContext());
		String name = getName();
		if (name != null && insertProcessorMap.containsKey(name)) {
			InsertProcessor ip = (InsertProcessor) insertProcessorMap.get(name);
			if (ip != this) {
				ip.process(jsfContext, parentTag);
				return;
			}
		}
		String src = getSrc();
		if (src != null) {
			processInclude(jsfContext, parentTag, src);
		} else {
			processChildren(jsfContext, parentTag);
		}
	}
	
	public String getName() {
		return getProperty(JsfConstants.NAME_ATTR);
	}
	
	public String getSrc() {
		return getProperty(JsfConstants.SRC_ATTR);
	}

	protected void processInclude(JsfContext jsfContext, Tag parentTag, String src)
			throws JspException {

		S2Container container = SingletonS2ContainerFactory.getContainer();
		ViewTemplateFactory factory = (ViewTemplateFactory) container.getComponent(ViewTemplateFactory.class);
		ViewTemplate template = factory.getViewTemplate(src);
		ViewProcessor viewProcessor = (ViewProcessor) template.getRootTagProcessor();
		InsertProcessor insertProcessor = viewProcessor.getInsertProcessor(null);
		insertProcessor.process(jsfContext, parentTag);
	}
}