/*******************************************************************************
 * Copyright (c) 2000, 2008 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.presentations.r21.widgets;

import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.SWTException;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Widget;

/**
 */
public class CTabItem extends Item {
    CTabFolder parent;

    int x, y, width, height = 0;

    String toolTipText;

    Control control; // the tab page

    private Image disabledImage;

    // internal constants
    static final int LEFT_MARGIN = 4;

    static final int RIGHT_MARGIN = 4;

    static final int TOP_MARGIN = 3;

    static final int BOTTOM_MARGIN = 3;

    private static final int INTERNAL_SPACING = 2;

    private static final String ellipsis = "..."; //$NON-NLS-1$

    String shortenedText;

    int shortenedTextWidth;

    /**
     * Constructs a new instance of this class given its parent
     * (which must be a <code>CTabFolder</code>) and a style value
     * describing its behavior and appearance. The item is added
     * to the end of the items maintained by its parent.
     * <p>
     * The style value is either one of the style constants defined in
     * class <code>SWT</code> which is applicable to instances of this
     * class, or must be built by <em>bitwise OR</em>'ing together 
     * (that is, using the <code>int</code> "|" operator) two or more
     * of those <code>SWT</code> style constants. The class description
     * lists the style constants that are applicable to the class.
     * Style bits are also inherited from superclasses.
     * </p>
     *
     * @param parent a CTabFolder which will be the parent of the new instance (cannot be null)
     * @param style the style of control to construct
     *
     * @exception IllegalArgumentException <ul>
     *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
     * </ul>
     * @exception SWTException <ul>
     *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
     * </ul>
     *
     * @see SWT
     * @see Widget#getStyle
     */
    public CTabItem(CTabFolder parent, int style) {
        this(parent, style, parent.getItemCount());
    }

    /**
     * Constructs a new instance of this class given its parent
     * (which must be a <code>CTabFolder</code>), a style value
     * describing its behavior and appearance, and the index
     * at which to place it in the items maintained by its parent.
     * <p>
     * The style value is either one of the style constants defined in
     * class <code>SWT</code> which is applicable to instances of this
     * class, or must be built by <em>bitwise OR</em>'ing together 
     * (that is, using the <code>int</code> "|" operator) two or more
     * of those <code>SWT</code> style constants. The class description
     * lists the style constants that are applicable to the class.
     * Style bits are also inherited from superclasses.
     * </p>
     *
     * @param parent a CTabFolder which will be the parent of the new instance (cannot be null)
     * @param style the style of control to construct
     * @param index the index to store the receiver in its parent
     *
     * @exception IllegalArgumentException <ul>
     *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
     * </ul>
     * @exception SWTException <ul>
     *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
     * </ul>
     *
     * @see SWT
     * @see Widget#getStyle
     */
    public CTabItem(CTabFolder parent, int style, int index) {
        super(parent, checkStyle(style));
        parent.createItem(this, index);
    }

    /**
	 * @param style  
	 */
    private static int checkStyle(int style) {
        return SWT.NONE;
    }

    public void dispose() {
        if (isDisposed()) {
			return;
		}
        parent.destroyItem(this);
        super.dispose();
        parent = null;
        control = null;
        toolTipText = null;
    }

    /**
     * Returns a rectangle describing the receiver's size and location
     * relative to its parent.
     *
     * @return the receiver's bounding column rectangle
     *
     * @exception SWTException <ul>
     *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
     *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
     * </ul>
     */
    public Rectangle getBounds() {
        //checkWidget();
        return new Rectangle(x, y, width, height);
    }

    /**
     * Gets the control that is displayed in the content are of the tab item.
     *
     * @return the control
     *
     * @exception SWTError(ERROR_THREAD_INVALID_ACCESS)
     *	when called from the wrong thread
     * @exception SWTError(ERROR_WIDGET_DISPOSED)
     *	when the widget has been disposed
     */
    public Control getControl() {
        checkWidget();
        return control;
    }

    public Display getDisplay() {
        if (parent == null) {
			SWT.error(SWT.ERROR_WIDGET_DISPOSED);
		}
        return parent.getDisplay();
    }

    /**
     * Get the image displayed in the tab if the tab is disabled.
     * 
     * @return the disabled image or null
     */
    public Image getDisabledImage() {
        //checkWidget();
        return disabledImage;
    }

    /**
     * Returns the receiver's parent, which must be a <code>CTabFolder</code>.
     *
     * @return the receiver's parent
     */
    public CTabFolder getParent() {
        //checkWidget();
        return parent;
    }

