/* ConfirmationCallback.java -- callback for confirmations.
   Copyright (C) 2003, Free Software Foundation, Inc.

This file is part of GNU Classpath.

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

GNU Classpath 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
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.security.auth.callback;

import java.io.Serializable;

/**
 * Underlying security services instantiate and pass a
 * <code>ConfirmationCallback</code> to the <code>handle()</code> method of a
 * {@link CallbackHandler} to ask for YES/NO, OK/CANCEL, YES/NO/CANCEL or other
 * similar confirmations.
 *
 * @see CallbackHandler
 */
public class ConfirmationCallback implements Callback, Serializable
{

  // Constants and variables
  // -------------------------------------------------------------------------

  /**
   * <p>Unspecified option type.</p>
   *
   * <p>The <code>getOptionType</code> method returns this value if this
   * <code>ConfirmationCallback</code> was instantiated with <code>options</code>
   * instead of an <code>optionType</code>.</p>
   */
  public static final int UNSPECIFIED_OPTION = -1;

  /**
   * <p>YES/NO confirmation option.</p>
   *
   * <p>An underlying security service specifies this as the <code>optionType</code>
   * to a <code>ConfirmationCallback</code> constructor if it requires a
   * confirmation which can be answered with either <code>YES</code> or
   * <code>NO</code>.</p>
   */
  public static final int YES_NO_OPTION = 0;

  /**
   * <p>YES/NO/CANCEL confirmation confirmation option.</p>
   *
   * <p>An underlying security service specifies this as the <code>optionType</code>
   * to a <code>ConfirmationCallback</code> constructor if it requires a
   * confirmation which can be answered with either <code>YES</code>,
   * <code>NO</code> or <code>CANCEL</code>.
   */
  public static final int YES_NO_CANCEL_OPTION = 1;

  /**
   * <p>OK/CANCEL confirmation confirmation option.</p>
   *
   * <p>An underlying security service specifies this as the <code>optionType</code>
   * to a <code>ConfirmationCallback</code> constructor if it requires a
   * confirmation which can be answered with either <code>OK</code> or
   * <code>CANCEL</code>.</p>
   */
  public static final int OK_CANCEL_OPTION = 2;

  /**
   * <p>YES option.</p>
   *
   * <p>If an <code>optionType</code> was specified to this
   * <code>ConfirmationCallback</code>, this option may be specified as a
   * <code>defaultOption</code> or returned as the selected index.</p>
   */
  public static final int YES = 0;

  /**
   * <p>NO option.</p>
   *
   * <p>If an <code>optionType</code> was specified to this
   * <code>ConfirmationCallback</code>, this option may be specified as a
   * <code>defaultOption</code> or returned as the selected index.</p>
   */
  public static final int NO = 1;

  /**
   * <p>CANCEL option.</p>
   *
   * <p>If an <code>optionType</code> was specified to this
   * <code>ConfirmationCallback</code>, this option may be specified as a
   * <code>defaultOption</code> or returned as the selected index.</p>
   */
  public static final int CANCEL = 2;

  /**
   * <p>OK option.</p>
   *
   * <p>If an <code>optionType</code> was specified to this
   * <code>ConfirmationCallback</code>, this option may be specified as a
   * <code>defaultOption</code> or returned as the selected index.</p>
   */
  public static final int OK = 3;

  /** INFORMATION message type. */
  public static final int INFORMATION = 0;

  /** WARNING message type. */
  public static final int WARNING = 1;

  /** ERROR message type. */
  public static final int ERROR = 2;

  /**
   * @serial
   * @since 1.4
   */
  private String prompt;

  /**
   * @serial
   * @since 1.4
   */
  private int messageType;

  /**
   * @serial
   * @since 1.4
   */
  private int optionType;

  /**
   * @serial
   * @since 1.4
   */
  private int defaultOption;

  /**
   * @serial
   * @since 1.4
   */
  private String[] options = null;

  /**
   * @serial
   * @since 1.4
   */
  private int selection;

  // Constructor(s)
  // -------------------------------------------------------------------------

  /**
   * <p>Construct a <code>ConfirmationCallback</code> with a message type, an
   * option type and a default option.</p>
   *
   * <p>Underlying security services use this constructor if they require
   * either a YES/NO, YES/NO/CANCEL or OK/CANCEL confirmation.</p>
   *
   * @param messageType the message type (INFORMATION, WARNING or ERROR).
   * @param optionType the option type (YES_NO_OPTION, YES_NO_CANCEL_OPTION or
   * OK_CANCEL_OPTION).
   * @param defaultOption the default option from the provided optionType (YES,
   * NO, CANCEL or OK).
   * @throws IllegalArgumentException if <code>messageType</code> is not either
   * <code>INFORMATION</code>, <code>WARNING</code>, or <code>ERROR</code>, if
   * <code>optionType</code> is not either <code>YES_NO_OPTION</code>,
   * <code>YES_NO_CANCEL_OPTION</code>, or <code>OK_CANCEL_OPTION</code>, or if
   * <code>defaultOption</code> does not correspond to one of the options in
   * <code>optionType</code>.
   */
  public ConfirmationCallback(int messageType, int optionType, int defaultOption)
    throws IllegalArgumentException
  {
    super();

    setMessageType(messageType);
    setOptionType(optionType, defaultOption);
    this.defaultOption = defaultOption;
  }

