/*=============================================================================#
 # 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.rtm.base.ui.rexpr;

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.Font;
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.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.RParser;
import org.eclipse.statet.r.ui.graphics.RFontFamilyChooser;
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 FontFamilyType extends TypeDef implements PaintListener, Listener {
	
	
	private Button detail;
	
	private String currentValue;
	private String currentFontName;
	private Font currentSWTFont;
	
	private RFontFamilyChooser fontChooser;
	
	private final RGraphicFunctions rGraphicFunctions= RGraphicFunctions.DEFAULT;
	
	
	public FontFamilyType(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;
		String newValue= null;
		try {
			if (newExpr != null && newExpr.getTypeKey() == RTypedExpr.R) {
				final RParser rParser= new RParser(AstInfo.LEVEL_MODEL_DEFAULT);
				newValue= this.rGraphicFunctions.parseFontFamily(rParser.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 font family 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.currentFontName != null && !this.currentFontName.isEmpty()) {
			if (this.currentSWTFont == null) {
				this.currentSWTFont= RFontFamilyChooser.createFont(this.detail.getDisplay(), this.currentFontName,
						this.detail.getFont().getFontData()[0].getHeight() );
				if (this.currentSWTFont == null) {
					this.currentFontName= ""; //$NON-NLS-1$
				}
			}
			RFontFamilyChooser.drawPreview(gc, 5, 5, size.x - 11, size.y - 11, this.currentSWTFont);
		}
	}
	
	@Override
	public void handleEvent(final Event event) {
		switch (event.type) {
		case SWT.Selection:
			showColorChooser();
			return;
		case SWT.Dispose:
			if (this.fontChooser != null) {
				this.fontChooser.dispose();
			}
			if (this.currentSWTFont != null) {
				this.currentSWTFont.dispose();
				this.currentSWTFont= null;
			}
			return;
		default:
			break;
		}
	}
	
	private void showColorChooser() {
		if (this.fontChooser == null) {
			this.fontChooser= new RFontFamilyChooser() {
				@Override
				protected void onOK() {
					FontFamilyType.this.setValue(getValue());
				}
			};
		}
		if (this.fontChooser.isActive()) {
			this.fontChooser.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.fontChooser.open(this.detail.getShell(), bounds, this.currentValue);
	}
	
	private void setValue(final String value) {
		if (value == null) {
			setExpr(""); //$NON-NLS-1$
			return;
		}
		final StringBuilder sb= new StringBuilder();
		sb.append('"');
		sb.append(value);
		sb.append('"');
		
		doSetValue(value);
		
		this.detail.redraw();
		setExpr(sb.toString());
	}
	
	private void doSetValue(final String value) {
		final String fontName= RFontFamilyChooser.getFontName(value);
		if (this.currentSWTFont != null && !this.currentFontName.equals(fontName)) {
			this.currentSWTFont.dispose();
			this.currentSWTFont= null;
		}
		this.currentValue= value;
		this.currentFontName= fontName;
	}
	
}
