/*******************************************************************************
 * Copyright (c) 2008, 2009 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Pawel Piech (Wind River) - adapted breadcrumb for use in Debug view (Bug 252677)
 *******************************************************************************/
package org.eclipse.debug.internal.ui.viewers.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.5
 */
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);
		addElementListener(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", "DebugBreadcrumbItemDetailComposite"); //$NON-NLS-1$ //$NON-NLS-2$
		fTextComposite.setData("org.eclipse.e4.ui.css.id", "DebugBreadcrumbItemDetailTextComposite"); //$NON-NLS-1$ //$NON-NLS-2$
		fImageComposite.setData("org.eclipse.e4.ui.css.id", "DebugBreadcrumbItemDetailImageComposite"); //$NON-NLS-1$ //$NON-NLS-2$
		fElementImage.setData("org.eclipse.e4.ui.css.id", "DebugBreadcrumbItemDetailImageLabel"); //$NON-NLS-1$ //$NON-NLS-2$
		fElementText.setData("org.eclipse.e4.ui.css.id", "DebugBreadcrumbItemDetailTextLabel"); //$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;
	}

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

		fSelected= selected;

	}

	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:
					case SWT.ARROW_UP:
					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() {
				Shell shell = fParent.getDropDownShell();
				if (shell == null) {
					fParent.openDropDownMenu();
					shell = fParent.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();
				Shell shell= fParent.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);
			}
		});
	}
}
