/**
 * License Agreement.
 *
 *  JBoss RichFaces - Ajax4jsf Component Library
 *
 * Copyright (C) 2007  Exadel, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2.1 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 */

package org.richfaces.component;

import java.util.Iterator;

import javax.faces.component.UIColumn;
import javax.faces.component.UIComponent;

import org.ajax4jsf.component.AjaxSupport;
import org.ajax4jsf.component.SequenceDataAdaptor;
import org.apache.commons.collections.Predicate;
import org.apache.commons.collections.iterators.FilterIterator;
import org.apache.commons.collections.iterators.IteratorChain;


/**
 * JSF component class
 * 
 */
public abstract class UIDataTable extends SequenceDataAdaptor {

	/**
	 * @author shura
	 * 
	 */
	private static final class NotColumnPredicate implements Predicate {
		public boolean evaluate(Object input) {
			return !(input instanceof UIColumn || input instanceof Column);
		}
	}

	/**
	 * @author shura
	 * 
	 */
	private static final class ColumnPredicate implements Predicate {
		public boolean evaluate(Object input) {
//			if (input instanceof UIComponent) {
//				UIComponent component = (UIComponent) input;
//				
//				if (!component.isRendered()) {
//					return false;
//				}
//			}
//			
			return (input instanceof UIColumn || input instanceof Column);
		}
	}

	/**
	 * @author shura
	 * 
	 */
	private static final class AjaxSupportPredicate implements Predicate {
		public boolean evaluate(Object input) {
			return (input instanceof AjaxSupport || input instanceof Dropzone);
		}
	}

	public static final Predicate isColumn = new ColumnPredicate();

	public static final Predicate isNotColumn = new NotColumnPredicate();

	public static final Predicate isAjaxSupport = new AjaxSupportPredicate();

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.ajax4jsf.ajax.repeat.UIDataAdaptor#dataChildren()
	 */
	public Iterator dataChildren() {
		IteratorChain dataChildren = new IteratorChain();
		dataChildren.addIterator(new FilterIterator(getFacets().values()
				.iterator(), isAjaxSupport));

		
		
		// Append all columns children.
		dataChildren.addIterator(columns());
		
		
//		for (Iterator iter = columns(); iter.hasNext();) {
//			UIComponent column = (UIComponent) iter.next();
//			if (column.isRendered()) {
//				dataChildren.addIterator(column.getChildren()
//						.iterator());
//
//			}
//		}
		
		//commons-collections 2.x bug workaround
		dataChildren.hasNext();
		
		return dataChildren;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.ajax4jsf.ajax.repeat.UIDataAdaptor#fixedChildren()
	 */
	public Iterator fixedChildren() {
		// Iterate over facets, non-column childrens and column's facets.
		IteratorChain fixedChildren = new IteratorChain(getFacets().values().iterator());
		fixedChildren.addIterator(new FilterIterator(getChildren().iterator(),
				isNotColumn));
		// Append all columns facets.
		for (Iterator iter = columns(); iter.hasNext();) {
			UIComponent column = (UIComponent) iter.next();
			if (column.isRendered()) {
				fixedChildren.addIterator(column.getFacets().values()
						.iterator());

			}
		}
		
		//commons-collections 2.x bug workaround
		fixedChildren.hasNext();
		
		return fixedChildren;
	}

	public Iterator columns() {
		return new FilterIterator(getChildren().iterator(), isColumn);
	}

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

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

}