/*******************************************************************************
 * Copyright (c) 2018 Remain Software
 * 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:
 *     wim.jongman@remainsoftware.com - initial API and implementation
 *******************************************************************************/
package org.eclipse.tips.ui.internal;

import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.tips.core.TipImage;
import org.eclipse.tips.core.TipProvider;
import org.eclipse.tips.core.internal.LogUtil;
import org.eclipse.tips.core.internal.TipManager;
import org.eclipse.tips.ui.internal.util.ImageUtil;
import org.eclipse.tips.ui.internal.util.ResourceManager;
import org.eclipse.tips.ui.internal.util.SWTResourceManager;

@SuppressWarnings("restriction")
public class Slider extends Composite {

	private static final int RESIZE_RELOAD_DELAY = 100;
	private Composite fScroller;
	private TipProvider fSelectedProvider;
	private int fSpacing = 5;
	private int fSliderIndex = 0;
	private List<ProviderSelectionListener> fListeners = new ArrayList<>();
	private TipManager fTipManager;
	private Button fLeftButton;
	private Button fRightButton;
	private Composite fSelectedProviderButton;
	private HashMap<String, Image> fProviderImageCache = new HashMap<>();
	private int fIconSize = 48;
	private PropertyChangeListener fPropertyChangeListener;
	private int fLeftRightButtonWidth;
	private long fLastResizeEventTime;
	private boolean fResizeRequestPending;

