package org.seasar.jsf.template.impl;

import java.util.Stack;

import org.seasar.jsf.template.ComponentTreeBuilder;
import org.seasar.jsf.template.TagSelector;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

public final class ViewTemplateHandler extends DefaultHandler {

	private TagSelectors tagSelectors_;
	private Stack builderStack_ = new Stack();
	private ComponentTreeBuilder root_;

	public ViewTemplateHandler(TagSelectors tagSelectors) {
		tagSelectors_ = tagSelectors;
	}
	
	public ComponentTreeBuilder getRoot() {
		return root_;
	}

	public void startElement(String namespaceURI, String localName,
			String qName, Attributes attributes) {

		ComponentTreeBuilder builder = createBuilder(namespaceURI, localName, qName, attributes);
		if (builder != null) {
			if (!builderStack_.isEmpty()) {
				ComponentTreeBuilder parent = (ComponentTreeBuilder) builderStack_.peek();
				parent.addChild(builder);
			} else {
				root_ = builder;
			}
			builderStack_.push(builder);
		}
	}

	protected ComponentTreeBuilder createBuilder(String namespaceURI, String localName,
			String qName, Attributes attributes) {

		TagSelector selector = tagSelectors_.getTagSelector(namespaceURI, localName, qName, attributes);
		if (selector != null) {
			return selector.createBuilder(namespaceURI, localName, qName, attributes);
		}
		return null;
	}

	public void characters(char[] buffer, int start, int length) {
		if (!builderStack_.isEmpty()) {
			ComponentTreeBuilder parent = (ComponentTreeBuilder) builderStack_.peek();
			parent.addChild(new UITextBuilder(new String(buffer, start, length)));
		}
	}

	public void endElement(String namespaceURI, String localName, String qName) {
		builderStack_.pop();
	}

	public void error(SAXParseException e) throws SAXException {
		throw e;
	}

	public void warning(SAXParseException e) throws SAXException {
		System.err.println(e);
	}
}