/*=============================================================================#
 # Copyright (c) 2013, 2020 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.rtm.base.ui.rexpr;

import com.ibm.icu.text.DecimalFormat;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
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.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.ui.statushandlers.StatusManager;

import org.eclipse.statet.jcommons.text.core.input.StringParserInput;

import org.eclipse.statet.ecommons.ui.components.DoubleText;
import org.eclipse.statet.ecommons.ui.components.ObjValueEvent;

import org.eclipse.statet.ltk.ast.core.AstInfo;
import org.eclipse.statet.r.core.model.RGraphicFunctions;
import org.eclipse.statet.r.core.rsource.ast.RScanner;
import org.eclipse.statet.r.ui.graphics.RAlphaChooser;
import org.eclipse.statet.rtm.base.ui.RtModelUIPlugin;
import org.eclipse.statet.rtm.base.ui.rexpr.RExprWidget.TypeDef;
import org.eclipse.statet.rtm.rtdata.types.RTypedExpr;


public class AlphaType extends TypeDef implements PaintListener, Listener {
	
	
	private Button detail;
	
	private Float currentValue;
	private int current255= -1;
	private Color currentSWTColor;
	
	private RAlphaChooser alphaChooser;
	
	private final RGraphicFunctions rGraphicFunctions= RGraphicFunctions.DEFAULT;
	
	
	public AlphaType(final RExprTypeUIAdapter type) {
		super(type);
	}
	
	
	@Override
	public boolean hasDetail() {
		return true;
	}
	
	@Override
	protected Control createDetailControl(final Composite parent) {
		this.detail= new Button(parent, SWT.NONE);
		this.detail.addPaintListener(this);
		this.detail.addListener(SWT.Selection, this);
		this.detail.addListener(SWT.Dispose, this);
		
		return this.detail;
	}
	
	
	@Override
	public void valueAboutToChange(final ObjValueEvent<RTypedExpr> event) {
		final RTypedExpr newExpr= event.newValue;
		Float newValue= null;
		try {
			if (newExpr != null && newExpr.getTypeKey() == RTypedExpr.R) {
				final RScanner scanner= new RScanner(AstInfo.LEVEL_MODEL_DEFAULT);
				newValue= this.rGraphicFunctions.parseAlpha(scanner.scanExpr(
						new StringParserInput(newExpr.getExpr()).init() ));
			}
		}
		catch (final Exception e) {
			StatusManager.getManager().handle(new Status(IStatus.ERROR, RtModelUIPlugin.BUNDLE_ID,
					"An error occurred when parsing the R alpha value expression.", e ));
		}
		
		doSetValue(newValue);
		
		this.detail.redraw();
	}
	
	
	@Override
	public void paintControl(final PaintEvent e) {
		final GC gc= e.gc;
		final Point size= this.detail.getSize();
		gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_DARK_GRAY));
		gc.drawRectangle(4, 4, size.x - 9, size.y - 9);
		if (this.currentValue != null) {
			if (this.currentSWTColor == null) {
				this.currentSWTColor= new Color(this.detail.getDisplay(),
						this.current255, this.current255, this.current255);
			}
			RAlphaChooser.drawPreview(gc, 5, 5, size.x - 11, size.y - 11, this.currentSWTColor);
		}
	}
	
	@Override
	public void handleEvent(final Event event) {
		switch (event.type) {
		case SWT.Selection:
			showColorChooser();
			return;
		case SWT.Dispose:
			if (this.alphaChooser != null) {
				this.alphaChooser.dispose();
			}
			if (this.currentSWTColor != null) {
				this.currentSWTColor.dispose();
				this.currentSWTColor= null;
			}
			return;
		default:
			break;
		}
	}
	
	private void showColorChooser() {
		if (this.alphaChooser == null) {
			this.alphaChooser= new RAlphaChooser() {
				@Override
				protected void onOK() {
					AlphaType.this.setValue(getValue());
				}
			};
		}
		if (this.alphaChooser.isActive()) {
			this.alphaChooser.close();
			return;
		}
		final Rectangle bounds= this.detail.getBounds();
		{	final Point location= this.detail.getParent().toDisplay(new Point(bounds.x, bounds.y));
			bounds.x= location.x;
			bounds.y= location.y;
		}
		this.alphaChooser.open(this.detail.getShell(), bounds, this.currentValue);
	}
	
	private void setValue(final Float value) {
		if (value == null) {
			setExpr(""); //$NON-NLS-1$
			return;
		}
		final StringBuilder sb= new StringBuilder();
		final DecimalFormat format= DoubleText.createFormat(3);
		sb.append(format.format(value.doubleValue()));
		
		doSetValue(value);
		
		this.detail.redraw();
		setExpr(sb.toString());
	}
	
	private void doSetValue(final Float value) {
		if (value != null) {
			final int v255= 255 - Math.round(value * 255);
			if (this.currentSWTColor != null && v255 != this.current255) {
				this.currentSWTColor.dispose();
				this.currentSWTColor= null;
			}
			this.currentValue= value;
			this.current255= v255;
		}
		else {
			this.currentValue= null;
		}
	}
	
}