	/**
	 * Constructor for the Slider widget.
	 *
	 * @param parent the parent
	 * @param style  the SWT style bits
	 */
	public Slider(Composite parent, int style) {
		super(parent, style);

		GridLayout layout = new GridLayout(3, false);
		layout.marginHeight = 0;
		setLayout(layout);

		fLeftButton = new Button(this, SWT.FLAT);
		fLeftRightButtonWidth = fIconSize / 2 + 8;
		setLeftRightButtonGridData(fLeftButton, fLeftRightButtonWidth);
		fLeftButton.setImage(getImage("icons/" + fIconSize + "/aleft.png")); //$NON-NLS-1$ //$NON-NLS-2$
		fLeftButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				scrollLeft();
			}
		});

		fScroller = new Composite(this, SWT.DOUBLE_BUFFERED);
		GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
		layoutData.heightHint = fIconSize + 4;
		fScroller.setLayoutData(layoutData);

		fRightButton = new Button(this, SWT.FLAT);
		setLeftRightButtonGridData(fRightButton, fLeftRightButtonWidth);
		fRightButton.setImage(getImage("icons/" + fIconSize + "/aright.png")); //$NON-NLS-1$ //$NON-NLS-2$
		fRightButton.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				scrollRight();
			}
		});

		setupDisposeListener();
		setupProviderListener();
		setupResizeListener();
	}

	// Recalculation of slider is expensive. Make sure it is done only once when
	// resizing.
	private void setupResizeListener() {
		addListener(SWT.Resize, event -> {
			fLastResizeEventTime = System.currentTimeMillis();
			if (!fResizeRequestPending) {
				fResizeRequestPending = true;
				submitResizeExecution();
			}
		});
	}

	private void submitResizeExecution() {
		getDisplay().timerExec(RESIZE_RELOAD_DELAY / 2, () -> {
			long currentTime = System.currentTimeMillis();
			if (currentTime - fLastResizeEventTime > RESIZE_RELOAD_DELAY) {
				load();
				fResizeRequestPending = false;
			}
			if (fResizeRequestPending) {
				submitResizeExecution();
			}
		});
	}

	private void setLeftRightButtonGridData(Button pButton, int pWidth) {
		GridData gridData = new GridData(SWT.FILL, SWT.FILL, false, false, 1, 1);
		gridData.widthHint = pWidth;
		gridData.heightHint = fIconSize;
		pButton.setLayoutData(gridData);
	}

	private void setupDisposeListener() {
		addListener(SWT.Dispose, event -> {
			fTipManager.getChangeSupport().removePropertyChangeListener(fPropertyChangeListener);
			fProviderImageCache.values().forEach(img -> {
				if (!img.isDisposed()) {
					img.dispose();
				}
			});
		});
	}

	private void setupProviderListener() {
		fPropertyChangeListener = provider -> {
			if (!isDisposed())
				getDisplay().asyncExec(() -> load());
		};
	}

	private static Image getImage(String icon) {
		return ResourceManager.getPluginImage("org.eclipse.tips.ui", icon); //$NON-NLS-1$
	}

	/**
	 * Loads or reloads the provider list. If you want to update the read count of
	 * the current button or all buttons then check the {@link #updateButton()} and
	 * {@link #updateButtons()} methods.
	 *
	 */
	public void load() {
		if (isDisposed() || fScroller.isDisposed() || fTipManager == null) {
			return;
		}
		Arrays.stream(fScroller.getChildren()).filter(control -> !control.isDisposed())
				.forEach(control -> control.dispose());
		List<TipProvider> providers = fTipManager.getProviders();
		int spaceCount = Math.floorDiv(fScroller.getBounds().width, (fIconSize + fSpacing));
		int providerCount = providers.size();

		if (fSliderIndex > 0 && spaceCount >= providerCount) {
			fSliderIndex = 0;
		}

		if (spaceCount >= providerCount) {
			if (fRightButton.isEnabled()) {
				enableLeftRightButtons(false);
			}
		} else {
			if (!fRightButton.isEnabled()) {
				enableLeftRightButtons(true);
			}
		}

		int emptyPixelsLeft = Math.floorMod(fScroller.getBounds().width, (fIconSize + fSpacing));
		int newSpacing = fSpacing + (emptyPixelsLeft / (spaceCount + 1));
		for (int i = 0; i < Math.min(providerCount - fSliderIndex, spaceCount); i++) {
			TipProvider provider = providers.get(i + fSliderIndex);
			if (fSelectedProvider == null && !provider.getTips().isEmpty()) {
				fSelectedProvider = provider;
				notifyListeners(fSelectedProvider);
			}
			createProviderButton(providers.get(i + fSliderIndex), newSpacing, i);
		}
		setBackground(fScroller.getBackground());
	}

	private void enableLeftRightButtons(boolean enable) {
		fRightButton.setEnabled(enable);
		fRightButton.setVisible(enable);
		setLeftRightButtonGridData(fRightButton, enable ? fLeftRightButtonWidth : 0);
		fLeftButton.setEnabled(enable);
		fLeftButton.setVisible(enable);
		setLeftRightButtonGridData(fLeftButton, enable ? fLeftRightButtonWidth : 0);
		fRightButton.requestLayout();
		fLeftButton.requestLayout();
	}

	private Composite createProviderButton(TipProvider provider, int spacing, int index) {
		Composite button = new Composite(fScroller, SWT.DOUBLE_BUFFERED);
		button.setToolTipText(provider.getDescription());
		button.setBackground(fScroller.getBackground());
		button.setSize(fIconSize + 4, fIconSize + 4);
		button.setLocation((index * (fIconSize + spacing) + spacing - fSpacing), 2);
		button.addPaintListener(e -> {
			if (fSelectedProvider == provider) {
				fSelectedProviderButton = button;
			}
			paintButton(e.gc, button, provider);
		});
		button.addListener(SWT.MouseEnter, event -> button.redraw());
		button.addListener(SWT.MouseExit, event -> button.redraw());
		button.addListener(SWT.MouseUp, event -> {
			if (fSelectedProvider == provider) {
				return;
			}
			fSelectedProvider = provider;
			if (fSelectedProviderButton != null && !fSelectedProviderButton.isDisposed()) {
				fSelectedProviderButton.redraw();
			}
			fSelectedProviderButton = button;
			fSelectedProviderButton.redraw();
			notifyListeners(provider);
		});
		if (fSelectedProvider == provider) {
			fSelectedProviderButton = button;
		}
		return button;
	}

	/**
	 * Updates the read count of the currently selected button.
	 */
	public void updateButton() {
		if (fSelectedProviderButton != null && !fSelectedProviderButton.isDisposed()) {
			getDisplay().asyncExec(() -> fSelectedProviderButton.redraw());
		}
	}

	/**
	 * Calls redraw on all buttons to update the badge counter.
	 */
	public void updateButtons() {
		if (!isDisposed()) {
			getDisplay().asyncExec(() -> {
				if (!fScroller.isDisposed()) {
					for (Control control : fScroller.getChildren()) {
						if (control instanceof Composite && !control.isDisposed()) {
							control.redraw();
						}
					}
				}
			});
		}
	}

	/**
	 * Sets the {@link TipManager}.
	 *
	 * @param tipManager the {@link TipManager}
	 * @return this
	 */
	public Slider setTipManager(TipManager tipManager) {
		fTipManager = tipManager;
		fTipManager.getChangeSupport().addPropertyChangeListener(TipProvider.PROP_READY, fPropertyChangeListener);
		fIconSize = 48;
		load();
		return this;
	}

	private void notifyListeners(TipProvider provider) {
		fListeners.forEach(listener -> {
			try {
				listener.selected(provider);
			} catch (Exception e) {
				fTipManager.log(LogUtil.error(getClass(), e));
			}
		});
	}

	@Override
	public Point computeSize(int wHint, int hHint, boolean changed) {
		Point point = new Point(fIconSize * 3, fIconSize + fSpacing + fSpacing);
		return point;
	}

	protected void scrollRight() {
		if (fSliderIndex < fTipManager.getProviders().size() - 1) {
			fSliderIndex++;
			load();
		}
	}

	protected void scrollLeft() {
		if (fSliderIndex > 0) {
			fSliderIndex--;
			load();
		}
	}

	/**
	 * @return the current selected {@link TipProvider}.
	 */
	public TipProvider getTipProvider() {
		return fSelectedProvider;
	}

	/**
	 * Sets the passed provider as the selected provider in the slider.
	 *
	 * @param provider the new provider for the slider.
	 *
	 * @return this
	 */
	public Slider setTipProvider(TipProvider provider) {
		fSelectedProvider = provider;
		updateButtons();
		return this;
	}

	/**
	 * Adds the listener to the list of listeners to be called when an event with a
	 * {@link TipProvider} occurs.
	 *
	 * @param listener the {@link ProviderSelectionListener}
	 * @return this
	 */
	public Slider addTipProviderListener(ProviderSelectionListener listener) {
		fListeners.add(listener);
		return this;
	}

	/**
	 * Removes the listener from the list.
	 *
	 * @param listener the {@link ProviderSelectionListener}
	 * @return this
	 */
	public Slider removeTipProviderListener(ProviderSelectionListener listener) {
		fListeners.remove(listener);
		return this;
	}

	private void paintButton(GC gc, Composite providerButton, TipProvider provider) {
		gc.setAdvanced(true);
		if (!gc.getAdvanced()) {
			throw new RuntimeException(Messages.Slider_13);
		}
		if (provider.equals(fSelectedProvider)) {
			gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
			gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION));
			gc.drawRectangle(0, 0, fIconSize + 3, fIconSize + 3);
		} else {
			gc.setForeground(fLeftButton.getForeground());
			gc.setBackground(fLeftButton.getBackground());
			boolean mouseIn = getDisplay().getCursorControl() == providerButton;
			if (mouseIn) {
				gc.drawRectangle(0, 0, fIconSize + 3, fIconSize + 3);
			} else {
				gc.setBackground(fScroller.getBackground());
			}
		}
		gc.fillRectangle(2, 2, fIconSize, fIconSize);
		Image overlay = getUnreadOverlay(providerButton, provider);
		gc.drawImage(overlay, 2, 2);
		if (overlay != getProviderImage(provider, selectProviderImage(provider))) {
			overlay.dispose();
		}
	}

	private TipImage selectProviderImage(TipProvider provider) {
		return provider.getImage();
	}

	private Image getProviderImage(TipProvider provider, TipImage image) {
		if (!fProviderImageCache.containsKey(provider.getID())) {
			try {
				fProviderImageCache.put(provider.getID(),
						new Image(getDisplay(), ImageUtil.decodeToImage(image.getBase64Image())));
			} catch (Exception e) {
				fTipManager.log(LogUtil.error(getClass(), e));
				return null;
			}
		}
		return fProviderImageCache.get(provider.getID());
	}

	private Image getUnreadOverlay(Composite providerButton, TipProvider provider) {
		if (provider.getTips().isEmpty()) {
			return getProviderImage(provider, selectProviderImage(provider));
		}

		int tipCount = provider.getTips().size();
		Point textExtent = getTipCountTextSize(providerButton, tipCount);

		Image image = null;
		if (tipCount > 9) {
			image = new Image(getDisplay(), textExtent.x + 8, textExtent.y + 5);
		} else {
			image = new Image(getDisplay(), textExtent.x + 15, textExtent.y + 5);
		}
		ImageData data = image.getImageData();
		data.transparentPixel = data.getPixel(0, 0);
		image.dispose();
		image = new Image(getDisplay(), data);
		GC gc = new GC(image);
		gc.setAdvanced(true);
		if (fTipManager.mustServeReadTips()) {
			gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_DARK_GREEN));
		} else {
			gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_RED));
		}
		gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_WHITE));
		gc.setFont(SWTResourceManager.getBoldFont(gc.getFont()));
		gc.setAlpha(200);
		gc.setTextAntialias(SWT.ON);
		if (tipCount > 9) {
			gc.fillOval(0, 0, textExtent.x + 8, textExtent.y + 5);
			gc.drawText(tipCount + "", 4, 2, true); //$NON-NLS-1$
		} else {
			gc.fillOval(0, 0, textExtent.x + 15, textExtent.y + 5);
			gc.drawText(tipCount + "", 8, 2, true); //$NON-NLS-1$
		}
		Image result = ResourceManager.decorateImage(getProviderImage(provider, selectProviderImage(provider)), image,
				SWTResourceManager.TOP_RIGHT);
		image.dispose();
		gc.dispose();
		return result;
	}

	private Point getTipCountTextSize(Composite providerButton, int tipCount) {
		GC gc2 = new GC(providerButton);
		gc2.setAdvanced(true);
		gc2.setFont(SWTResourceManager.getBoldFont(gc2.getFont()));
		Point textExtent = gc2.textExtent(tipCount + ""); //$NON-NLS-1$
		gc2.dispose();
		return textExtent;
	}
}