/*******************************************************************************
 * Copyright (c) 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.ui.internal.layout;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;

/**
 * <code>CellData</code> is the layout data object associated with 
 * <code>CellLayout</code>. You can attach a CellData object to a
 * control by using the <code>setLayoutData</code> method. CellData
 * objects are optional. If you do not attach any layout data to a control,
 * it will behave just like attaching a CellData created using its default
 * constructor.
 * 
 * @since 3.0
 **/
public final class CellData {

    /**
     * hintType flag (value = 0) indicating that the control's computeSize method should be used
     * to determine the control size. If modifierType is set to NONE, then the widthHint
     * and heightHint fields will be ignored.
     */
    public final static int NONE = 0;

    /**
     * hintType flag (value = 1) indicating that the widthHint and heightHint should be used
     * as the control's size instead of the result of computeSize
     * <p>
     * This flag is useful for list boxes, text boxes, tree controls, and other controls
     * whose contents can change dynamically. For example, create a tree control and set
     * its width and height hints to the default size for that control. This will cause
     * the hints to be used instead of the preferred size of the tree control.</p>
     */
    public final static int OVERRIDE = 1;

    /**
     * hintType(value = 2) indicating that the width of the control should be no less than
     * widthHint (if provided) and the height of the control should be no less
     * than heightHint (if provided).
     * <p>
     * This flag is useful for buttons. For example, set the width and height hints to
     * the default button size. This will use the default button size unless the button
     * label is too large to fit on the button.
     * </p>  
     */
    public final static int MINIMUM = 2;

    /**
     * hintType flag (value = 3) indicating that the width of the control should be no more than
     * widthHint (if provided) and the height of the control should be no more
     * than heightHint (if provided). 
     * <p>
     * This flag is useful for wrapping text. For example, set heightHint to SWT.DEFAULT
     * and set widthHint to the desired number of pixels after which text should wrap. This
     * will cause the text to wrap after the given number of pixels, but will not allocate
     * extra space in the column if the text widget does not fill an entire line.
     * </p> 
     */
    public final static int MAXIMUM = 3;

    /**
     * This flag controls how the width and height hints are to be treated. See the constants
     * above. 
     */
    public int hintType = OVERRIDE;

    /**
     * Width hint. This modifies the width of the control, in pixels. If set to SWT.DEFAULT,
     * this dimension will not be constrained. Depending on the value of modifierType,
     * this may be a minimum size, a maximum size, or simply replace the preferred control
     * size.
     */
    public int widthHint = SWT.DEFAULT;

    /**
     * Height hint. This modifies the height of the control, in pixels. If set to SWT.DEFAULT,
     * this dimension will not be constrained. Depending on the value of modifierType,
     * this will be a minimum size, a maximum size, or a replacement for the control's preferred
     * size. 
     */
    public int heightHint = SWT.DEFAULT;

    /**
     * Number of rows spanned by this cell (default = 1)
     */
    public int verticalSpan = 1;

    /**
     * Number of columns spanned by this cell (default = 1)
     */
    public int horizontalSpan = 1;

    /**
     * Horizontal alignment of the control within the cell. May be one
     * of SWT.LEFT, SWT.RIGHT, SWT.CENTER, or SWT.NORMAL. SWT.NORMAL indicates
     * that the control should be made as wide as the cell.
     */
    public int horizontalAlignment = SWT.FILL;

    /**
     * Vertical alignment of the control within the cell. May be one of
     * SWT.TOP, SWT.BOTTOM, SWT.CENTER, or SWT.NORMAL. SWT.NORMAL indicates
     * that the control should be made as wide as the cell.
     */
    public int verticalAlignment = SWT.FILL;

    /**
     * Horizontal indentation (pixels). Positive values move the control 
     * to the right, negative to the left.
     */
    public int horizontalIndent = 0;

    /**
     * Vertical indentation (pixels). Positive values move the control
     * down, negative values move the control up.
     */
    public int verticalIndent = 0;

    /**
     * Constructs a CellData with default properties
     */
    public CellData() {
        // Use the default values for all fields.
    }

    /**
     * Creates a new CellData that with properties that are as close as possible to
     * the given GridData. This is used for converting GridLayouts into CellLayouts.
     * 
     * @param data
     */
    public CellData(GridData data) {
        verticalSpan = data.verticalSpan;
        horizontalSpan = data.horizontalSpan;

        switch (data.horizontalAlignment) {
        case GridData.BEGINNING:
            horizontalAlignment = SWT.LEFT;
            break;
        case GridData.CENTER:
            horizontalAlignment = SWT.CENTER;
            break;
        case GridData.END:
            horizontalAlignment = SWT.RIGHT;
            break;
        case GridData.FILL:
            horizontalAlignment = SWT.FILL;
            break;
        }

        switch (data.verticalAlignment) {
        case GridData.BEGINNING:
            verticalAlignment = SWT.LEFT;
            break;
        case GridData.CENTER:
            verticalAlignment = SWT.CENTER;
            break;
        case GridData.END:
            verticalAlignment = SWT.RIGHT;
            break;
        case GridData.FILL:
            verticalAlignment = SWT.FILL;
            break;
        }

        widthHint = data.widthHint;
        heightHint = data.heightHint;
        horizontalIndent = data.horizontalIndent;
        hintType = OVERRIDE;
    }

