/**
 *
 */

package org.richfaces.component;

import java.util.Iterator;

import org.apache.commons.collections.iterators.IteratorChain;
import org.richfaces.model.StackingTreeModel;
import org.richfaces.model.StackingTreeModelDataProvider;
import org.richfaces.model.VisualStackingTreeModel;


/**
 * JSF component class
 * 
 */
public abstract class UIRecursiveTreeNodesAdaptor extends UITreeNodesAdaptor {

	public static final String COMPONENT_TYPE = "org.richfaces.RecursiveTreeNodesAdaptor";

	public static final String COMPONENT_FAMILY = "org.richfaces.RecursiveTreeNodesAdaptor";

	public abstract Object getRoots();
	public abstract void setRoots(Object roots);

	public abstract boolean isIncluded();
	public abstract void setIncluded(boolean active);

	public abstract boolean isIncludedRoot();
	public abstract void setIncludedRoot(boolean active);
	
	protected boolean includeNode() {
		return isIncluded() && isIncludedRoot();
	}
	
	public Object getData() {
		return getRoots();
 	}
	
	public abstract String getVar();
	public abstract void setVar(String var);
	
	public StackingTreeModel getStackingModel() {
		StackingTreeModel stackingModel = super.getStackingModel();
		
		StackingTreeModel recursiveModel = new VisualStackingTreeModel(getId(), getVar(), new StackingTreeModelDataProvider() {

			public Object getData() {
				return UIRecursiveTreeNodesAdaptor.this.getNodes();
			}
			
		}, UIRecursiveTreeNodesAdaptor.this) {

			public StackingTreeModel getModelById(String id) {
				StackingTreeModel model = super.getModelById(id);
				if (model == null) {
					model = this.getParent().getModelById(id);
				}
				
				return model;
			}

			public Iterator getModelsIterator() {
				IteratorChain chain = new IteratorChain();
				chain.addIterator(super.getModelsIterator());
				chain.addIterator(this.getParent().getModelsIterator());

				return chain;
			}

			protected boolean isActive() {
				return UIRecursiveTreeNodesAdaptor.this.isRendered();
			}
			
			protected boolean isActiveData() {
				return UIRecursiveTreeNodesAdaptor.this.isIncluded() && UIRecursiveTreeNodesAdaptor.this.isIncludedNode();
			}
		};
		stackingModel.addStackingModel(recursiveModel);
		
		return stackingModel;
	}
	
}
