package daruma.wfs.filter;

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

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

import daruma.xml.DeclaredName ;
import daruma.xml.util.XMLParseErrorException;

import daruma.geometry.TransformationContext;

import daruma.storage_manager.StorageManager;
import daruma.storage_manager.type_definition.TypeName;
import daruma.storage_manager.type_definition.TypeDefinition;

//======================================================================
/**
 * Filter ノードの述語情報を格納するためのの抽象クラス
 */
public abstract class PredicateDescription
{
    private StorageManager storage; 
    private TypeName typeName;
    private TypeDefinition type;
    private TransformationContext trans;

    protected DeclaredName tagName ;	/* match した Element の tagname 
					 * を記録。効率よく等価性を
					 * チェックするため
					 * Lexicon に登録されている
					 * 実体を利用する。
					 */

    protected List<PredicateDescription> children ; /// 子供ノード

    //--------------------------------------------------
    /**
     * コンストラクタ
     */
    public PredicateDescription(StorageManager  storage ,
				TypeName  typeName ,
				TypeDefinition  type ,
				TransformationContext trans )
    {
	this.storage = storage;
	this.typeName = typeName;
	this.type = type;
	this.trans = trans;
	this.children = new ArrayList<PredicateDescription>() ;
    }

    //--------------------------------------------------
    /**
     * SQL への変換インターフェース
     */
    public abstract String getSQLExpression();

    //--------------------------------------------------
    /**
     * storage へのアクセス
     */
    protected StorageManager getStorage()
    {
	return( this.storage );
    }

    //--------------------------------------------------
    /**
     * typeName へのアクセス
     */
    protected TypeName getTypeName()
    {
	return( this.typeName );
    }

    //--------------------------------------------------
    /**
     * typeDefinition へのアクセス
     */
    protected TypeDefinition getTypeDefinition()
    {
	return( this.type );
    }

    //--------------------------------------------------
    /**
     * CoordinateSystem へのアクセス
     */
    protected TransformationContext getTransformationContext()
    {
	return( this.trans );
    }

    //--------------------------------------------------
    /**
     * 子ノードへを追加
     */
    public void addChild(PredicateDescription child) 
    {
	this.children.add(child) ;
    }

    //--------------------------------------------------
    /**
     * 子ノードを取得
     */
    public PredicateDescription getChild(int index)
    {
	return this.children.get(index) ;
    }

    //--------------------------------------------------
    /**
     * 子ノードリストを取得
     */
    public List<PredicateDescription> getChildren()
    {
	return this.children ;
    }

    //--------------------------------------------------
    /**
     * 子ノードの数を取得
     */
    public int numberOfChildren()
    {
	return this.children.size() ;
    }

    //--------------------------------------------------
    /**
     * 詳細チェック
     * 地理検索などのチェックを精密に行う、2nd pass の処理
     */
    abstract public boolean detailedCheck(Node feature) 
	throws XMLParseErrorException ;
}
