/*******************************************************************************
 * Copyright (c) 2008, 2011 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
 *     Fabio Zadrozny - Bug 465666
 *******************************************************************************/
package org.eclipse.jdt.internal.ui.javaeditor.breadcrumb;

import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.AccessibleAdapter;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MenuDetectEvent;
import org.eclipse.swt.events.MenuDetectListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.TraverseEvent;
import org.eclipse.swt.events.TraverseListener;
import org.eclipse.swt.graphics.Image;
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.Label;
import org.eclipse.swt.widgets.Shell;


/**
 * The label and icon part of the breadcrumb item.
 *
 * @since 3.4
 */
class BreadcrumbItemDetails {

	private final Label fElementImage;
	private final Label fElementText;
	private final Composite fDetailComposite;
	private final BreadcrumbItem fParent;
	private final Composite fTextComposite;
	private final Composite fImageComposite;

	private boolean fTextVisible;
	private boolean fSelected;
	private boolean fHasFocus;


	public BreadcrumbItemDetails(BreadcrumbItem parent, Composite parentContainer) {
		fParent= parent;
		fTextVisible= true;

		fDetailComposite= new Composite(parentContainer, SWT.NONE);
		fDetailComposite.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
		GridLayout layout= new GridLayout(2, false);
		layout.marginHeight= 0;
		layout.marginWidth= 0;
		layout.horizontalSpacing= 0;
		fDetailComposite.setLayout(layout);
		addElementListener(fDetailComposite);

		fImageComposite= new Composite(fDetailComposite, SWT.NONE);
		fImageComposite.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
		layout= new GridLayout(1, false);
		layout.marginHeight= 1;
		layout.marginWidth= 2;
		fImageComposite.setLayout(layout);
		fImageComposite.addPaintListener(new PaintListener() {
			@Override
			public void paintControl(PaintEvent e) {
				if (fHasFocus && !isTextVisible()) {
					e.gc.drawFocus(e.x, e.y, e.width, e.height);
				}
			}
		});
		installFocusComposite(fImageComposite);
		addElementListener(fImageComposite);

		fElementImage= new Label(fImageComposite, SWT.NONE);
		GridData layoutData= new GridData(SWT.BEGINNING, SWT.CENTER, false, false);
		fElementImage.setLayoutData(layoutData);
		addElementListener(fElementImage);

		fTextComposite= new Composite(fDetailComposite, SWT.NONE);
		fTextComposite.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
		layout= new GridLayout(1, false);
		layout.marginHeight= 2;
		layout.marginWidth= 2;
		fTextComposite.setLayout(layout);
		addElementListener(fTextComposite);
		fTextComposite.addPaintListener(new PaintListener() {
			@Override
			public void paintControl(PaintEvent e) {
				if (fHasFocus && isTextVisible()) {
					e.gc.drawFocus(e.x, e.y, e.width, e.height);
				}
			}
		});
		installFocusComposite(fTextComposite);

		fElementText= new Label(fTextComposite, SWT.NONE);
		layoutData= new GridData(SWT.BEGINNING, SWT.CENTER, false, false);
		fElementText.setLayoutData(layoutData);
		addElementListener(fElementText);

		fTextComposite.getAccessible().addAccessibleListener(new AccessibleAdapter() {
			@Override
			public void getName(AccessibleEvent e) {
				e.result= fElementText.getText();
			}
		});
		fImageComposite.getAccessible().addAccessibleListener(new AccessibleAdapter() {
			@Override
			public void getName(AccessibleEvent e) {
				e.result= fElementText.getText();
			}
		});

		fDetailComposite.setTabList(new Control[] { fTextComposite });

		fDetailComposite.setData("org.eclipse.e4.ui.css.id", "BreadcrumbItemDetailComposite"); //$NON-NLS-1$ //$NON-NLS-2$
		fTextComposite.setData("org.eclipse.e4.ui.css.id", "BreadcrumbItemDetailTextComposite"); //$NON-NLS-1$ //$NON-NLS-2$
		fImageComposite.setData("org.eclipse.e4.ui.css.id", "BreadcrumbItemDetailImageComposite"); //$NON-NLS-1$ //$NON-NLS-2$
		fElementImage.setData("org.eclipse.e4.ui.css.id", "BreadcrumbItemDetailImageLabel"); //$NON-NLS-1$ //$NON-NLS-2$
		fElementText.setData("org.eclipse.e4.ui.css.id", "BreadcrumbItemDetailTextLabel"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/**
	 * Returns whether this element has the keyboard focus.
	 *
	 * @return true if this element has the keyboard focus.
	 */
	public boolean hasFocus() {
		return fHasFocus;
	}

	/**
	 * Sets the tool tip to the given text.
	 *
	 * @param text the tool tip
	 */
	public void setToolTip(String text) {
		if (isTextVisible()) {
			fElementText.getParent().setToolTipText(text);
			fElementText.setToolTipText(text);

			fElementImage.setToolTipText(text);
		} else {
			fElementText.getParent().setToolTipText(null);
			fElementText.setToolTipText(null);

			fElementImage.setToolTipText(text);
		}
	}

	/**
	 * Sets the image to the given image.
	 *
	 * @param image the image to use
	 */
	public void setImage(Image image) {
		if (image != fElementImage.getImage()) {
			fElementImage.setImage(image);
		}
	}

	/**
	 * Sets the text to the given text.
	 *
	 * @param text the text to use
	 */
	public void setText(String text) {
		if (text == null) {
			text= ""; //$NON-NLS-1$
		}
		if (!text.equals(fElementText.getText())) {
			fElementText.setText(text);
		}
	}

	/**
	 * Returns the width of this element.
	 *
	 * @return current width of this element
	 */
	public int getWidth() {
		int result= 2;

		if (fElementImage.getImage() != null)
			result+= fElementImage.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;

		if (fTextVisible && fElementText.getText().length() > 0)
			result+= fElementText.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;

		return result;
	}

	public void setTextVisible(boolean enabled) {
		if (fTextVisible == enabled)
			return;

		fTextVisible= enabled;

		GridData data= (GridData) fTextComposite.getLayoutData();
		data.exclude= !enabled;
		fTextComposite.setVisible(enabled);

		if (fTextVisible) {
			fDetailComposite.setTabList(new Control[] { fTextComposite });
		} else {
			fDetailComposite.setTabList(new Control[] { fImageComposite });
		}

		if (fHasFocus) {
			if (isTextVisible()) {
				fTextComposite.setFocus();
			} else {
				fImageComposite.setFocus();
			}
		}
	}

	/**
	 * Tells whether this item shows a text or only an image.
	 *
	 * @return <code>true</code> if it shows a text and an image, false if it only shows the image
	 */
	public boolean isTextVisible() {
		return fTextVisible;
	}

	/**
	 * Sets whether details should be shown.
	 *
	 * @param visible <code>true</code> if details should be shown
	 */
	public void setVisible(boolean visible) {
		fDetailComposite.setVisible(visible);

		GridData data= (GridData) fDetailComposite.getLayoutData();
		data.exclude= !visible;
	}

	public void setSelected(boolean selected) {
		if (selected == fSelected)
			return;

		fSelected= selected;
		if (!fSelected)
			fHasFocus= false;

	}

	public void setFocus(boolean enabled) {
		if (enabled == fHasFocus)
			return;

		fHasFocus= enabled;
		if (fHasFocus) {
			if (isTextVisible()) {
				fTextComposite.setFocus();
			} else {
				fImageComposite.setFocus();
			}
		}
	}

	/**
	 * Install focus and key listeners to the given composite.
	 *
	 * @param composite the composite which may get focus
	 */
	private void installFocusComposite(Composite composite) {
		composite.addTraverseListener(new TraverseListener() {
			@Override
			public void keyTraversed(TraverseEvent e) {
				if (e.detail == SWT.TRAVERSE_TAB_NEXT || e.detail == SWT.TRAVERSE_TAB_PREVIOUS) {
					int index= fParent.getViewer().getIndexOfItem(fParent);
					if (e.detail == SWT.TRAVERSE_TAB_NEXT) {
						index++;
					} else {
						index--;
					}

					if (index > 0 && index < fParent.getViewer().getItemCount()) {
						fParent.getViewer().selectItem(fParent.getViewer().getItem(index));
					}

					e.doit= true;
				}
			}
		});
		composite.addKeyListener(new KeyListener() {
			@Override
			public void keyPressed(KeyEvent e) {
				BreadcrumbViewer viewer= fParent.getViewer();

				switch (e.keyCode) {
					case SWT.ARROW_LEFT:
						if (fSelected) {
							viewer.doTraverse(false);
							e.doit= false;
						} else {
							viewer.selectItem(fParent);
						}
						break;
					case SWT.ARROW_RIGHT:
						if (fSelected) {
							viewer.doTraverse(true);
							e.doit= false;
						} else {
							viewer.selectItem(fParent);
						}
						break;
					case SWT.ARROW_DOWN:
						if (!fSelected) {
							viewer.selectItem(fParent);
						}
						openDropDown();
						e.doit= false;
						break;
					case SWT.KEYPAD_ADD:
						if (!fSelected) {
							viewer.selectItem(fParent);
						}
						openDropDown();
						e.doit= false;
						break;
					case SWT.CR:
						if (!fSelected) {
							viewer.selectItem(fParent);
						}
						viewer.fireOpen();
						break;
					default:
						if (e.character == ' ') {
							if (!fSelected) {
								viewer.selectItem(fParent);
							}
							openDropDown();
							e.doit= false;
						}
						break;
				}
			}

			private void openDropDown() {
				BreadcrumbViewer viewer= fParent.getViewer();

				int index= viewer.getIndexOfItem(fParent);
				BreadcrumbItem parent= fParent.getViewer().getItem(index - 1);

				Shell shell= parent.getDropDownShell();
				if (shell == null) {
					parent.openDropDownMenu();
					shell= parent.getDropDownShell();
				}
				shell.setFocus();
			}

			@Override
			public void keyReleased(KeyEvent e) {
			}
		});

		composite.addFocusListener(new FocusListener() {
			@Override
			public void focusGained(FocusEvent e) {
				if (!fHasFocus) {
					fHasFocus= true;
				}
			}

			@Override
			public void focusLost(FocusEvent e) {
				if (fHasFocus) {
					fHasFocus= false;
				}
			}
		});
	}

	/**
	 * Add mouse listeners to the given control.
	 *
	 * @param control the control to which may be clicked
	 */
	private void addElementListener(Control control) {
		control.addMouseListener(new MouseListener() {
			@Override
			public void mouseDoubleClick(MouseEvent e) {
			}

			@Override
			public void mouseDown(MouseEvent e) {
				BreadcrumbViewer viewer= fParent.getViewer();

				int parentIndex= viewer.getIndexOfItem(fParent) - 1;
				Shell shell= null;
				if (parentIndex >= 0) {//sanity check, must always hold
					BreadcrumbItem dropDownItem= viewer.getItem(parentIndex);
					shell= dropDownItem.getDropDownShell();
				}

				viewer.selectItem(fParent);
				if (shell == null && e.button == 1 && e.stateMask == 0) {
					fParent.getViewer().fireDoubleClick();
				}
			}

			@Override
			public void mouseUp(MouseEvent e) {
			}
		});
		control.addMenuDetectListener(new MenuDetectListener() {
			@Override
			public void menuDetected(MenuDetectEvent e) {
				BreadcrumbViewer viewer= fParent.getViewer();
				viewer.selectItem(fParent);
				fParent.getViewer().fireMenuDetect(e);
			}
		});
	}
}
