/**
 * 
 */
package org.compiere.vos;

import java.io.Serializable;
import java.util.ArrayList;


import org.compiere.common.constants.Build;
import org.compiere.util.CLoggerSimple;
import org.compiere.util.CompiereLogger;
import org.compiere.util.NamePair;
/**
 * @author gwu
 *
 */
public class ListBoxVO implements Serializable 
{
	public static CompiereLogger	log = new CLoggerSimple(ListBoxVO.class);
	/** SQL Query       */
	public String       Query = null;
	/** Table Name      */
	public String       TableName = "";
	/** Key Column      */
	public String       KeyColumn = "";
	/** Zoom Window     */
	public int          zoomWindow;
	/** Zoom Window     */
	public int          ZoomWindowPO;
	/** Zoom Query      */
	//public QueryVO		ZoomQuery = null;

	/** Direct Access Query 	*/
	public String       QueryDirect = "";
	/** Parent Flag     */
	public boolean      IsParent = false;
	/** Key Flag     	*/
	public boolean      IsKey = false;
	/** Validation code */
	public String       ValidationCode = "";
	/** Validation flag */
	public boolean      IsValidated = false;

	/**	AD_Column_Info or AD_Process_Para	*/
	public int          Column_ID;
	/** Real AD_Reference_ID				*/
	public int 			AD_Reference_Value_ID;
	/** CreadedBy?updatedBy					*/
	public boolean		IsCreadedUpdatedBy = false;





	private static final long serialVersionUID = 1L;

	private String m_defaultKey = null;

	// do not change to HashMap; using an array to maintain sorted order
	/**
	 * @gwt.typeArgs <org.compiere.util.NamePair>
	 */
	private ArrayList m_options = null;
	/**
	 * @gwt.typeArgs <org.compiere.util.NamePair>
	 */
	private ArrayList m_exception_options = null;

	public void setExceptionOptions(ArrayList exceptionOptions) {
		if(m_exception_options == null)
			m_exception_options = new ArrayList();
		concatNamePairArray(m_exception_options, exceptionOptions);
		//concatNamePairArray(m_options, exceptionOptions);
	}

	public void setOptions(ArrayList validOptions) {
		if(Build.isDebug())
			log.finest("setOptions(before):"+this);
		m_options = validOptions;
		if(Build.isDebug())
			log.finest("setOptions(after):"+this);

		//log.finest("setOptions: Now the exception options are:"+(m_exception_options));
		//log.finest("setOptions: Now the m_options are:"+(m_options));
	}

	public void addOption(NamePair option) {
		if(option != null) {
			if(NamePair.indexOfKey(m_options, option.getID()) == -1)
				m_options.add(option);
		}
		else
			throw new IllegalArgumentException("option should not be null");
	}
	
	public void pushExceptionOption(NamePair option) {

		if(m_exception_options == null)
			m_exception_options = new ArrayList(10);
		if(option != null) {
			if(NamePair.indexOfKey(m_exception_options, option.getID()) == -1)
				m_exception_options.add(option);
		}
		else
			throw new IllegalArgumentException("option should not be null");
	}

	public void pushExceptionOptions(ArrayList options) {
		if(Build.isDebug())
			log.finest("pushExceptionOptions(before):"+this);

		for(int i=0; i<options.size(); i++) {
			pushExceptionOption((NamePair)options.get(i));
		}
		if(Build.isDebug())
			log.finest("pushExceptionOptions(before):"+this);

	}

	
	public static void concatNamePairArray(ArrayList options, ArrayList c) {
		if(c == null) 
			return;
		if(options == null)
			throw new IllegalArgumentException("options cannot be null");
		if(options != null)
			for(int i=0; i<c.size(); i++)
				if(NamePair.indexOfKey(options, ((NamePair)c.get(i)).getID()) == -1)
					options.add(c.get(i));
	}



	public ListBoxVO()
	{		//m_options = new ArrayList(4);
	//this.m_defaultKey = "";
		this(true);
	}

	public ListBoxVO(boolean init) {
		if(init) {
			m_options = new ArrayList(4);
		this.m_defaultKey = "";
		}
	}
	public ListBoxVO(NamePair[] p_options, String p_defaultKey )
	{
		ArrayList options = new ArrayList(p_options.length);
		for(int i=0; i<p_options.length; i++)
			options.add(p_options[i]);
		create(options, p_defaultKey);
	}

	public ListBoxVO(ArrayList p_options, String p_defaultKey ) {
		create(p_options, p_defaultKey);
	}

	private void create(ArrayList p_options, String p_defaultKey )
	{
		//for(int i=0; i<m_options.size(); i++) 
		m_options = p_options;
		//ZD, toArray doesn't work in GWT     m_options = (NamePair[])p_options.toArray();

		if( null == m_options ) {
			m_options = new ArrayList(); 
		}
		m_defaultKey = p_defaultKey;
	}

	public String getDefaultKey()
	{
		return m_defaultKey;
	}

	public void setDefaultKey( String defaultKey )
	{
		m_defaultKey = defaultKey;
	}

	public ArrayList getOptions()
	{
		return m_options;
	}

	/**
	 * Returns the index of the first option found for the key, or -1 if not found.
	 * @param key
	 * @return
	 */
	public int indexOfKey( String key )
	{
		return NamePair.indexOfKey(m_options, key);
	}

	/**
	 * Returns the index of the first option found for the key, or -1 if not found.
	 * @param value
	 * @return
	 */
	public int indexOfValue( String value )
	{
		return NamePair.indexOfValue(m_options, value);
	}


	public String getValue( String key )
	{
		NamePair option = getOption(key);
		if(option == null)
			return null;
		return option.getName();
	}

	public NamePair getValidOption( String key ) {
		int index = NamePair.indexOfKey(m_options, key );
		if( index >= 0 )
			return ((NamePair)m_options.get(index));
		return null;
	}
	
	public NamePair getOption( String key )
	{


		int index = NamePair.indexOfKey(m_options, key );
		if( index >= 0 )
			return ((NamePair)m_options.get(index));
		else {
			if(m_exception_options == null)
				return null;
			index = NamePair.indexOfKey(m_exception_options, key);
			if(index >= 0)
				return ((NamePair)m_exception_options.get(index));
		}
		return null;
	}

	public ArrayList getExceptionOptions() {
		return this.m_exception_options;
	}
	public String toString() {
		return "m_options:"+m_options+"m_exception_options:"+m_exception_options;
	}

	public boolean isOptionsSet() {
		return m_options != null;
	}
}

