package com.tandbergtv.workflow.driver.search;
/**
 * Holds information for a search predicate involving a single value. 
 * 
 * @author Imran Naqvi
 */
public class ValueParameter extends SearchParameterBase {

	private Object value = null;

	private SearchOperator operator = null;
	
	/**
	 * Creates a ValueParameter
	 */
	public ValueParameter(String name) {
		this(name, SearchType.STRING, SearchOperator.EQUAL);
	}

	/**
	 * Creates a ValueParameter
	 * @param type
	 */
	public ValueParameter(String name, SearchType type) {
		super(name, type);
		setOperator(SearchOperator.EQUAL);		
	}
	
	/**
	 * Creates a ValueParameter
	 * @param type
	 * @param isVariable
	 */
	public ValueParameter(String name, SearchType type, boolean isVariable) {
		super(name, type, isVariable);
		setOperator(SearchOperator.EQUAL);
	}

	/**
	 * Creates a ValueParameter
	 * @param type
	 * @param isVariable
	 */
	public ValueParameter(String name, SearchType type, boolean isVariable, Object value) {
		super(name, type, isVariable);
		setOperator(SearchOperator.EQUAL);
		this.setValue(value);
	}
	
	/**
	 * Creates a ValueParameter
	 * @param type
	 * @param operator
	 */
	public ValueParameter(String name, SearchType type, SearchOperator operator) {
		this(name, type, null, operator);
	}
	
	/**
	 * Creates a ValueParameter
	 * @param type
	 * @param value
	 */
	public ValueParameter(String name, SearchType type, Object value) {
		super(name, type);
		this.setValue(value);
		setOperator(SearchOperator.EQUAL);
	}
	

	/**
	 * Creates a ValueParameter
	 * @param value
	 * @param operator
	 */
	public ValueParameter(String name, SearchType type, boolean isVariable, SearchOperator operator) {
		super(name, type, isVariable);
		setOperator(operator);
	}
	
	/**
	 * Creates a ValueParameter
	 * @param value
	 * @param operator
	 */
	public ValueParameter(String name, SearchType type, Object value, SearchOperator operator) {
		this(name, type, false, value, operator);
	}
	
	/**
	 * Creates a ValueParameter
	 * @param value
	 * @param operator
	 */
	public ValueParameter(String name, SearchType type, Object value, SearchOperator operator, boolean ignoreCase) {
		this(name, type, false, value, operator);
		setIgnoreCase(ignoreCase);
	}

	/**
	 * Creates a ValueParameter
	 * @param type
	 * @param isVariable
	 * @param value
	 * @param operator
	 */
	public ValueParameter(String name, SearchType type, boolean isVariable, Object value, SearchOperator operator) {
		super(name, type, isVariable);
		this.value = value;
		setOperator(operator);
	}
	
	public Object getValue() {
		return value;
	}

	public void setValue(Object value) {
		this.value = value;
	}

	public SearchOperator getOperator() {
		return operator;
	}

	public void setOperator(SearchOperator operator) {
		if (operator == SearchOperator.IN || operator == SearchOperator.NOTIN || 
				(operator == SearchOperator.LIKE && this.getFieldType() != SearchType.STRING))
			throw new RuntimeException("Search operator is invalid: " + operator);
		
		this.operator = operator;
	}

	@Override
	public String getPredicate() {
		/* Get some special cases out of the way */
		if (value == null && getOperator() == SearchOperator.EQUAL)
			return " is null";
		if (value == null && getOperator() == SearchOperator.NOTEQUAL)
			return " is not null";

		String operator = getOperatorString();

		String stringValue = value.toString();
		if(getIgnoreCase()) {
			stringValue = stringValue.toLowerCase();
		}
		if (SearchOperator.EQUAL == getOperator()
				&& getFieldType() == SearchType.STRING)
			return operator + "'" + stringValue + "'";
		else if (SearchOperator.NOTEQUAL == getOperator()
				&& this.getFieldType() == SearchType.STRING)
			return operator + "'" + stringValue + "'";
		else if (SearchOperator.LIKE == getOperator()
				&& this.getFieldType() == SearchType.STRING)
			return operator + "'%" + stringValue + "%'";
		else if (this.getFieldType() == SearchType.DATE)
			return operator + "to_date('" + value + "','" + DATE_FORMAT + "' )";
		else if (SearchOperator.STARTSWITH == getOperator()
				&& this.getFieldType() == SearchType.STRING) {
			return operator + "'" + stringValue + "%'";
		} else if (SearchOperator.ENDSWITH == getOperator()
				&& this.getFieldType() == SearchType.STRING) {
			return operator + "'%" + stringValue + "'";
		} else if (SearchOperator.CONTAINS == getOperator()
				&& this.getFieldType() == SearchType.STRING) {
			return operator + "'%" + stringValue + "%'";
		} else if (SearchOperator.DOESNOTCONTAIN == getOperator()
				&& this.getFieldType() == SearchType.STRING) {
			return "not" + operator + "'%" + stringValue + "%'";
		} else if (SearchOperator.ISEMPTY == getOperator()
				&& this.getFieldType() == SearchType.STRING) {
			return "not" + operator + "'" + stringValue + "%'";
		} else if (SearchOperator.ISNOTEMPTY == getOperator()
				&& this.getFieldType() == SearchType.STRING) {
			return operator + "'" + stringValue + "%'";
		} else if (this.getFieldType() == SearchType.STRING) {
			return operator + "'" + stringValue + "'";
		} else
			return operator + stringValue;
	}

	private String getOperatorString() {
		switch (this.operator) {
			case EQUAL:
				return " = ";
			case GREATERTHAN:
			case GREATERTHANTODAY:
				return " > ";
			case LESSTHAN:
			case LESSTHANTODAY:
				return " < ";
			case NOTEQUAL:
				return " != ";
			case LIKE:
				return " LIKE ";
			case GREATERTHANEQUAL:
				return " >= ";
			case LESSTHANEQUAL:
				return " <= ";
			case STARTSWITH:
			case ENDSWITH:
			case CONTAINS:
			case DOESNOTCONTAIN:
			case ISEMPTY:
			case ISNOTEMPTY:
				return " LIKE ";				
		}
		return null;
	}

}
