package industries.doublehelix.conditionalfilter.filtertypes.container;

import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * The master filter as a logical one containing all other filters and having additional settings like
 * active or not 
 * @author klaue
 *
 */
public class MasterFilter extends ContainerFilter { 
	private static final long serialVersionUID = 1L;
	private boolean isActive = true;
	
	/**
	 * Make a new master filter of the given filter type. Defaults to active.
	 * @param type
	 */
	public MasterFilter(ContainerType type) {
		super(type);
	}
	
	/**
	 * Make a new master filter of the given filter type.
	 * @param type
	 * @param isActive true to set this filter as active. Only top-level container filter should be set to inactive
	 */
	public MasterFilter(ContainerType type, boolean isActive) {
		this(type);
		this.isActive = isActive;
	}
	
	/**
	 * True if this filter is deemed active
	 * @return true if active
	 */
	public boolean isActive() {
		return this.isActive;
	}
	
	/**
	 * Set this filter's active state. An inactive master filter should not be used to filter anything and its sql methods
	 * will reflect that ("where 1=1" instead of "where [...]"
	 * @param active
	 */
	public void setActive(boolean active) {
		this.isActive = active;
	}
	
	@Override
	public String toString() {
		StringBuffer buf = new StringBuffer();
		if (!this.isActive) {
			buf.append("Inactive master filter: ");
		}
		buf.append(super.toString());
		return buf.toString();
	}
	
	@Override
	public String getSqlWhere() {
		if (!this.isActive) {
			//System.out.println("Warning, getSqlWhere() of inactive master filter called");
			return "1 = 1";
		}
		
		return super.getSqlWhere();
	}

	@Override
	public String getPreparedStatementWhereString() {
		if (!this.isActive) {
			//System.out.println("Warning, getPreparedStatementWhereString() of inactive master filter called");
			return "1 = 1";
		}
		
		return super.getPreparedStatementWhereString();
	}

	@Override
	public int addPreparedStatementValues(PreparedStatement ps, int currentIndex) throws SQLException {
		if (!this.isActive) {
			//System.out.println("Warning, addPreparedStatementValues() of inactive filter called");
			return currentIndex;
		}
		return super.addPreparedStatementValues(ps, currentIndex);
	}
	
	/**
	 * This will merge all master filters. 
	 * If all filters are inactive, the new master filter will be inactive and the rest of the process would be like below.
	 * If all are active, the result is a new master filter that contains a new ContainerFilter for each master filter
	 * which in turn contains all of the former master filters subfilters. Those subfilters are not copies, if you require
	 * a copy, call this method with merge(ContainerType.ALL, (MasterFilter)yourfilter1.clone(), (MasterFilter)yourfilter2.clone())
	 * If just some are inactive, the result is the same as if all were active with just those that are inactive not merged in
	 * @param filters
	 * @param mergeType how the master filters should be merged
	 * @return a new master filter
	 */
	public static MasterFilter merge(ContainerType mergeType, MasterFilter... filters) {
		int activeCount = 0;
		for (MasterFilter filter : filters) {
			if (filter.isActive()) ++activeCount;
		}
		
		boolean skipInactive = activeCount != 0;
		
		MasterFilter newMaster = new MasterFilter(mergeType, activeCount > 0);
		
		for (MasterFilter filter : filters) {
			if (!filter.isActive() && skipInactive) continue;
			ContainerFilter containerFilter = new ContainerFilter(filter.getType());
			containerFilter.setSubFilters(filter.getSubFilters());
			newMaster.addFilter(containerFilter);
		}
		return newMaster;
	}
}
