/*   **********************************************************************  **
 **   Copyright notice                                                       **
 **                                                                          **
 **   (c) 2003-2006 RSSOwl Development Team                                  **
 **   http://www.rssowl.org/                                                 **
 **                                                                          **
 **   All rights reserved                                                    **
 **                                                                          **
 **   This program and the accompanying materials are made available under   **
 **   the terms of the Eclipse Public License 1.0 which accompanies this     **
 **   distribution, and is available at:                                     **
 **   http://www.rssowl.org/legal/epl-v10.html                               **
 **                                                                          **
 **   A copy is found in the file epl-v10.html and important notices to the  **
 **   license from the team is found in the textfile LICENSE.txt distributed **
 **   in this package.                                                       **
 **                                                                          **
 **   This copyright notice MUST APPEAR in all copies of the file!           **
 **                                                                          **
 **   Contributors:                                                          **
 **     RSSOwl - initial API and implementation (bpasero@rssowl.org)         **
 **                                                                          **
 **  **********************************************************************  */

package net.sourceforge.rssowl.controller.dialog;

import net.sourceforge.rssowl.controller.GUI;
import net.sourceforge.rssowl.controller.properties.EditFavoriteProperties;
import net.sourceforge.rssowl.controller.properties.ViewFavoriteProperties;
import net.sourceforge.rssowl.model.Favorite;
import net.sourceforge.rssowl.util.GlobalSettings;
import net.sourceforge.rssowl.util.shop.FontShop;
import net.sourceforge.rssowl.util.shop.LayoutShop;
import net.sourceforge.rssowl.util.shop.PaintShop;
import net.sourceforge.rssowl.util.shop.StringShop;

import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
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.Shell;
import org.eclipse.swt.widgets.TabFolder;
import org.eclipse.swt.widgets.TabItem;

/**
 * The edit favorite dialog allows to change and view settings of a favorite. It
 * uses the same layout as the preferences dialog with a tree on the left side
 * to select items.
 * 
 * @author <a href="mailto:bpasero@rssowl.org">Benjamin Pasero </a>
 * @version 1.2.3
 */
public class FavoriteDialog extends Dialog {

  /** Flag to set if dialog is in edit or new mode */
  public static boolean isEditFavorite = false;

  /** Min. width of the dialog in DLUs */
  private static final int dialogMinWidth = 400;

  private Favorite editedFavorite;
  private EditFavoriteProperties editFavProps;
  private TabItem infoItem;
  private TabItem settingsItem;
  private TabFolder tabFolder;
  private String title;

  /**
   * Creates a Dialog with a tab showing different categories. Each selected
   * tabitem will open a view to change some settings. Note that the dialog will
   * have no visual representation (no widgets) until it is told to open.
   * <p>
   * Note that the <code>open</code> method blocks for input dialogs.
   * </p>
   * 
   * @param favorite The favorite that is edited
   * @param parentShell the parent shell
   * @param dialogTitle the dialog title, or <code>null</code> if none
   */
  public FavoriteDialog(Favorite favorite, Shell parentShell, String dialogTitle) {
    super(parentShell);
    this.title = dialogTitle;

    /** Create Temp Favorite to have all data of the favorite */
    editedFavorite = new Favorite("", "", null);
    favorite.duplicate(editedFavorite);
  }

  /**
   * Get the updated favorite from this dialog
   * 
   * @return Favorite The updated favorite
   */
  public Favorite getUpdatedFavorite() {
    return editedFavorite;
  }

  /**
   * @see org.eclipse.jface.dialogs.Dialog#buttonPressed(int)
   */
  protected void buttonPressed(int buttonId) {

    /** Save updated favorite */
    if (buttonId == IDialogConstants.OK_ID) {
      String initialUrl = editedFavorite.getUrl() != null ? editedFavorite.getUrl() : "";

      /** Edit Favorite propertypage is opened - Save Favorite */
      editedFavorite = editFavProps.getUpdatedFavorite();

      /** Validate input of the new or edited favorite: URL */
      if (editedFavorite.getUrl().equals("")) {
        editFavProps.setMessage(GUI.i18n.getTranslation("MESSAGEBOX_FILL_URL"), true);
        tabFolder.setSelection(0);
        return;
      }

      /** Validate input of the new or edited favorite: Category */
      if (!StringShop.isset(editedFavorite.getCatPath())) {
        editFavProps.setMessage(GUI.i18n.getTranslation("MESSAGEBOX_SELECT_CAT"), true);
        tabFolder.setSelection(0);
        return;
      }

      /** Reset Metadata and Unread Count if Channel unknown but Favorite updated */
      if (!initialUrl.equals(editedFavorite.getUrl())) {
        editedFavorite.setUnreadNewsCount(0);
        editedFavorite.clearMetaData();
      }
    }

    /** Close Dialog */
    super.buttonPressed(buttonId);
  }

  /**
   * @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
   */
  protected void configureShell(Shell shell) {
    shell.setLayout(LayoutShop.createGridLayout(1, 0, 5));

    /** On Mac do not set Shell Image since it will change the Dock Image */
    if (!GlobalSettings.isMac())
      shell.setImages(PaintShop.iconOwl);

    shell.setText(title);
    shell.setSize(0, 0);
  }

