/*
  This file is part of the BJP package.

  BJP package is free software: you can redistribute it and/or modify it
  under the terms of the GNU Lesser General Public License as published by the
  Free Software Foundation, either version 3 of the License, or (at your
  option) any later version.

  BJP package 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 BJP package.  If not, see <http://www.gnu.org/licenses/>.
 */
package dataset.feature;

import java.util.BitSet;
import java.util.List;

/**
 * This abstract class represents a feature, which is a conjunction of variable
 * assignments.
 */
public abstract class Feature {
	private final BitSet var;
	protected final int numberOfDomainVariables;

	/**
	 * Class constructor
	 * @param n The number of variables in the feature
	 */
	public Feature(int n) {
		this.numberOfDomainVariables = n;
		this.var = new BitSet(n);
	}

	/**
	 * Class constructor
	 * @param n The number of variables in the feature
	 * @param var The variables which appear in the feature
	 */
	protected Feature(int n, BitSet var) {
		this.numberOfDomainVariables = n;
		this.var = (BitSet) var.clone();
	}

	public BitSet getVar() {
		return this.var;
	}

	public void addVar(int var) {
		this.var.set(var);
	}

	public void rmVar(int var) {
		this.var.clear(var);
	}

	protected int getNumberOfDomainVariables() {
		return this.numberOfDomainVariables;
	}

	public abstract boolean isSatisfied(Feature otherFeature);

	public abstract void addVal(int var, Integer val);

	public abstract Integer getVal(int var);

	public abstract int getLength();

	@Override
	public abstract Feature clone();

	@Override
	public abstract boolean equals(Object object);

	@Override
	public int hashCode() {
		int hash = 7;
		hash = 47 * hash + (this.var == null ? 0 : this.var.hashCode());

		return hash;
	}

	public abstract BitSet getValues();

	public abstract void setValues(BitSet values);

	public abstract Feature getSubset(BitSet variables);

	public abstract Feature getSubset(List<Integer> blanketOfX);
	
}