    /**
     * Copies the given CellData
     * 
     * @param newData
     */
    public CellData(CellData newData) {
        hintType = newData.hintType;
        widthHint = newData.widthHint;
        heightHint = newData.heightHint;
        horizontalAlignment = newData.horizontalAlignment;
        verticalAlignment = newData.verticalAlignment;
        horizontalSpan = newData.horizontalSpan;
        verticalSpan = newData.verticalSpan;
    }

    /**
     * Sets the size hint for this control. This is used to modify the control's 
     * preferred size. If one dimension should remain unmodified, that hint can be
     * set to SWT.DEFAULT. Using a size hint of CellData.MINIMUM ensures that the preferred
     * control size is larger than the hint. Using a size hint of CellData.MAXIMUM ensures
     * that the preferred size is smaller than the hint. Using a size hint of CellData.OVERRIDE
     * ensures that the preferred size is always equal to the hint. 
     * 
     * @param hintType one of CellData.MINIMUM, CellData.MAXIMUM, or CellData.OVERRIDE
     * @param hint size hint (in pixels). If either dimension is set to SWT.DEFAULT, the
     * hint will not affect that dimension 
     * @return this
     */
    public CellData setHint(int hintType, Point hint) {
        return setHint(hintType, hint.x, hint.y);
    }

    /**
     * Sets the size hint for this control. This is used to modify the control's 
     * preferred size. If one dimension should remain unmodified, that hint can be
     * set to SWT.DEFAULT. Using a size hint of CellData.MINIMUM ensures that the preferred
     * control size is larger than the hint. Using a size hint of CellData.MAXIMUM ensures
     * that the preferred size is smaller than the hint. Using a size hint of CellData.OVERRIDE
     * ensures that the preferred size is always equal to the hint. If both hints are equal
     * to SWT.DEFAULT, then the control's preferred size is unmodified.
     * 
     * @param hintType one of CellData.MINIMUM, CellData.MAXIMUM, or CellData.OVERRIDE
     * @param horizontal horizontal hint (pixels). A value of SWT.DEFAULT will leave the result
     * of the control's computeSize method unmodified.
     * @param vertical vertical hint (pixels). A value of SWT.DEFAULT will leave the result of 
     * the control's computeSize method unmodified.
     * @return this
     */
    public CellData setHint(int hintType, int horizontal, int vertical) {
        this.hintType = hintType;
        this.heightHint = vertical;
        this.widthHint = horizontal;

        return this;
    }

    /**
     * Sets the alignment for this control
     * 
     * @param horizontalAlignment one of SWT.LEFT, SWT.RIGHT, SWT.FILL, or SWT.CENTER
     * @param verticalAlignment one of SWT.TOP, SWT.BOTTOM, SWT.FILL, or SWT.CENTER
     * @return this
     */
    public CellData align(int horizontalAlignment, int verticalAlignment) {
        this.horizontalAlignment = horizontalAlignment;
        this.verticalAlignment = verticalAlignment;

        return this;
    }

    /**
     * Sets the number of rows and columns spanned by this control.
     * 
     * @param horizontalSpan number of columns spanned by the control (> 0)
     * @param verticalSpan number of rows spanned by the control (> 0)
     * @return this
     */
    public CellData span(int horizontalSpan, int verticalSpan) {
        this.horizontalSpan = horizontalSpan;
        this.verticalSpan = verticalSpan;

        return this;
    }

    /**
     * Sets the indentation for this control. The indentation is added to
     * the control's position within the cell. For example, indentation of
     * (10,4) will move the control right by 10 pixels and down by 4 pixels.
     * 
     * @param indent indentation (pixels)
     * @return this
     */
    public CellData indent(Point indent) {
        return this.indent(indent.x, indent.y);
    }

    /**
     * Sets the indentation for this cell
     * 
     * @param horizontalIndent distance (pixels) to move the control to the right
     * @param verticalIndent distance (pixels) to move the control down
     * @return this
     */
    public CellData indent(int horizontalIndent, int verticalIndent) {
        this.horizontalIndent = horizontalIndent;
        this.verticalIndent = verticalIndent;

        return this;
    }

