/*******************************************************************************
 * Copyright (c) 2001, 2005 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.common.frameworks.internal.dialog.ui;

import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Arrays;
import java.util.Iterator;
import java.util.Vector;
import org.eclipse.core.runtime.IStatus;
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.ui.PlatformUI;
import org.eclipse.wst.common.environment.Choice;


/**
 * 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 IStatus 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,
    IStatus 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.isMultiStatus() || status.getException() != 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 PlatformUI.getWorkbench().getDisplay().getSystemImage(SWT.ICON_INFORMATION);
  }

  /*
   * (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,
    IStatus status)
  {

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

  }

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

    return openOptions(
      parent,
      dialogTitle,
      message,
      status,
      IStatus.OK | IStatus.INFO | IStatus.WARNING | IStatus.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,
    IStatus 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,
    IStatus 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,
    IStatus 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,
    IStatus 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())
    {
      IStatus childStatus = (IStatus) enumeration.next();
      populateList(list, childStatus, 0);
    }
  }
  private void populateList(List list, IStatus 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());
    IStatus[] children = status.getChildren();
    for (int i = 0; i < children.length; i++)
    {
      populateList(list, children[i], nesting + 1);
    }
  }
  private void populateDetails(Text text, IStatus status, int nesting)
  {
    if (!status.matches(displayMask))
    {
      return;
    }
        
    String    tabChars    = repeat( ' ', nesting * 2 );
    String    messageLine = tabChars + status.getMessage() + System.getProperty("line.separator");
    Throwable except      = status.getException();
    
    text.append( messageLine );
    
    if( except != null )
    {
      String[] trace = getStackTrace( except );
      
      for( int index = 0; index < trace.length; index++ )
      {
        text.append( tabChars + "    " + trace[index] + System.getProperty("line.separator") );
      }
    }
    
    IStatus[] 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(IStatus status, int mask)
  {
    IStatus[] 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) );
  }
  
  private String[] getStackTrace( Throwable exc )
  {
    Vector       lines        = new Vector();
    StringWriter stringWriter = new StringWriter();
    PrintWriter  printWriter  = new PrintWriter( stringWriter );
    
    exc.printStackTrace( printWriter );
    
    try
    {
      printWriter.close();
      stringWriter.close();
    }
    catch( Exception nestedExc )
    {
      return new String[0];
    }
    
    StringReader stringReader = new StringReader( stringWriter.toString() );
    BufferedReader reader     = new BufferedReader( stringReader );
    String         line       = null;
    
    try
    {
      line = reader.readLine();
    
      while( line != null )
      {
        lines.add( line.trim() );
        line = reader.readLine();
      }
    }
    catch( Exception nestedExc )
    {
      return new String[0];
    }
    
    return (String[])lines.toArray( new String[0] );
  }
  
  private String repeat( char the_char, int count )
  {
    StringBuffer buf = new StringBuffer( count );

    for( int index = 0; index < count; index++ )
    {
      buf.append( the_char );
    }

    return buf.toString();
  }
  
}
