/*******************************************************************************
 * Copyright (c) 2000, 2006 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);
    }

    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;
    }
}