    /**
     * Returns the preferred size of the given control, given the known dimensions of
     * its cell.
     *  
     * @param toCompute the control whose size is to be computed
     * @param cellWidth width of the cell, in pixels (or SWT.DEFAULT if unknown)
     * @param cellHeight height of the cell, in pixels (or SWT.DEFAULT if unknown)
     * @return the preferred size of the given control, in pixels
     */
    public Point computeSize(SizeCache toCompute, int cellWidth, int cellHeight) {

        int absHorizontalIndent = Math.abs(horizontalIndent);
        int absVerticalIndent = Math.abs(verticalIndent);

        // If we're going to indent, subtract off the space that will be required for indentation from
        // the available space
        if (cellWidth != SWT.DEFAULT) {
            cellWidth -= absHorizontalIndent;
        }

        if (cellHeight != SWT.DEFAULT) {
            cellHeight -= absVerticalIndent;
        }

        int controlWidth = horizontalAlignment == SWT.FILL ? cellWidth
                : SWT.DEFAULT;
        int controlHeight = verticalAlignment == SWT.FILL ? cellHeight
                : SWT.DEFAULT;

        // Note: this could be optimized further. If we're using a MAXIMUM hint and 
        // non-FILL alignment, we could simply call computeMaximumBoundedSize using the
        // minimum of the cell size and the hint as the boundary -- basically, rather
        // than applying two limits for the hint and the cell boundary, we can do it in
        // one step and reduce the size computations by half (for this specific case).
        Point controlSize = computeControlSize(toCompute, controlWidth,
                controlHeight);

        if (cellWidth != SWT.DEFAULT && controlSize.x > cellWidth) {
            controlSize = computeControlSize(toCompute, cellWidth,
                    controlHeight);
            if (cellHeight != SWT.DEFAULT && controlSize.y > cellHeight) {
                controlSize.y = cellHeight;
            }
        } else if (cellHeight != SWT.DEFAULT && controlSize.y > cellHeight) {
            controlSize = computeControlSize(toCompute, controlWidth,
                    cellHeight);
            if (cellWidth != SWT.DEFAULT && controlSize.x > cellWidth) {
                controlSize.x = cellWidth;
            }
        }

        // If we're going to indent, add the indentation to the required space 
        controlSize.x += absHorizontalIndent;
        controlSize.y += absVerticalIndent;

        return controlSize;
    }

    /**
     * Arranges the given control within the given rectangle using the
     * criteria described by this CellData.
     * 
     * @param control 
     * @param cellBounds
     * @since 3.0
     */
    public void positionControl(SizeCache cache, Rectangle cellBounds) {

        int startx = cellBounds.x;
        int starty = cellBounds.y;
        int availableWidth = cellBounds.width - horizontalIndent;
        int availableHeight = cellBounds.height - verticalIndent;

        Point size = computeSize(cache, availableWidth, availableHeight);

        // Horizontal justification
        switch (horizontalAlignment) {
        case SWT.RIGHT:
            startx = cellBounds.x + availableWidth - size.x;
            break;
        case SWT.CENTER:
            startx = cellBounds.x + (availableWidth - size.x) / 2;
            break;
        }

        // Vertical justification
        switch (verticalAlignment) {
        case SWT.BOTTOM:
            starty = cellBounds.y + availableHeight - size.y;
            break;
        case SWT.CENTER:
            starty = cellBounds.y + (availableHeight - size.y) / 2;
            break;
        }

        // Position the control
        cache.getControl().setBounds(startx + horizontalIndent,
                starty + verticalIndent, size.x, size.y);
    }

    /**
     * Returns the preferred size of the given control in this cell, given one or both
     * known dimensions of the control. This differs from computeSize, which takes known
     * dimensions of the <b>cell</b> as arguments.
     * 
     * @param toCompute
     * @param controlWidth
     * @param controlHeight
     * @return
     * @since 3.0
     */
    private Point computeControlSize(SizeCache toCompute, int controlWidth,
            int controlHeight) {
        switch (hintType) {
        case OVERRIDE:
            return computeOverrideSize(toCompute, controlWidth, controlHeight,
                    widthHint, heightHint);
        case MINIMUM:
            return computeMinimumBoundedSize(toCompute, controlWidth,
                    controlHeight, widthHint, heightHint);
        case MAXIMUM:
            return computeMaximumBoundedSize(toCompute, controlWidth,
                    controlHeight, widthHint, heightHint);
        }

        return computeRawSize(toCompute, controlWidth, controlHeight);
    }

