/*
 * Created on Jul 5, 2006
 * 
 * (C) Copyright TANDBERG Television Ltd.
 */
package com.tandbergtv.workflow.util;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import com.tandbergtv.workflow.driver.search.SearchParameterBase;


/**
 * This class holds the information about the search criteria fields like sorting column name,
 * sorting order, starting record number, and number of records for a page.
 * 
 * @author rao
 */
public class SearchCriteria implements Serializable
{
	private static final long serialVersionUID = 1L;

	// A 0-based number indicating the record to begin fetching from
	private int startingRecordNumber;

	// The number of records to read
	private int recordsCount;

	private List<SearchParameterBase> searchList;

	/**
	 * Default Class Constructor
	 */
	public SearchCriteria()
	{
		this.startingRecordNumber = 0;
		this.recordsCount = 0;
		this.searchList = new ArrayList<SearchParameterBase>();
	}

	/**
	 * Creates a SearchCriteria
	 * @param searchMap
	 */
	@SuppressWarnings("unchecked")
	public SearchCriteria(SearchCriteria criteria)
	{
		this();
		
		if (criteria == null)
			throw new IllegalArgumentException("Search criteria cannot be null");
		
		this.searchList = (List<SearchParameterBase>)((ArrayList<SearchParameterBase>)criteria.getSearchList()).clone();
	}

	/**
	 * @return The number of records to fetch
	 */
	public int getRecordsCount()
	{
		return recordsCount;
	}

	/**
	 * @param recordsCount
	 *            The number of records to fetch
	 */
	public void setRecordsCount(int recordsCount)
	{
		this.recordsCount = recordsCount;
	}

	/**
	 * @return Returns the searchList.
	 */
	public List<SearchParameterBase> getSearchList()
	{
		return searchList;
	}

	/**
	 * Returns the 0-based Record number from which to begin fetching Records.
	 * 
	 * @return The number of the Record from which to start fetching data.
	 */
	public int getStartingRecordNumber()
	{
		return startingRecordNumber;
	}

	/**
	 * Sets the 0-based Record number from which to begin fetching Records.
	 * 
	 * @param startingRecordNumber
	 *            The number of the Record from which to start fetching data.
	 */
	public void setStartingRecordNumber(int startingRecordNumber)
	{
		this.startingRecordNumber = startingRecordNumber;
	}
	
	/**
	 * Adds a search parameter using the specified key
	 * 
	 * @param parameter
	 */
	public void addParameter(SearchParameterBase parameter)
	{
		this.searchList.add(parameter);
	}
	
	/**
	 * @param parameters
	 * 
	 * Adds the given list of parameters
	 */
	public void addParameters(List<SearchParameterBase> parameters)
	{
		this.searchList.addAll(parameters);
	}

	/**
	 * Removes the search parameter with the specified key
	 * 
	 * @param fieldName
	 * @return The removed parameter
	 */
	public SearchParameterBase removeParameter(String fieldName)
	{
		SearchParameterBase param = getParameter(fieldName);
		if (param == null)
			return null;
		this.searchList.remove(param);
		return param;
	}
	
	/**
	 * Gets the search parameter using the specified key
	 * 
	 * @param fieldName
	 * @return The matching Parameter
	 */
	public SearchParameterBase getParameter(String fieldName)
	{
		for(SearchParameterBase param : this.searchList)
			if (param.getFieldName().equals(fieldName))
				return param;
		return null;
	}
	
	/**
	 * Returns a parameter of the specified type that has the specified name
	 * 
	 * @param fieldName the name of the parameter
	 * @param T the type of the parameter
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public <T> T getParameter(String fieldName, Class T)
	{
		for (SearchParameterBase param : this.searchList)
		{
			if (param.getFieldName().equals(fieldName) && param.getClass().isAssignableFrom(T))
				return (T)param;
		}
		
		return (T)null;
	}
	
	/**
	 * Returns the number of parameters in the search criteria
	 * 
	 * @return The number of parameters
	 */
	public int count()
	{
		return this.searchList.size();
	}
	
	/**
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString()
	{
		StringBuilder sbSearchCriteria = new StringBuilder();
		for (SearchParameterBase param : this.searchList)
		{
			if (param.getSortingOrder() == null)
				continue;
			sbSearchCriteria.append("Sorting Column Name-->" + param.getFieldName());
			sbSearchCriteria.append(" ::Sorting Order-->" + param.getSortingOrder());
		}
		sbSearchCriteria.append(" ::Starting Record Number-->" + getStartingRecordNumber());
		sbSearchCriteria.append(" ::Records Count-->" + getRecordsCount());
		return sbSearchCriteria.toString();
	}
}