  /**
   * <p>Construct a <code>ConfirmationCallback</code> with a message type, a
   * list of options and a default option.</p>
   *
   * <p>Underlying security services use this constructor if they require a
   * confirmation different from the available preset confirmations provided
   * (for example, CONTINUE/ABORT or STOP/GO). The confirmation options are
   * listed in the <code>options</code> array, and are displayed by the
   * {@link CallbackHandler} implementation in a manner consistent with the
   * way preset options are displayed.</p>
   *
   * @param messageType the message type (INFORMATION, WARNING or ERROR).
   * @param options the list of confirmation options.
   * @param defaultOption the default option, represented as an index into the
   * <code>options</code> array.
   * @throws IllegalArgumentException if <code>messageType</code> is not either
   * <code>INFORMATION</code>, <code>WARNING</code>, or <code>ERROR</code>, if
   * <code>options</code> is <code>null</code>, if <code>options</code> has a
   * length of <code>0</code>, if any element from <code>options</code> is
   * <code>null</code>, if any element from <code>options</code> has a length
   * of <code>0</code>, or if <code>defaultOption</code> does not lie within
   * the array boundaries of <code>options</code>.
   */
  public ConfirmationCallback(int messageType, String[] options, int defaultOption)
  {
    super();

    setMessageType(messageType);
    setOptions(options, defaultOption);
    this.defaultOption = defaultOption;
  }

  /**
   * <p>Construct a <code>ConfirmationCallback</code> with a prompt, message
   * type, an option type and a default option.</p>
   *
   * <p>Underlying security services use this constructor if they require
   * either a YES/NO, YES/NO/CANCEL or OK/CANCEL confirmation.</p>
   *
   * @param prompt the prompt used to describe the list of options.
   * @param messageType the message type (INFORMATION, WARNING or ERROR).
   * @param optionType the option type (YES_NO_OPTION, YES_NO_CANCEL_OPTION or
   * OK_CANCEL_OPTION).
   * @param defaultOption the default option from the provided optionType (YES,
   * NO, CANCEL or OK).
   * @throws IllegalArgumentException if <code>prompt</code> is <code>null</code>,
   * if <code>prompt</code> has a length of <code>0</code>, if
   * <code>messageType</code> is not either <code>INFORMATION</code>,
   * <code>WARNING</code>, or <code>ERROR</code>, if <code>optionType</code> is
   * not either <code>YES_NO_OPTION</code>, <code>YES_NO_CANCEL_OPTION</code>,
   * or <code>OK_CANCEL_OPTION</code>, or if <code>defaultOption</code> does
   * not correspond to one of the options in <code>optionType</code>.
   */
  public ConfirmationCallback(String prompt, int messageType, int optionType,
			      int defaultOption)
  {
    super();

    setPrompt(prompt);
    setMessageType(messageType);
    setOptionType(optionType, defaultOption);
    this.defaultOption = defaultOption;
  }

  /**
   * <p>Construct a <code>ConfirmationCallback</code> with a prompt, message
   * type, a list of options and a default option.</p>
   *
   * <p>Underlying security services use this constructor if they require a
   * confirmation different from the available preset confirmations provided
   * (for example, CONTINUE/ABORT or STOP/GO). The confirmation options are
   * listed in the <code>options</code> array, and are displayed by the
   * {@link CallbackHandler} implementation in a manner consistent with the
   * way preset options are displayed.</p>
   *
   * @param prompt the prompt used to describe the list of options.
   * @param messageType the message type (INFORMATION, WARNING or ERROR).
   * @param options the list of confirmation options.
   * @param defaultOption the default option, represented as an index into the
   * <code>options</code> array.
   * @throws IllegalArgumentException if <code>prompt</code> is <code>null</code>,
   * if <code>prompt</code> has a length of <code>0</code>, if
   * <code>messageType</code> is not either <code>INFORMATION</code>,
   * <code>WARNING</code>, or <code>ERROR</code>, if <code>options</code> is
   * <code>null</code>, if <code>options</code> has a length of <code>0</code>,
   * if any element from <code>options</code> is <code>null</code>, if any
   * element from <code>options</code> has a length of <code>0</code>, or if
   * <code>defaultOption</code> does not lie within the array boundaries of
   * <code>options</code>.
   */
  public ConfirmationCallback(String prompt, int messageType, String[] options,
			      int defaultOption)
  {
    super();

    setPrompt(prompt);
    setMessageType(messageType);
    setOptions(options, defaultOption);
    this.defaultOption = defaultOption;
  }

  // Class methods
  // -------------------------------------------------------------------------

  // Instance methods
  // -------------------------------------------------------------------------

  /**
   * Get the prompt.
   *
   * @return the prompt, or <code>null</code> if this
   * <code>ConfirmationCallback</code> was instantiated without a prompt.
   */
  public String getPrompt()
  {
    return prompt;
  }