    /** 
     * Computes the size of the control, given its outer dimensions. This should be used in
     * place of calling Control.computeSize, since Control.computeSize takes control-specific
     * inner dimensions as hints.
     *
     * @param toCompute Control whose size will be computed
     * @param controlWidth width of the control (pixels or SWT.DEFAULT if unknown)
     * @param controlHeight height of the control (pixels or SWT.DEFAULT if unknown)
     * @return preferred dimensions of the control
     */
    private static Point computeRawSize(SizeCache toCompute, int controlWidth,
            int controlHeight) {
        if (controlWidth != SWT.DEFAULT && controlHeight != SWT.DEFAULT) {
            return new Point(controlWidth, controlHeight);
        }

        // Known bug: we pass the OUTER dimension of the control into computeSize, even though
        // SWT expects a control-specific inner dimension as width and height hints. Currently,
        // SWT does not provide any means to convert outer dimensions into inner dimensions.
        // Fortunately, the outer and inner dimensions tend to be quite close so we
        // pass in the outer dimension and adjust the result if it differs from one of the
        // hints. This may cause incorrect text wrapping in rare cases, and should be fixed
        // once SWT provides a way to convert the outer dimension of a control into a valid
        // width or height hint for Control.computeSize. Note that the distinction between outer
        // and inner dimensions is undocumented in SWT, and most examples also contain this
        // bug.
        Point result = toCompute.computeSize(controlWidth, controlHeight);

        // Hack: If the result of computeSize differs from the width or height-hints, adjust it.
        // See above. Don't remove this hack until SWT provides some way to pass correct width
        // and height hints into computeSize. Once this happens, these conditions should always
        // return false and the hack will have no effect.
        if (controlWidth != SWT.DEFAULT) {
            result.x = controlWidth;
        } else if (controlHeight != SWT.DEFAULT) {
            result.y = controlHeight;
        }

        return result;
    }

    /**
     * Computes the preferred size of the control. Optionally, one or both dimensions
     * may be fixed to a given size.
     * 
     * @param control object that can compute the size of the control of interest
     * @param wHint known width (or SWT.DEFAULT if the width needs to be computed) 
     * @param hHint known height (or SWT.DEFAULT if the height needs to be computed) 
     * @param overrideW width that should always be returned by the control, 
     * or SWT.DEFAULT if the width is not being constrained
     * @param overrideH height that should always be returned by the control, 
     * or SWT.DEFAULT if the height is not being constrained
     * @return
     */
    private static Point computeOverrideSize(SizeCache control, int wHint,
            int hHint, int overrideW, int overrideH) {
        int resultWidth = overrideW;
        int resultHeight = overrideH;

        if (wHint != SWT.DEFAULT) {
            resultWidth = wHint;
        }

        if (hHint != SWT.DEFAULT) {
            resultHeight = hHint;
        }

        if (resultWidth == SWT.DEFAULT || resultHeight == SWT.DEFAULT) {
            Point result = computeRawSize(control, resultWidth, resultHeight);

            return result;
        }

        return new Point(resultWidth, resultHeight);
    }

    /**
     * Computes the size for the control, optionally bounding the size in the x and
     * y directions. The various hints are used to determine which dimensions are
     * already known and which dimensions need to be computed.
     * 
     * @param control The control whose size should be computed
     * @param wHint known width (or SWT.DEFAULT if the width needs to be computed) 
     * @param hHint known height (or SWT.DEFAULT if the height needs to be computed) 
     * @param boundedWidth maximum width for the control (or SWT.DEFAULT if the width is unbounded)
     * @param boundedHeight maximum height for the control (or SWT.DEFAULT if the height is unbounded)
     * @return the preferred size of the control, given that it cannot exceed the given bounds 
     */
    private static Point computeMaximumBoundedSize(SizeCache control,
            int wHint, int hHint, int boundedWidth, int boundedHeight) {
        Point controlSize = computeRawSize(control, wHint, hHint);

        if (wHint == SWT.DEFAULT && boundedWidth != SWT.DEFAULT
                && controlSize.x > boundedWidth) {
            return computeMaximumBoundedSize(control, boundedWidth, hHint,
                    boundedWidth, boundedHeight);
        }

        if (hHint == SWT.DEFAULT && boundedHeight != SWT.DEFAULT
                && controlSize.y > boundedHeight) {
            return computeMaximumBoundedSize(control, wHint, boundedHeight,
                    boundedWidth, boundedHeight);
        }

        return controlSize;
    }

    private static Point computeMinimumBoundedSize(SizeCache control,
            int wHint, int hHint, int minimumWidth, int minimumHeight) {

        Point controlSize = computeRawSize(control, wHint, hHint);

        if (minimumWidth != SWT.DEFAULT && wHint == SWT.DEFAULT
                && controlSize.x < minimumWidth) {
            return computeMinimumBoundedSize(control, minimumWidth, hHint,
                    minimumWidth, minimumHeight);
        }

        if (minimumHeight != SWT.DEFAULT && hHint == SWT.DEFAULT
                && controlSize.y < minimumHeight) {
            return computeMinimumBoundedSize(control, wHint, minimumHeight,
                    minimumWidth, minimumHeight);
        }

        return controlSize;
    }

}
