/*******************************************************************************
 * Copyright (c) 2001, 2004 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.command.internal.env.ui.dialog;

import java.util.Arrays;
import java.util.Iterator;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.wst.command.env.common.StringUtils;
import org.eclipse.wst.command.env.core.common.Choice;
import org.eclipse.wst.command.env.core.common.Status;


/**
 * A dialog to display one or more errors to the user, as contained in an
 * <code>Status</code> object. If an error contains additional detailed
 * information then a Details button is automatically supplied, which shows or
 * hides an error details viewer when pressed by the user.
 *  
 */
public class MessageDialog extends Dialog
{
  protected Composite parent;

  /**
   * Reserve room for this many list items.
   */
  protected static final int LIST_ITEM_COUNT = 7;

  /**
   * The Details button.
   */
  protected Button detailsButton;

  /**
   * The title of the dialog.
   */
  protected String title;

  /**
   * The message to display.
   */
  protected String message;

  /**
   * The SWT list control that displays the error details.
   */
  protected List list;
  protected Text details;

  /**
   * Indicates whether the error details viewer is currently created.
   */
  protected boolean listCreated = false;
  protected boolean detailsCreated = false;

  /**
   * Filter mask for determining which status items to display.
   */
  protected int displayMask = 0xFFFF;

  /**
   * The main status object.
   */
  protected Status status;
  
  private Point savedSize = null;