  /**
   * Get the message type.
   *
   * @return the message type (INFORMATION, WARNING or ERROR).
   */
  public int getMessageType()
  {
    return messageType;
  }

  /**
   * <p>Get the option type.</p>
   *
   * <p>If this method returns {@link #UNSPECIFIED_OPTION}, then this
   * <code>ConfirmationCallback</code> was instantiated with <code>options</code>
   * instead of an <code>optionType</code>. In this case, invoke the
   * {@link #getOptions()} method to determine which confirmation options to
   * display.</p>
   *
   * @return the option type (YES_NO_OPTION, YES_NO_CANCEL_OPTION or
   * OK_CANCEL_OPTION), or UNSPECIFIED_OPTION if this
   * <code>ConfirmationCallback</code> was instantiated with <code>options</code>
   * instead of an <code>optionType</code>.
   */
  public int getOptionType()
  {
    if (options != null)
      {
	return UNSPECIFIED_OPTION;
      }
    return optionType;
  }

  /**
   * Get the confirmation options.
   *
   * @return the list of confirmation options, or <code>null</code> if this
   * <code>ConfirmationCallback</code> was instantiated with an
   * <code>optionType</code> instead of <code>options</code>.
   */
  public String[] getOptions()
  {
    return options;
  }

  /**
   * Get the default option.
   *
   * @return the default option, represented as <code>YES</code>, <code>NO</code>,
   * <code>OK</code> or <code>CANCEL</code> if an <code>optionType</code> was
   * specified to the constructor of this <code>ConfirmationCallback</code>.
   * Otherwise, this method returns the default option as an index into the
   * <code>options</code> array specified to the constructor of this
   * <code>ConfirmationCallback</code>.
   */
  public int getDefaultOption()
  {
    return defaultOption;
  }

  /**
   * Set the selected confirmation option.
   *
   * @param selection the selection represented as <code>YES</code>,
   * <code>NO</code>, <code>OK</code> or <code>CANCEL</code> if an
   * <code>optionType</code> was specified to the constructor of this
   * <code>ConfirmationCallback</code>. Otherwise, the <code>selection</code>
   * represents the index into the <code>options</code> array specified to the
   * constructor of this <code>ConfirmationCallback</code>.
   * @see #getSelectedIndex()
   */
  public void setSelectedIndex(int selection)
  {
    if (options != null)
      {
	setOptions(options, selection);
      }
    else
      {
	setOptionType(optionType, selection);
      }
  }

  /**
   * Get the selected confirmation option.
   *
   * @return the selected confirmation option represented as <code>YES</code>,
   * <code>NO</code>, <code>OK</code> or <code>CANCEL</code> if an
   * <code>optionType</code> was specified to the constructor of this
   * <code>ConfirmationCallback</code>. Otherwise, this method returns the
   * selected confirmation option as an index into the <code>options</code>
   * array specified to the constructor of this <code>ConfirmationCallback</code>.
   * @see #setSelectedIndex(int)
   */
  public int getSelectedIndex()
  {
    return this.selection;
  }

  private void setMessageType(int messageType) throws IllegalArgumentException
  {
    switch (messageType)
      {
      case INFORMATION:
      case WARNING:
      case ERROR: this.messageType = messageType; break;
      default: throw new IllegalArgumentException("illegal message type");
      }
  }

  private void setOptionType(int optionType, int selectedOption)
    throws IllegalArgumentException
  {
    switch (optionType)
      {
      case YES_NO_OPTION:
	this.optionType = optionType;
	switch (selectedOption)
	  {
	  case YES:
	  case NO: this.selection = selectedOption; break;
	  default: throw new IllegalArgumentException("invalid option");
	  }
	break;
      case YES_NO_CANCEL_OPTION:
	this.optionType = optionType;
	switch (selectedOption)
	  {
	  case YES:
	  case NO:
	  case CANCEL: this.selection = selectedOption; break;
	  default: throw new IllegalArgumentException("invalid option");
	  }
	break;
      case OK_CANCEL_OPTION:
	this.optionType = optionType;
	switch (selectedOption)
	  {
	  case OK:
	  case CANCEL: this.selection = selectedOption; break;
	  default: throw new IllegalArgumentException("invalid option");
	  }
	break;
      default:
	throw new IllegalArgumentException("illegal option type");
      }
  }

  private void setOptions(String[] options, int selectedOption)
    throws IllegalArgumentException
  {
    if ((selectedOption < 0) || (selectedOption > options.length - 1))
      {
	throw new IllegalArgumentException("invalid selection");
      }
    if ((options == null) || (options.length == 0))
      {
	throw new IllegalArgumentException("options is null or empty");
      }
    for (int i = 0; i < options.length; i++)
      {
	if ((options[i] == null) || (options[i].length() == 0))
	  {
	    throw new IllegalArgumentException("options[" + i + "] is null or empty");
	  }
      }
    this.options = options;
    this.selection = selectedOption;
  }

  private void setPrompt(String prompt) throws IllegalArgumentException
  {
    if ((prompt == null) || (prompt.length() == 0))
      {
	throw new IllegalArgumentException("prompt is null or empty");
      }
    this.prompt = prompt;
  }
}
