package dk.itu.mario.level.grammar;

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

public class OrClause implements Clause {
	private double[] chances;
	private List<Clause> subClauses = new ArrayList<Clause>();

	public OrClause(double[] chances, List<Clause> subClauses) {
		if (chances.length != subClauses.size()) {
			throw new IllegalArgumentException("List of probabilities does not match size of subclause list in OrClause constructor.");
		}
		this.chances = chances;
		this.subClauses.addAll(subClauses);
	}
	
	public OrClause(double[] chances, Clause... subClauses) {
		this.chances = chances;
		double chanceTotal = 0.0;
		for (double chance : chances) {
			chanceTotal += chance;
		}
		if (Math.abs(chanceTotal - 1.0) > 0.01) {
			throw new IllegalArgumentException(
					"Total or-clause chances must sum to 1.0.");
		}
		for (Clause clause : subClauses) {
			this.subClauses.add(clause);
		}
	}
	
	@Override
	public boolean isChoice() {
		return true;
	}

	@Override
	public boolean isTerminal() {
		return false;
	}
	@Override
	public Clause makeRandomChoice() {
		double rand = Math.random();
		for (int i = 0; i < chances.length; i++) {
			if (rand < chances[i]) {
				return subClauses.get(i);
			}
			rand -= chances[i];
		}
		return subClauses.get(chances.length - 1);
	}

	@Override
	public int getNumSubClauses() {
		return subClauses.size();
	}
	
	public Clause getSubClause(int index) {
		throw new UnsupportedOperationException();
	}
	
	@Override
	public boolean isVariable() {
		return false;
	}
	
	@Override
	public String toString() {
		if (subClauses.size() == 0) {
			return "(Empty OR clause)";
		}
		StringBuilder sb = new StringBuilder();
		sb.append("(");
		for (int i = 0; i < subClauses.size() - 1; i ++) {
			sb.append(subClauses.get(i).toString());
			sb.append(" | ");
		}
		sb.append(subClauses.get(subClauses.size()-1).toString());
		sb.append(")");
		
		return sb.toString();
	}
}