  /**
   * List of the main error object's detailed errors (element type: <code>Status</code>).
   */
  protected java.util.List statusList;
  /**
   * Creates an error dialog. Note that the dialog will have no visual
   * representation (no widgets) until it is told to open.
   * <p>
   * Normally one should use <code>openError</code> to create and open one of
   * these. This constructor is useful only if the error object being displayed
   * contains child items <it>and</it> you need to specify a mask which will
   * be used to filter the displaying of these children.
   * </p>
   * 
   * @param parentShell
   *            the shell under which to create this dialog
   * @param dialogTitle
   *            the title to use for this dialog, or <code>null</code> to
   *            indicate that the default title should be used
   * @param message
   *            the message to show in this dialog, or <code>null</code> to
   *            indicate that the error's message should be shown as the
   *            primary message
   * @param status
   *            the error to show to the user
   * @param displayMask
   *            the mask to use to filter the displaying of child items, as per
   *            <code>Status.matches</code>
   */
  public MessageDialog(
    Shell parentShell,
    String dialogTitle,
    String message,
    Status status,
    int displayMask)
  {
    super(parentShell);
      this.title = dialogTitle == null ? JFaceResources.getString("Problem_Occurred") : //$NON-NLS-1$
  dialogTitle;
    this.message = message == null ? status.getMessage() : JFaceResources.format("Reason", new Object[] { message, status.getMessage()}); //$NON-NLS-1$
    this.status = status;
    statusList = Arrays.asList(status.getChildren());
    this.displayMask = displayMask;
    setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.APPLICATION_MODAL);
  }
  /*
   * (non-Javadoc) Method declared on Dialog. Handles the pressing of the Ok or
   * Details button in this dialog. If the Ok button was pressed then close
   * this dialog. If the Details button was pressed then toggle the displaying
   * of the error details area. Note that the Details button will only be
   * visible if the error being displayed specifies child details.
   */
  protected void buttonPressed(int id)
  {
    if (id == StatusDialogConstants.DETAILS_ID)
    { // was the details button pressed?
      toggleDetailsArea();
    }
    else
    {
      super.buttonPressed(id);
    }
  }
  /*
   * (non-Javadoc) Method declared in Window.
   */
  protected void configureShell(Shell shell)
  {
    super.configureShell(shell);
    shell.setText(title);
  }
  /*
   * (non-Javadoc) This should also be overwritten Method declared on Dialog.
   */
  protected void createButtonsForButtonBar(Composite parent)
  {
    // create OK and Details buttons
    createButton(
      parent,
      StatusDialogConstants.OK_ID,
      IDialogConstants.OK_LABEL,
      true);
    if (status.hasChildren() || status.getThrowable() != null )
    {
      detailsButton =
        createButton(
          parent,
          StatusDialogConstants.DETAILS_ID,
          IDialogConstants.SHOW_DETAILS_LABEL,
          false);
    }
    
    parent.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
  }

  /*
   * This is one of the few methods that needs to be overwritten by the
   * subclasses. The image names can be found in the Dialog class
   */
  protected Image getDialogImage()
  {
    // create image
    return JFaceResources.getImageRegistry().get(DLG_IMG_INFO);
  }

  /*
   * (non-Javadoc) Method declared on Dialog. Creates and returns the contents
   * of the upper part of the dialog (above the button bar).
   */
  protected Control createDialogArea(Composite parent)
  {
    this.parent = parent;

    // create composite
    Composite composite = (Composite) super.createDialogArea(parent);
    Composite imageAndLabel = new Composite(composite, SWT.NONE);
    GridLayout gl = new GridLayout();
    gl.numColumns = 2;
    imageAndLabel.setLayout(gl);
    composite.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
    
    // create image
    Image image = getDialogImage();
    if (image != null)
    {
      Label label = new Label(imageAndLabel, 0);
      image.setBackground(label.getBackground());
      label.setImage(image);
      label.setLayoutData(
        new GridData(
          GridData.HORIZONTAL_ALIGN_CENTER
            | GridData.VERTICAL_ALIGN_BEGINNING));
    }

    // create message
    if (message != null)
    {
      Text text = new Text(imageAndLabel, SWT.READ_ONLY|SWT.WRAP);
      text.setText(message);
      GridData data =
        new GridData(
          GridData.GRAB_HORIZONTAL
            | GridData.GRAB_VERTICAL
            | GridData.HORIZONTAL_ALIGN_FILL
            | GridData.VERTICAL_ALIGN_CENTER);
      data.widthHint =
        convertHorizontalDLUsToPixels(
          IDialogConstants.MINIMUM_MESSAGE_AREA_WIDTH);
     
      text.setLayoutData(data);
      text.setFont(parent.getFont());
    }

    return composite;
  }

  protected List createDropDownList(Composite parent)
  {
    // create the list
    list = new List(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);

    // fill the list
    populateList(list);

    GridData data =
      new GridData(
        GridData.HORIZONTAL_ALIGN_FILL
          | GridData.GRAB_HORIZONTAL
          | GridData.VERTICAL_ALIGN_FILL
          | GridData.GRAB_VERTICAL);
    data.heightHint = list.getItemHeight() * LIST_ITEM_COUNT;
    list.setLayoutData(data);
    listCreated = true;
    return list;
  }
  protected Text createDropDownDetails(Composite parent)
  {
    details = new Text(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.READ_ONLY);
    //details.setEditable(false);
    Color color = new Color(parent.getShell().getDisplay(), 255, 255, 255);
    details.setBackground(color);
    populateDetails(details, status, 0);
    GridData data =
      new GridData(
        GridData.HORIZONTAL_ALIGN_FILL
          | GridData.GRAB_HORIZONTAL
          | GridData.VERTICAL_ALIGN_FILL
          | GridData.GRAB_VERTICAL);
    details.setLayoutData(data);
    details.setSelection(0);
    detailsCreated = true;
    return details;
  }
  /*
   * (non-Javadoc) Method declared on Window.
   */
  /**
   * Extends <code>Window.open()</code>. Opens an error dialog to display
   * the error. If you specified a mask to filter the displaying of these
   * children, the error dialog will only be displayed if there is at least one
   * child status matching the mask.
   */
  public int open()
  {
    if (shouldDisplay(status, displayMask))
    {
      return super.open();
    }
    return 0;
  }
  /**
   * This essentially does the work of a factory Opens an error dialog to
   * display the given error. Use this method if the error object being
   * displayed does not contain child items, or if you wish to display all such
   * items without filtering.
   * 
   * @param parent
   *            the parent shell of the dialog, or <code>null</code> if none
   * @param dialogTitle
   *            the title to use for this dialog, or <code>null</code> to
   *            indicate that the default title should be used
   * @param message
   *            the message to show in this dialog, or <code>null</code> to
   *            indicate that the error's message should be shown as the
   *            primary message
   * @param status
   *            the error to show to the user
   * @return the code of the button that was pressed that resulted in this
   *         dialog closing. This will be <code>Dialog.OK</code> if the OK
   *         button was pressed, or <code>Dialog.CANCEL</code> if this
   *         dialog's close window decoration or the ESC key was used.
   */
  public static int openMessage(
    Shell parent,
    String dialogTitle,
    String message,
    Status status)
  {

    switch (status.getSeverity())
    {
      case Status.INFO :
        return openInfo(
          parent,
          dialogTitle,
          message,
          status,
          Status.OK | Status.INFO | Status.WARNING | Status.ERROR);
      case Status.WARNING :
        return openWarning(
          parent,
          dialogTitle,
          message,
          status,
          Status.OK | Status.INFO | Status.WARNING | Status.ERROR);
      default :
        return openError(
          parent,
          dialogTitle,
          message,
          status,
          Status.OK | Status.INFO | Status.WARNING | Status.ERROR);
    }

  }

  public static int openMessage(
    Shell parent,
    String dialogTitle,
    String message,
    Status status,
    Choice[] options)
  {

    return openOptions(
      parent,
      dialogTitle,
      message,
      status,
      Status.OK | Status.INFO | Status.WARNING | Status.ERROR,
      options);
  }

  /**
   * Opens an error dialog to display the given error. Use this method if the
   * error object being displayed contains child items <it>and</it> you wish
   * to specify a mask which will be used to filter the displaying of these
   * children. The error dialog will only be displayed if there is at least one
   * child status matching the mask.
   * 
   * @param parentShell
   *            the parent shell of the dialog, or <code>null</code> if none
   * @param dialogTitle
   *            the title to use for this dialog, or <code>null</code> to
   *            indicate that the default title should be used
   * @param message
   *            the message to show in this dialog, or <code>null</code> to
   *            indicate that the error's message should be shown as the
   *            primary message
   * @param status
   *            the error to show to the user
   * @param displayMask
   *            the mask to use to filter the displaying of child items, as per
   *            <code>Status.matches</code>
   * @return the code of the button that was pressed that resulted in this
   *         dialog closing. This will be <code>Dialog.OK</code> if the OK
   *         button was pressed, or <code>Dialog.CANCEL</code> if this
   *         dialog's close window decoration or the ESC key was used.
   */
  public static int openError(
    Shell parentShell,
    String title,
    String message,
    Status status,
    int displayMask)
  {
    ErrorDialog dialog =
      new ErrorDialog(parentShell, title, message, status, displayMask);
    return dialog.open();
  }

  public static int openInfo(
    Shell parentShell,
    String title,
    String message,
    Status status,
    int displayMask)
  {
    InfoDialog dialog =
      new InfoDialog(parentShell, title, message, status, displayMask);
    return dialog.open();
  }

  public static int openWarning(
    Shell parentShell,
    String title,
    String message,
    Status status,
    int displayMask)
  {
    WarningDialog dialog =
      new WarningDialog(parentShell, title, message, status, displayMask);
    return dialog.open();
  }

  public static int openOptions(
    Shell parentShell,
    String title,
    String message,
    Status status,
    int displayMask,
    Choice[] options)
  {
    OptionsDialog dialog =
      new OptionsDialog(
        parentShell,
        title,
        message,
        status,
        displayMask,
        options);
    dialog.open();
    return dialog.getReturnCode();
  }

  /**
   * Populates the list using this error dialog's status object. This walks the
   * child stati of the status object and displays them in a list. The format
   * for each entry is status_path : status_message If the status's path was
   * null then it (and the colon) are omitted.
   */
  private void populateList(List list)
  {
    Iterator enumeration = statusList.iterator();
    while (enumeration.hasNext())
    {
      Status childStatus = (Status) enumeration.next();
      populateList(list, childStatus, 0);
    }
  }
  private void populateList(List list, Status status, int nesting)
  {
    if (!status.matches(displayMask))
    {
      return;
    }
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < nesting; i++)
    {
      sb.append("  ");
    }
    sb.append(status.getMessage());
    list.add(sb.toString());
    Status[] children = status.getChildren();
    for (int i = 0; i < children.length; i++)
    {
      populateList(list, children[i], nesting + 1);
    }
  }
  private void populateDetails(Text text, Status status, int nesting)
  {
    if (!status.matches(displayMask))
    {
      return;
    }
        
    String    tabChars    = StringUtils.repeat( ' ', nesting * 2 );
    String    messageLine = tabChars + status.getMessage() + System.getProperty("line.separator");
    Throwable except      = status.getThrowable();
    
    text.append( messageLine );
    
    if( except != null )
    {
      String[] trace = StringUtils.getStackTrace( except );
      
      for( int index = 0; index < trace.length; index++ )
      {
        text.append( tabChars + "    " + trace[index] + System.getProperty("line.separator") );
      }
    }
    
    Status[] children = status.getChildren();
    for (int i = 0; i < children.length; i++)
    {
      populateDetails(text, children[i], nesting + 1);
    }
  }
  /**
   * Returns whether the given status object should be displayed.
   * 
   * @param status
   *            a status object
   * @param mask
   *            a mask as per <code>Status.matches</code>
   * @return <code>true</code> if the given status should be displayed, and
   *         <code>false</code> otherwise
   */
  protected static boolean shouldDisplay(Status status, int mask)
  {
    Status[] children = status.getChildren();
    if (children == null || children.length == 0)
    {
      return status.matches(mask);
    }
    for (int i = 0; i < children.length; i++)
    {
      if (children[i].matches(mask))
        return true;
    }
    return false;
  }
  /**
   * Toggles the unfolding of the details area. This is triggered by the user
   * pressing the details button.
   */
  private void toggleDetailsArea()
  {
    Point windowSize = getShell().getSize();
    int   newHeight  = -1;
    
    if (detailsCreated)
    {
      details.dispose();
      detailsCreated = false;
      detailsButton.setText(IDialogConstants.SHOW_DETAILS_LABEL);
      
      // Without the following computeSize call the setSize call below throws an array out of bounds exception.
      // Very weird.
      getContents().computeSize(SWT.DEFAULT, SWT.DEFAULT);
      
      newHeight = savedSize.y;
    }
    else
    {
      if( savedSize == null ) savedSize = windowSize;
        
      details = createDropDownDetails((Composite) getContents());
      detailsButton.setText(IDialogConstants.HIDE_DETAILS_LABEL);
      newHeight = getContents().computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
    }


    newHeight = newHeight > 400 ? 400 : newHeight;
    
    getShell().setSize( new Point(windowSize.x, newHeight) );
  }
}
