/*   **********************************************************************  **
 **   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.util.shop;

import net.sourceforge.rssowl.controller.GUI;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

/**
 * Factory class for some LayoutData concerns in RSSOwl.
 * 
 * @author <a href="mailto:bpasero@rssowl.org">Benjamin Pasero </a>
 * @version 1.2.3
 */
public class LayoutShop {

  /** This utility class constructor is hidden */
  private LayoutShop() {
  // Protect default constructor
  }

  /**
   * Center a shell on the monitor
   * 
   * @param display The display
   * @param shell The shell to center
   */
  public static void centerShell(Display display, Shell shell) {
    Rectangle displayBounds = display.getPrimaryMonitor().getBounds();
    Rectangle shellBounds = shell.getBounds();
    int x = displayBounds.x + (displayBounds.width - shellBounds.width) >> 1;
    int y = displayBounds.y + (displayBounds.height - shellBounds.height) >> 1;
    shell.setLocation(x, y);
  }

  /**
   * Create a new FillLayout with the given parameters
   * 
   * @param marginWidth Margin width in pixel
   * @param marginHeight Margin height in pixel
   * @return FillLayout New FillLayout with the given parameters
   */
  public static FillLayout createFillLayout(int marginWidth, int marginHeight) {
    FillLayout f = new FillLayout();
    f.marginHeight = marginHeight;
    f.marginWidth = marginWidth;
    return f;
  }

  /**
   * Create a new GridLayout with the given parameters
   * 
   * @param cols The number of columns
   * @return GridLayout New GridLayout with the given parameters
   */
  public static GridLayout createGridLayout(int cols) {
    return createGridLayout(cols, 5, 5, 5, 5, false);
  }

  /**
   * Create a new GridLayout with the given parameters
   * 
   * @param cols The number of columns
   * @param marginWidth Margin width in pixel
   * @return GridLayout New GridLayout with the given parameters
   */
  public static GridLayout createGridLayout(int cols, int marginWidth) {
    return createGridLayout(cols, marginWidth, 5, 5, 5, false);
  }

  /**
   * Create a new GridLayout with the given parameters
   * 
   * @param cols The number of columns
   * @param marginWidth Margin width in pixel
   * @param marginHeight Margin height in pixel
   * @return GridLayout New GridLayout with the given parameters
   */
  public static GridLayout createGridLayout(int cols, int marginWidth, int marginHeight) {
    return createGridLayout(cols, marginWidth, marginHeight, 5, 5, false);
  }

  /**
   * Create a new GridLayout with the given parameters
   * 
   * @param cols The number of columns
   * @param marginWidth Margin width in pixel
   * @param marginHeight Margin height in pixel
   * @param makeColumnsEqualWidth TRUE if columns should be equals in size
   * @return GridLayout New GridLayout with the given parameters
   */
  public static GridLayout createGridLayout(int cols, int marginWidth, int marginHeight, boolean makeColumnsEqualWidth) {
    return createGridLayout(cols, marginWidth, marginHeight, 5, 5, makeColumnsEqualWidth);
  }

  /**
   * Create a new GridLayout with the given parameters
   * 
   * @param cols The number of columns
   * @param marginWidth Margin width in pixel
   * @param marginHeight Margin height in pixel
   * @param verticalSpacing Vertical spacing in pixel
   * @return GridLayout New GridLayout with the given parameters
   */
  public static GridLayout createGridLayout(int cols, int marginWidth, int marginHeight, int verticalSpacing) {
    return createGridLayout(cols, marginWidth, marginHeight, verticalSpacing, 5, false);
  }

  /**
   * Create a new GridLayout with the given parameters
   * 
   * @param cols The number of columns
   * @param marginWidth Margin width in pixel
   * @param marginHeight Margin height in pixel
   * @param verticalSpacing Vertical spacing in pixel
   * @param horizontalSpacing Horizontal spacing in pixel
   * @param makeColumnsEqualWidth TRUE if columns should be equals in size
   * @return GridLayout New GridLayout with the given parameters
   */
  public static GridLayout createGridLayout(int cols, int marginWidth, int marginHeight, int verticalSpacing, int horizontalSpacing, boolean makeColumnsEqualWidth) {
    GridLayout g = new GridLayout(cols, makeColumnsEqualWidth);
    g.marginHeight = marginHeight;
    g.marginWidth = marginWidth;
    g.verticalSpacing = verticalSpacing;
    g.horizontalSpacing = horizontalSpacing;
    return g;
  }

  /**
   * Sets the initial location to use for the shell. The default implementation
   * centers the shell horizontally (1/2 of the difference to the left and 1/2
   * to the right) and vertically (1/3 above and 2/3 below) relative to the
   * parent shell
   * 
   * @param shell The shell to set the location
   * @param computeSize If TRUE, initialSize is computed from the Shell
   * @param sameDialogCount In the case the same dialog is opened more than
   * once, do not position the Shells on the same position. The sameDialogCount
   * integer tells how many dialogs of the same kind are already open. This
   * number is used to move the new dialog by some pixels.
   */
  public static void positionShell(Shell shell, boolean computeSize, int sameDialogCount) {
    Rectangle containerBounds = GUI.shell.getBounds();
    Point initialSize = (computeSize == true) ? shell.computeSize(SWT.DEFAULT, SWT.DEFAULT, true) : shell.getSize();
    int x = Math.max(0, containerBounds.x + (containerBounds.width - initialSize.x) >> 1);
    int y = Math.max(0, containerBounds.y + (containerBounds.height - initialSize.y) / 3);
    shell.setLocation(x + sameDialogCount * 20, y + sameDialogCount * 20);
  }

  /**
   * Set invisible labels as spacer to a composite. The labels will grab
   * vertical space.
   * 
   * @param composite The control to add the spacer into
   * @param cols Is used as horizontal span in the GridData
   * @param rows Number of labels that are created
   */
  public static void setDialogSpacer(Composite composite, int cols, int rows) {
    for (int a = 0; a < rows; a++) {
      Label spacer = new Label(composite, SWT.NONE);
      spacer.setLayoutData(LayoutDataShop.createGridData(GridData.HORIZONTAL_ALIGN_BEGINNING, cols));
      spacer.setFont(FontShop.dialogFont);
    }
  }

  /**
   * Recursivly update layout for given control and childs
   * 
   * @param control The control to set the layout
   */
  public static void setLayoutForAll(Control control) {
    if (control instanceof Composite) {
      Control[] childs = ((Composite) control).getChildren();
      for (int a = 0; a < childs.length; a++)
        setLayoutForAll(childs[a]);

      ((Composite) control).layout();
    }
  }
}