    /**
     * Returns the receiver's tool tip text, or null if it has
     * not been set.
     *
     * @return the receiver's tool tip text
     *
     * @exception SWTException <ul>
     *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
     *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
     * </ul>
     */
    public String getToolTipText() {
        checkWidget();
        return toolTipText;
    }

    /**
     * Paint the receiver.
     */
    void onPaint(GC gc, boolean isSelected) {

        if (width == 0 || height == 0) {
			return;
		}

        Display display = getDisplay();
        Color highlightShadow = display
                .getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW);
        Color normalShadow = display
                .getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW);

        int index = parent.indexOf(this);

        if (isSelected) {

            Rectangle bounds = null;
            if (!parent.onBottom) {
                if (index == parent.topTabIndex) {
                    bounds = new Rectangle(x + 1, y + 1, width - 2, height - 1);
                } else {
                    bounds = new Rectangle(x + 2, y + 1, width - 3, height - 1);
                }
            } else {
                if (index == parent.topTabIndex) {
                    bounds = new Rectangle(x + 1, y + 1, width - 2, height - 2);
                } else {
                    bounds = new Rectangle(x + 2, y + 1, width - 3, height - 2);
                }
            }
            if (parent.backgroundImage != null) {
                // draw a background image behind the text
                Rectangle imageRect = parent.backgroundImage.getBounds();
                gc.drawImage(parent.backgroundImage, 0, 0, imageRect.width,
                        imageRect.height, bounds.x, bounds.y, bounds.width,
                        bounds.height);
            } else if (parent.gradientColors != null) {
                // draw a gradient behind the text
                Color oldBackground = gc.getBackground();
                if (parent.gradientColors.length == 1) {
                    if (parent.gradientColors[0] != null) {
						gc.setBackground(parent.gradientColors[0]);
					}
                    gc.fillRectangle(bounds.x, bounds.y, bounds.width,
                            bounds.height);
                } else {
                    Color oldForeground = gc.getForeground();
                    Color lastColor = parent.gradientColors[0];
                    if (lastColor == null) {
						lastColor = oldBackground;
					}
                    for (int i = 0, pos = 0; i < parent.gradientPercents.length; ++i) {
                        gc.setForeground(lastColor);
                        lastColor = parent.gradientColors[i + 1];
                        if (lastColor == null) {
							lastColor = oldBackground;
						}
                        gc.setBackground(lastColor);
                        int gradientWidth = (parent.gradientPercents[i]
                                * bounds.width / 100)
                                - pos;
                        gc.fillGradientRectangle(bounds.x + pos, bounds.y,
                                gradientWidth, bounds.height, false);
                        pos += gradientWidth;
                    }
                    gc.setForeground(oldForeground);
                }
                gc.setBackground(oldBackground);
            }

            // draw tab lines
            if (!parent.onBottom) {
                gc.setForeground(normalShadow);
                if (index != parent.topTabIndex) {
                    gc.drawLine(x + 1, y, x + 1, y);
                    gc.drawLine(x, y + 1, x, y + height - 2);
                    gc.drawLine(x, y + height - 1, x, y + height - 1);
                }
                gc.drawLine(x + width - 1, y, x + width - 1, y);
                gc.drawLine(x + width, y + 1, x + width, y + height - 2);
                gc.drawLine(x + width, y + height - 1, x + width, y + height
                        - 1);

                gc.setForeground(highlightShadow);
                if (index != parent.topTabIndex) {
                    gc.drawLine(x + 2, y, x + 2, y);
                    gc.drawLine(x + 1, y + 1, x + 1, y + height - 2);
                    gc.drawLine(x + 1, y + height - 1, x + 1, y + height - 1);
                } else {
                    gc.drawLine(x, y, x, y + height - 1);
                }

                gc.drawLine(x + width - 2, y, x + width - 2, y);
                gc
                        .drawLine(x + width - 1, y + 1, x + width - 1, y
                                + height - 2);
                gc.drawLine(x + width - 1, y + height - 1, x + width - 1, y
                        + height - 1);

                // light line across top
                if (index != parent.topTabIndex) {
                    gc.drawLine(x + 3, y, x + width - 3, y);
                } else {
                    gc.drawLine(x + 1, y, x + width - 3, y);
                }
            } else {
                gc.setForeground(normalShadow);
                if (index != parent.topTabIndex) {
                    gc.drawLine(x, y, x, y);
                    gc.drawLine(x, y + 1, x, y + height - 2);
                    gc.drawLine(x + 1, y + height - 1, x + 1, y + height - 1);
                }
                gc.drawLine(x + width, y, x + width, y);
                gc.drawLine(x + width, y + 1, x + width, y + height - 2);
                gc.drawLine(x + width - 1, y + height - 1, x + width - 1, y
                        + height - 1);

                gc.setForeground(highlightShadow);
                if (index != parent.topTabIndex) {
                    gc.drawLine(x + 1, y, x + 1, y);
                    gc.drawLine(x + 1, y + 1, x + 1, y + height - 2);
                    gc.drawLine(x + 2, y + height - 1, x + 2, y + height - 1);
                } else {
                    gc.drawLine(x, y, x, y + height - 1);
                }

                gc.drawLine(x + width - 1, y, x + width - 1, y);
                gc
                        .drawLine(x + width - 1, y + 1, x + width - 1, y
                                + height - 2);
                gc.drawLine(x + width - 2, y + height - 1, x + width - 2, y
                        + height - 1);

                // light line across top and bottom
                if (index != parent.topTabIndex) {
                    gc.drawLine(x + 1, y, x + width - 2, y);
                    gc.drawLine(x + 2, y + height - 1, x + width - 3, y
                            + height - 1);
                } else {
                    gc.drawLine(x + 1, y, x + width - 2, y);
                    gc.drawLine(x + 1, y + height - 1, x + width - 3, y
                            + height - 1);
                }
            }
            if (parent.isFocusControl()) {
                // draw a focus rectangle
                int x1, y1, width1, height1;
                if (!parent.onBottom) {
                    if (index == parent.topTabIndex) {
                        x1 = x + 1;
                        y1 = y + 1;
                        width1 = width - 2;
                        height1 = height - 1;
                    } else {
                        x1 = x + 2;
                        y1 = y + 1;
                        width1 = width - 3;
                        height1 = height - 1;
                    }
                } else {
                    if (index == parent.topTabIndex) {
                        x1 = x + 1;
                        y1 = y + 1;
                        width1 = width - 2;
                        height1 = height - 2;
                    } else {
                        x1 = x + 2;
                        y1 = y + 1;
                        width1 = width - 3;
                        height1 = height - 2;
                    }
                }
                gc.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
                gc.setForeground(display.getSystemColor(SWT.COLOR_WHITE));
                gc.drawFocus(x1, y1, width1, height1);
            }
        } else {
            // draw tab lines for unselected items
            gc.setForeground(normalShadow);
            if (!parent.onBottom) {
                if (index != parent.topTabIndex
                        && index != parent.getSelectionIndex() + 1) {
                    gc.drawLine(x, y, x, y + (height / 2));
                }
            } else {
                if (index != parent.topTabIndex
                        && index != parent.getSelectionIndex() + 1) {
                    gc.drawLine(x, y + (height / 2), x, y + height - 1);
                }
            }

        }

        // draw Image
        int xDraw = x + LEFT_MARGIN;

        Image image = getImage();
        if (!isSelected && image != null) {
            Image temp = getDisabledImage();
            if (temp != null) {
                image = temp;
            }
        }
        if (image != null) {
            Rectangle imageBounds = image.getBounds();
            int imageX = xDraw;
            int imageHeight = Math.min(height - BOTTOM_MARGIN - TOP_MARGIN,
                    imageBounds.height);
            int imageY = y + (height - imageHeight) / 2;
            int imageWidth = imageBounds.width * imageHeight
                    / imageBounds.height;
            gc.drawImage(image, imageBounds.x, imageBounds.y,
                    imageBounds.width, imageBounds.height, imageX, imageY,
                    imageWidth, imageHeight);
            xDraw += imageWidth + INTERNAL_SPACING;
        }

        // draw Text
        int textWidth = x + width - xDraw - RIGHT_MARGIN;
        if (isSelected && parent.showClose) {
            textWidth = x + width - xDraw - parent.closeBar.getSize().x
                    - RIGHT_MARGIN;
        }
        if (shortenedText == null || shortenedTextWidth != textWidth) {
            shortenedText = shortenText(gc, getText(), textWidth);
            shortenedTextWidth = textWidth;
        }
        String text = shortenedText;

        if (isSelected && parent.selectionForeground != null) {
            gc.setForeground(parent.selectionForeground);
        } else {
            gc.setForeground(parent.getForeground());
        }
        int textY = y + (height - gc.textExtent(text, SWT.DRAW_MNEMONIC).y) / 2;
        gc.drawText(text, xDraw, textY, SWT.DRAW_TRANSPARENT
                | SWT.DRAW_MNEMONIC);

        gc.setForeground(parent.getForeground());
    }

    private static String shortenText(GC gc, String text, int width) {
        if (gc.textExtent(text, SWT.DRAW_MNEMONIC).x <= width) {
			return text;
		}

        int ellipseWidth = gc.textExtent(ellipsis, SWT.DRAW_MNEMONIC).x;
        int length = text.length();
        int end = length - 1;
        while (end > 0) {
            text = text.substring(0, end);
            int l1 = gc.textExtent(text, SWT.DRAW_MNEMONIC).x;
            if (l1 + ellipseWidth <= width) {
                return text + ellipsis;
            }
            end--;
        }
        return text + ellipsis;
    }

    /**
     * Answer the preferred height of the receiver for the GC.
     */
    int preferredHeight(GC gc) {
        Image image = getImage();
        int height = 0;
        if (image != null) {
			height = image.getBounds().height;
		}
        String text = getText();
        height = Math.max(height, gc.textExtent(text, SWT.DRAW_MNEMONIC).y);
        return height + TOP_MARGIN + BOTTOM_MARGIN;
    }

    /**
     * Answer the preferred width of the receiver for the GC.
     */
    int preferredWidth(GC gc) {
        int width = 0;
        Image image = getImage();
        if (image != null) {
			width += image.getBounds().width;
		}
        String text = getText();
        if (text != null) {
            if (image != null) {
				width += INTERNAL_SPACING;
			}
            width += gc.textExtent(text, SWT.DRAW_MNEMONIC).x;
        }
        if (parent.showClose) {
			width += INTERNAL_SPACING + preferredHeight(gc); // closebar will be square and will fill preferred height
		}
        return width + LEFT_MARGIN + RIGHT_MARGIN;
    }

    /**
     * Sets the control that is used to fill the client area of
     * the tab folder when the user selects the tab item.
     * <p>
     * @param control the new control (or null)
     *
     * @exception IllegalArgumentException <ul>
     *    <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li> 
     *    <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree</li>
     * </ul>
     * @exception SWTException <ul>
     *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
     *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
     * </ul>
     */
    public void setControl(Control control) {
        checkWidget();
        if (control != null) {
            if (control.isDisposed()) {
				SWT.error(SWT.ERROR_INVALID_ARGUMENT);
			}
            if (control.getParent() != parent) {
				SWT.error(SWT.ERROR_INVALID_PARENT);
			}
        }
        if (this.control != null && !this.control.isDisposed()) {
            this.control.setVisible(false);
        }
        this.control = control;
        if (this.control != null) {
            int index = parent.indexOf(this);
            if (index == parent.getSelectionIndex()) {
                this.control.setBounds(parent.getClientArea());
                this.control.setVisible(true);
            } else {
                this.control.setVisible(false);
            }
        }
    }

    public void setImage(Image image) {
        checkWidget();
        if (image != null && image.equals(getImage())) {
			return;
		}
        super.setImage(image);
        parent.resetTabSize(true);
    }

    /**
     * Sets the image that is displayed if the tab item is disabled.
     * Null will clear the image.
     * 
     * @param image the image to be displayed when the item is disabled or null
     *
     * @exception SWTException <ul>
     *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
     *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
     * </ul>
     */
    public void setDisabledImage(Image image) {
        checkWidget();
        if (image != null && image.equals(getDisabledImage())) {
			return;
		}
        disabledImage = image;
        parent.redraw();
    }

    /**
     * Set the widget text.
     * <p>
     * This method sets the widget label.  The label may include
     * mnemonic characters but must not contain line delimiters.
     *
     * @param string the new label for the widget
     *
     * @exception IllegalArgumentException <ul>
     *    <li>ERROR_NULL_ARGUMENT - if the text is null</li>
     * </ul>
     * @exception SWTException <ul>
     *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
     *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
     * </ul>
     */
    public void setText(String string) {
        checkWidget();
        if (string.equals(getText())) {
			return;
		}
        super.setText(string);
        shortenedText = null;
        shortenedTextWidth = 0;
        parent.resetTabSize(false);
    }

    /**
     * Sets the receiver's tool tip text to the argument, which
     * may be null indicating that no tool tip text should be shown.
     *
     * @param string the new tool tip text (or null)
     *
     * @exception SWTException <ul>
     *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
     *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
     * </ul>
     */
    public void setToolTipText(String string) {
        checkWidget();
        toolTipText = string;
    }
}
