/*=============================================================================#
 # Copyright (c) 2013, 2021 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ecommons.ui.components;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

import org.eclipse.statet.ecommons.collections.FastList;
import org.eclipse.statet.ecommons.graphics.core.ColorDef;
import org.eclipse.statet.ecommons.ui.SharedUIResources;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;


public class AlphaSelector extends Canvas implements IObjValueWidget<Float> {
	
	
	private static final Float DEFAULT_VALUE = new Float(1f);
	
	private static final Color G_BACKGROUND = SharedUIResources.getColors().getColor(SharedUIResources.GRAPHICS_BACKGROUND_COLOR_ID);
	
	private static final ColorDef DEFAULT_BASE = new ColorDef(0, 0, 0);
	
	
	private final static class Data {
		
		private final int size;
		private final float factor;
		
		private final ColorDef baseColor;
		
		private final int alphaX0;
		private final int alphaX1;
		
		private final int y0;
		private final int y1;
		
		
		public Data(final int size, final ColorDef baseColor) {
			this.size = size;
			this.baseColor = baseColor;
			factor = size - 1;
			
			alphaX0 = 1;
			alphaX1 = alphaX0 + Math.round(size * 0.15f);
			
			y0 = 1;
			y1 = y0 + size;
		}
		
		
		public int alpha_y_255(final int y) {
			final int v = 255 - Math.round(((y - y0) / factor) * 255f);
			if (v <= 0) {
				return 0;
			}
			if (v >= 255) {
				return 255;
			}
			return v;
		}
		
		public int alpha_255_y(final int v) {
			return y0 + Math.round((v / 255f) * factor);
		}
		
		public float alpha_y_01(final int y) {
			final float v = 1f - ((y - y0) / factor);
			if (v <= 0f) {
				return 0f;
			}
			if (v >= 1f) {
				return 1f;
			}
			return v;
		}
		
		public int alpha_01_y(final float v) {
			return y0 + Math.round(((1f - v) * factor));
		}
		
		public int getBaseMax() {
			return Math.max(baseColor.getRed(), Math.max(baseColor.getGreen(), baseColor.getBlue()));
		}
		
		public Image createImage(final Display display) {
			final Image image = new Image(display, alphaX1 + 1, y1 + 1);
			final GC gc = new GC(image);
			gc.setAdvanced(false);
			
			gc.setBackground(G_BACKGROUND);
			gc.fillRectangle(0, 0, image.getImageData().width, image.getImageData().height);
			
			// prim
			if (baseColor.equalsRGB(DEFAULT_BASE)) {
				final int x1 = alphaX1 - 1;
				for (int y = y0; y < y1; y++) {
					final int alpha255 = 255 - alpha_y_255(y);
					final Color color = new Color(display, alpha255, alpha255, alpha255);
					gc.setForeground(color);
					gc.drawLine(alphaX0, y, x1, y);
					color.dispose();
				}
			}
			else {
				final int x1 = alphaX1 - 1;
				for (int y = y0; y < y1; y++) {
					final int alpha255 = alpha_y_255(y);
					final int white = 255 - alpha255;
					final Color color = new Color(display, 
							white + (baseColor.getRed() * alpha255) / 255,
							white + (baseColor.getGreen() * alpha255) / 255,
							white + (baseColor.getBlue() * alpha255) / 255 );
					gc.setForeground(color);
					gc.drawLine(alphaX0, y, x1, y);
					color.dispose();
				}
			}
			
			gc.dispose();
			return image;
		}
		
	}
	
	
	private class SWTListener implements PaintListener, Listener {
		
		
		private static final int TRACK_ALPHA = 1;
		
		private Data fData;
		
		private Image fImage;
		
		private int fMouseState;
		
		
		@Override
		public void handleEvent(final Event event) {
			final Data data = fData;
			switch (event.type) {
			case SWT.MouseDown:
				if (data != null && event.y >= data.y0 && event.y < data.y1
						&& event.x >= data.alphaX0 && event.x < data.alphaX1) {
					doSetValue(Float.valueOf(data.alpha_y_01(event.y)), event.time, 0);
					fMouseState = TRACK_ALPHA;
				}
				return;
			case SWT.MouseUp:
				fMouseState = 0;
				return;
			case SWT.MouseMove:
				if (data != null) {
					switch (fMouseState) {
					case TRACK_ALPHA:
						doSetValue(Float.valueOf(data.alpha_y_01(event.y)), event.time, 0);
						break;
					}
				}
				return;
			case SWT.Dispose:
				if (fImage != null) {
					fImage.dispose();
					fImage = null;
				}
			}
		}
		
		private int computeSize(int width, final int height) {
			width = Math.round(width / 0.15f);
			return Math.min(width - 2, height - 2);
		}
		
		@Override
		public void paintControl(final PaintEvent e) {
			final Rectangle clientArea = getClientArea();
			int size = computeSize(clientArea.width, clientArea.height);
			if (fSize > 0 && fSize < size) {
				size = fSize;
			}
			
			if (fData == null || fData.size != size || !fData.baseColor.equalsRGB(fBaseColor)) {
				if (fImage != null) {
					fImage.dispose();
					fImage = null;
				}
				fData = new Data(size, fBaseColor);
			}
			
			final GC gc = e.gc;
			
			gc.setAdvanced(false);
			
			gc.setBackground(G_BACKGROUND);
			gc.fillRectangle(clientArea);
			
//			if (fImage == null) {
				if (fImage != null) {
					fImage.dispose();
					fImage = null;
				}
				fImage = fData.createImage(e.display);
//			}
			gc.drawImage(fImage, 0, 0);
			
			gc.setLineWidth(1);
			gc.setAdvanced(true);
			gc.setAntialias(SWT.ON);
			
			{	final float alpha = fValue.floatValue();
				final int y = fData.alpha_01_y(alpha);
				gc.setForeground(e.display.getSystemColor(SWT.COLOR_BLACK));
				gc.drawLine(fData.alphaX0 - 1, y, fData.alphaX1, y);
				if (255 * (1f - alpha) + (fData.getBaseMax() * alpha) < 127) {
					gc.setForeground(e.display.getSystemColor(SWT.COLOR_WHITE));
					gc.drawLine(fData.alphaX0, y, fData.alphaX1 - 1, y);
				}
			}
		}
		
	}
	
	
	private int fSize = 8 + LayoutUtils.defaultHSpacing() * 30;
	
	private Float fValue = DEFAULT_VALUE;
	
	private final FastList<IObjValueListener<Float>> fValueListeners= (FastList) new FastList<>(IObjValueListener.class);
	
	private ColorDef fBaseColor = DEFAULT_BASE;
	
	
	public AlphaSelector(final Composite parent) {
		super(parent, SWT.DOUBLE_BUFFERED);
		
		final SWTListener listener = new SWTListener();
		addPaintListener(listener);
		addListener(SWT.MouseDown, listener);
		addListener(SWT.MouseUp, listener);
		addListener(SWT.MouseMove, listener);
		addListener(SWT.Dispose, listener);
	}
	
	
	public void setSize(final int size) {
		fSize = size;
	}
	
	public void setBaseColor(final ColorDef color) {
		fBaseColor = (color != null) ? color : DEFAULT_BASE;
		redraw();
	}
	
	private boolean doSetValue(final Float newValue, final int time, final int flags) {
		if (fValue.equals(newValue) && flags == 0 && fValue != DEFAULT_VALUE) {
			return false;
		}
		final IObjValueListener<Float>[] listeners = fValueListeners.toArray();
		final ObjValueEvent<Float> event= new ObjValueEvent<>(this, time, 0,
				fValue, newValue, flags);
		
		fValue = newValue;
		for (int i = 0; i < listeners.length; i++) {
			event.newValue = newValue;
			listeners[i].valueChanged(event);
		}
		if (!isDisposed()) {
			redraw();
		}
		return true;
	}
	
	
	@Override
	public Point computeSize(final int wHint, final int hHint, final boolean changed) {
		int width = 2 + Math.round(fSize * 0.15f);
		int height = 2 + fSize;
		final int border = getBorderWidth();
		width += border * 2;
		height += border * 2;
		return new Point(width, height);
	}
	
	
	@Override
	public Control getControl() {
		return this;
	}
	
	@Override
	public Class<Float> getValueType() {
		return Float.class;
	}
	
	@Override
	public void addValueListener(final IObjValueListener<Float> listener) {
		fValueListeners.add(listener);
	}
	
	@Override
	public void removeValueListener(final IObjValueListener<Float> listener) {
		fValueListeners.remove(listener);
	}
	
	@Override
	public Float getValue(final int idx) {
		if (idx != 0) {
			throw new IllegalArgumentException("idx: " + idx); //$NON-NLS-1$
		}
		return fValue;
	}
	
	@Override
	public void setValue(final int idx, final Float value) {
		if (idx != 0) {
			throw new IllegalArgumentException("idx: " + idx); //$NON-NLS-1$
		}
		if (value == null) {
			throw new NullPointerException("value"); //$NON-NLS-1$
		}
		doSetValue(value, 0, 0);
	}
	
}
