/*
 * Copyright 2006 Takahiro Nakamura.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package woolpack.visitor;

import org.w3c.dom.Element;
import org.w3c.dom.Node;

import woolpack.dom.DomConstants;

/**
 * 定数と静的メソッドの集まり。
 * @author nakamura
 *
 */
public class DomVisitorConstants {
	
	/**
	 * {@link Visitor#getContext()}を{@link Node}にキャストして、
	 * v をテキストノードに変換して追加する{@link Acceptable}。
	 */
	public static final Acceptable<Object> OBJECT = new Acceptable<Object>(){
		public void accept(final Visitor visitor, final Object v) {
			final Node node = (Node)visitor.getContext();
			node.appendChild(DomConstants.getDocumentNode(node).createTextNode(v.toString()));
		}
	};
	
	/**
	 * {@link Visitor#getContext()}を{@link Node}にキャストして、
	 * 一覧をカンマ区切りで追加する{@link Acceptable}。
	 */
	public static final Acceptable<Iterable> ITERABLE_COMMA = new Acceptable<Iterable>(){
		public void accept(final Visitor visitor, final Iterable v) {
			boolean flag = true;
			for(final Object e:v){
				if(flag){
					flag = false;
				}else{
					visitor.visit(", ");
				}
				visitor.visit(e);
			}
		}
	};

	private DomVisitorConstants(){}// カバレージがここを通過してはいけない

	/**
	 * {@link Visitor#getContext()}を{@link Element}にキャストして、
	 * エレメントを追加して委譲する{@link Acceptable}を返す。
	 * @param <V> 汎用型。
	 * @param elementName エレメント名。
	 * @param child 委譲先。
	 * @return エレメントを追加して委譲する{@link Acceptable}。
	 */
	public static final <V> Acceptable<V> addElementAcceptable(final String elementName, final Acceptable<V> child){
		return new Acceptable<V>(){
			public void accept(final Visitor visitor, final V v) {
				final Element node = (Element)visitor.getContext();
				final Element element = DomConstants.getDocumentNode(node).createElement(elementName);
				node.appendChild(element);
				final Visitor newVisitor = visitor.copy();
				newVisitor.setContext(element);
				child.accept(newVisitor, v);
			}
		};
	}
}