  /**
   * @see org.eclipse.jface.dialogs.Dialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
   */
  protected void createButtonsForButtonBar(Composite parent) {

    /** Override parent, DLU dependant margins */
    ((GridLayout) parent.getLayout()).marginHeight = 5;
    ((GridLayout) parent.getLayout()).marginWidth = 10;

    /** Button order on Mac is different */
    if (GUI.display.getDismissalAlignment() == SWT.RIGHT) {
      createButton(parent, IDialogConstants.CANCEL_ID, GUI.i18n.getTranslation("BUTTON_CANCLE"), false).setFont(FontShop.dialogFont);
      createButton(parent, IDialogConstants.OK_ID, GUI.i18n.getTranslation("BUTTON_OK"), true).setFont(FontShop.dialogFont);
    } else {
      createButton(parent, IDialogConstants.OK_ID, GUI.i18n.getTranslation("BUTTON_OK"), true).setFont(FontShop.dialogFont);
      createButton(parent, IDialogConstants.CANCEL_ID, GUI.i18n.getTranslation("BUTTON_CANCLE"), false).setFont(FontShop.dialogFont);
    }
  }

  /**
   * @see org.eclipse.jface.dialogs.Dialog#createDialogArea(org.eclipse.swt.widgets.Composite)
   */
  protected Control createDialogArea(Composite parent) {

    /** Composite to hold all components */
    Composite baseComposite = (Composite) super.createDialogArea(parent);
    baseComposite.setLayout(LayoutShop.createFillLayout(5, 5));
    baseComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));

    /** TabFolder for Settings and Info TabItems */
    tabFolder = new TabFolder(baseComposite, SWT.TOP);
    tabFolder.setFont(FontShop.dialogFont);

    /** TabItem showing Settings for the Favorite */
    settingsItem = new TabItem(tabFolder, SWT.NONE);
    settingsItem.setText(GUI.i18n.getTranslation("POP_PROPERTIES"));

    /** Container for Favorite's Settings */
    Composite settingsContentHolder = new Composite(tabFolder, SWT.NONE);
    settingsContentHolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
    settingsContentHolder.setLayout(LayoutShop.createGridLayout(1, 5, 0));

    /** Create Favorite's Settings */
    editFavProps = new EditFavoriteProperties(settingsContentHolder, editedFavorite);

    /** Apply container to TabItem */
    settingsItem.setControl(settingsContentHolder);

    /** TabItem showing Info for the Favorite only visible in Edit Mode */
    if (isEditFavorite) {

      /** TabItem showing Infos for the Favorite */
      infoItem = new TabItem(tabFolder, SWT.NONE);
      infoItem.setText(GUI.i18n.getTranslation("MESSAGEBOX_TITLE_INFORMATION"));

      /** Container for Favorite's Infos */
      Composite infoContentHolder = new Composite(tabFolder, SWT.NONE);
      infoContentHolder.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
      infoContentHolder.setLayout(LayoutShop.createGridLayout(1, 5, 0));

      /** Create Favorite's Infos */
      new ViewFavoriteProperties(infoContentHolder, editedFavorite);

      /** Apply container to TabItem */
      infoItem.setControl(infoContentHolder);
    }

    return baseComposite;
  }

  /**
   * @see org.eclipse.jface.window.Window#getShellStyle()
   */
  protected int getShellStyle() {
    int style = SWT.TITLE | SWT.BORDER | SWT.RESIZE | SWT.APPLICATION_MODAL | getDefaultOrientation();

    /** Follow Apple's Human Interface Guidelines for Application Modal Dialogs */
    if (!GlobalSettings.isMac())
      style |= SWT.CLOSE;

    return style;
  }

  /**
   * @see org.eclipse.jface.dialogs.Dialog#initializeBounds()
   */
  protected void initializeBounds() {
    initializeBounds(true);
  }

  /**
   * Set size and location of the dialog
   * 
   * @param updateLocation If TRUE also update the location of the dialog
   */
  protected void initializeBounds(boolean updateLocation) {
    super.initializeBounds();
    Point currentSize = getShell().getSize();

    Point bestSize = getShell().computeSize(convertHorizontalDLUsToPixels(dialogMinWidth), SWT.DEFAULT);

    /** Calculate new location or use old one */
    Point location = (updateLocation == true) ? getInitialLocation(bestSize) : getShell().getLocation();

    /** Only change if dialog needs to become bigger */
    if (bestSize.y > currentSize.y)
      getShell().setBounds(location.x, location.y, bestSize.x, bestSize.y);

    /** Also define minimium size */
    getShell().setMinimumSize(bestSize.x, bestSize.y);
  }

  /**
   * Set the layout data of the button to a GridData with appropriate widths
   * This method was slightly modified so that it is not setting a heightHint.
   * 
   * @param button The button to layout
   */
  protected void setButtonLayoutData(Button button) {
    GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
    int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
    data.widthHint = Math.max(widthHint, button.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x);
    button.setLayoutData(data);
  }
}