/*=============================================================================#
 # Copyright (c) 2011, 2017 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.internal.rj.eclient.graphics;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
import org.eclipse.swt.widgets.Display;


public class FontManager {
	
	private static final int[] R2SWT_STYLE= new int[] {
			SWT.NONE,
			SWT.BOLD,
			SWT.ITALIC,
			SWT.BOLD | SWT.ITALIC,
	};
	private static final int R_STYLE_COUNT= 4;
	
	
	private static final int HR_FONTSIZE= 60;
	private static final double HR_FACTOR= HR_FONTSIZE;
	private static final int HR_MIN_FONTSIZE= HR_FONTSIZE / 2;
	
	
	private static final class FontInstance {
		
		private static final double[] UNINITIALIZED= new double[0];
		
		public final int size;
		public final Font swtFont;
		
		private double[] swtFontProperties; // [ baselineOffset ] -> FontSetting
		
		private int baseLine;
		private double metricTolerance= 0;
		private double ascentUp= Integer.MIN_VALUE;
		private double ascentLow= Integer.MIN_VALUE;
		
		private int[] charAbove255;
		private double[] charMetrics= UNINITIALIZED;
		private double[] strWidth= UNINITIALIZED;
		
		
		public FontInstance(final int size, final Font font) {
			this.size= size;
			this.swtFont= font;
		}
		
		
		public void init(final GC gc) {
			final FontMetrics fontMetrics= gc.getFontMetrics();
			this.baseLine= fontMetrics.getLeading() + fontMetrics.getAscent();
			this.metricTolerance= fontMetrics.getAscent() * 0.05;
			
			this.swtFontProperties= new double[] {
					this.baseLine,
			};
		}
		
		public int checkChar(final int ch) {
			if (ch <= 0) {
				return 0;
			}
			else if (ch <= 255) {
				return ch;
			}
			else if (this.charAbove255 == null){
				this.charAbove255= new int[256];
				this.charAbove255[0]= ch;
				return 256 + 0;
			}
			else {
				for (int i= 0; i < this.charAbove255.length; i++) {
					final int c= this.charAbove255[i];
					if (c == 0) {
						this.charAbove255[i]= c;
						return 256 + i;
					}
					else if (c == ch) {
						return 256 + i;
					}
				}
				final int[] newChar= new int[this.charAbove255.length + 256];
				System.arraycopy(this.charAbove255, 0, newChar, 0, this.charAbove255.length);
				newChar[this.charAbove255.length]= ch;
				this.charAbove255= newChar;
				return this.charAbove255.length - 256;
			}
		}
		
	}
	
	
	private static final class TestGC {
		
		
		private final GC testGC;
		
		private FontInstance font;
		
		private final Image image;
		private final int imageWidth;
		private final int imageHeigth;
		private final int imagePixelBytes;
		private final int imageLineBytes;
		private final byte imageBlankData;
		
		private ImageData imageData;
		
		
		public TestGC(final Device device) {
			final GC tempGC= new GC(device);
			final Font tempFont= new Font(device, new FontData(device.getSystemFont().getFontData()[0].getName(), HR_FONTSIZE, 0));
			tempGC.setFont(tempFont);
			this.imageHeigth= (int) (tempGC.getFontMetrics().getHeight() * 1.5);
			this.imageWidth= this.imageHeigth * 2;
			tempGC.dispose();
			tempFont.dispose();
			
			this.image= new Image(device, this.imageWidth, this.imageHeigth);
			
			this.testGC= new GC(this.image);
			this.testGC.setAdvanced(true);
			this.testGC.setAntialias(SWT.ON);
			this.testGC.setTextAntialias(SWT.ON);
			this.testGC.setInterpolation(SWT.HIGH);
			this.testGC.setAlpha(255);
			this.testGC.setBackground(device.getSystemColor(SWT.COLOR_WHITE));
			this.testGC.setForeground(device.getSystemColor(SWT.COLOR_BLACK));
			this.testGC.setFont(null);
			this.font= null;
			
			clearImage();
			this.imageData= this.image.getImageData();
			this.imageLineBytes= this.imageData.bytesPerLine;
			this.imagePixelBytes= Math.max(this.imageData.bytesPerLine / this.imageData.width, 1);
			this.imageBlankData= this.imageData.data[0];
		}
		
		
		public void setFont(final FontInstance font) {
//			if (gcFont != font) { // E-Bug #319125
				this.font= font;
				this.testGC.setFont(font.swtFont);
//			}
			if (this.font.baseLine == 0) {
				this.font.init(this.testGC);
				this.testGC.setFont(font.swtFont); // E-Bug #319125
			}
		}
		
		public FontInstance getFont() {
			return this.font;
		}
		
		public int getStringWidth(final String txt) {
			return this.testGC.stringExtent(txt).x;
		}
		
		public void clearImage() {
			this.testGC.fillRectangle(0, 0, this.imageWidth, this.imageHeigth);
			this.imageData= null;
		}
		
		private void drawText(final String txt) {
			this.testGC.drawString(txt, 0, 0, true);
		}
		
		public int findFirstLine() {
			if (this.imageData == null) {
				this.imageData= this.image.getImageData();
			}
			final byte[] data= this.imageData.data;
			for (int i= 0; i < data.length; i+= this.imagePixelBytes) {
				if (data[i] != this.imageBlankData) {
					return (i / this.imageLineBytes);
				}
			}
			return -1;
		}
		
		public int findLastLine() {
			if (this.imageData == null) {
				this.imageData= this.image.getImageData();
			}
			final byte[] data= this.imageData.data;
			for (int i= data.length - this.imagePixelBytes; i >= 0; i-= this.imagePixelBytes) {
				if (data[i] != this.imageBlankData) {
					return (i / this.imageLineBytes);
				}
			}
			return -1;
		}
		
		
		public void dispose() {
			if (!this.testGC.isDisposed()) {
				this.testGC.dispose();
			}
			if (!this.image.isDisposed()) {
				this.image.dispose();
			}
		}
		
	}
	
	
	public final class FontFamily {
		
		private static final double POLISH_SMALL_MAX_FACTOR= 0.4;
		private static final double POLISH_SMALL_ADD_CORR= 0.04;
		private static final double POLISH_ADD_CONST= 0.05;
		private static final double POLISH_ADD_REL= 0.1;
		
		private static final int METRIC_IDX_ADVWIDTH= 0;
		private static final int METRIC_IDX_ASCENT= 1;
		private static final int METRIC_IDX_DESCENT= 2;
		private static final int METRIC_COUNT= 3;
		
		
		final String name;
		
		final FontInstance[][] fonts= new FontInstance[R_STYLE_COUNT][];
		
		
		private FontFamily(final String name) {
			this.name= name;
		}
		
		
		private FontInstance get(final int style, final int size) {
			FontInstance[] styleFonts= this.fonts[style];
			if (styleFonts == null) {
				this.fonts[style]= styleFonts= new FontInstance[4];
			}
			int idx;
			if (size == HR_FONTSIZE) {
				idx= 0;
			}
			else {
				idx= styleFonts.length;
				for (int i= 1; i < styleFonts.length; i++) {
					if (styleFonts[i] != null) {
						if (styleFonts[i].size == size) {
							idx= i;
							break;
						}
					}
					else {
						idx= i;
						break;
					}
				}
				if (idx >= styleFonts.length) {
					this.fonts[style]= new FontInstance[styleFonts.length+4];
					System.arraycopy(styleFonts, 0, this.fonts[style], 0, styleFonts.length);
					styleFonts= this.fonts[style];
				}
			}
			if (styleFonts[idx] == null) {
				final FontData fontData= new FontData(this.name, size, R2SWT_STYLE[style]);
				styleFonts[idx]= new FontInstance(size,
						new Font(FontManager.this.display, fontData));
			}
			return styleFonts[idx];
		}
		
		public synchronized Font getSWTFont(final int style, final int size) {
			return get(style, size).swtFont;
		}
		
		public synchronized double[] getCharMetrics(final int style, final int size, final int ch) {
			final FontInstance font= get(style, HR_FONTSIZE);
			final double factor= size / HR_FACTOR;
			final int chIdx= font.checkChar(ch) * METRIC_COUNT;
			
			final double[] answer= new double[3];
			
			if (chIdx >= font.charMetrics.length
					|| font.charMetrics[chIdx] == 0) {
				synchronized (getTestLock()) {
					final TestGC gc= getTestGC();
					gc.setFont(font);
					
					if (font.charMetrics.length == 0) {
						font.charMetrics= new double[Math.max(512 * METRIC_COUNT,
								chIdx + 128 * METRIC_COUNT)];
						
						font.charMetrics[' ' * METRIC_COUNT + METRIC_IDX_ADVWIDTH] =
								(gc.testGC.getAdvanceWidth('m') * 0.2 + gc.testGC.getAdvanceWidth(' ') * 1.0) / 2.0;
						font.charMetrics[' ' * METRIC_COUNT + METRIC_IDX_ASCENT]= 0;
						font.charMetrics[' ' * METRIC_COUNT + METRIC_IDX_DESCENT]= 0;
						
						font.ascentUp= checkCharAscentMean(gc, new char[] { 'A', 'M', 'O', 'E' });
						font.ascentLow= checkCharAscentMean(gc, new char[] { 'a', 'm', 'p', 'w' });
						
						font.charMetrics[0 * METRIC_COUNT + METRIC_IDX_ADVWIDTH] =
								font.charMetrics['M' * METRIC_COUNT + METRIC_IDX_ADVWIDTH];
						font.charMetrics[0 * METRIC_COUNT + METRIC_IDX_ASCENT] =
								(font.ascentUp > 0) ? font.ascentUp : 0;
						font.charMetrics[0 * METRIC_COUNT + METRIC_IDX_DESCENT]= 0;
					}
					else if (chIdx >= font.charMetrics.length) {
						final double[] newArray= new double[(chIdx + 128 * METRIC_COUNT)];
						System.arraycopy(font.charMetrics, 0, newArray, 0, font.charMetrics.length);
						font.charMetrics= newArray;
					}
					
					if (font.charMetrics[chIdx] == 0) {
						computeCharHeights(gc, ch, chIdx);
					}
					
//					Point sext= gc.stringExtent(new String(new int[] { this.currentChar }, 0, 1));
//					Point text= gc.textExtent(new String(new int[] { this.currentChar }, 0, 1), SWT.TRANSPARENT);
//					System.out.println("height= " + gc.getHeight());
//					System.out.println("leading= " + gc.getLeading());
//					System.out.println("ascent= " + gc.getAscent());
//					System.out.println("descent= " + gc.getDescent());
//					System.out.println("stringExtend.y= " + sext.y);
//					System.out.println("textExtend.y= " + text.y);
//					System.out.println("stringExtend.x= " + sext.x);
//					System.out.println("textExtend.x= " + text.x);
//					System.out.println("advanceWidth= " + gc.getAdvanceWidth((char) this.currentChar));
//					System.out.println("charWidth= " + gc.getCharWidth((char) this.currentChar));
//					System.out.println("averageCharWidth= " + gc.getFontMetrics.getAverageCharWidth());
//					System.out.println(this.currentAnswer[2]);
				}
			}
			
			answer[0]= polish(font.charMetrics[chIdx + METRIC_IDX_ASCENT] + 1.01 / factor, factor);
			answer[1]= polish(font.charMetrics[chIdx + METRIC_IDX_DESCENT], factor);
			answer[2]= polish(font.charMetrics[chIdx + METRIC_IDX_ADVWIDTH], factor);
			
//			System.out.println("-> " + Arrays.toString(answer));
			return answer;
		}
		
		private void computeCharHeights(final TestGC gc, final int ch, final int idx) {
			final FontInstance font= gc.getFont();
			font.charMetrics[idx + METRIC_IDX_ADVWIDTH] =
					gc.testGC.getAdvanceWidth((char) ch);
			
			final String s= String.valueOf((char) ch);
			
			gc.clearImage();
			gc.drawText(s);
			final int firstLine= gc.findFirstLine();
			if (firstLine >= 0) {
				double ascent= font.baseLine - firstLine;
				if (Math.abs(ascent - font.ascentUp) <= font.metricTolerance) {
					ascent= font.ascentUp;
				}
				else if (Math.abs(ascent - font.ascentLow) <= font.metricTolerance) {
					ascent= font.ascentLow;
				}
				int descent= gc.findLastLine() - font.baseLine + 1;
				if (Math.abs(descent) <= font.metricTolerance) {
					descent= 0;
				}
				font.charMetrics[idx + METRIC_IDX_ASCENT]= ascent;
				font.charMetrics[idx + METRIC_IDX_DESCENT]= descent;
			}
			else {
				font.charMetrics[idx + METRIC_IDX_ASCENT]= 0;
				font.charMetrics[idx + METRIC_IDX_DESCENT]= 0;
			}
			
			if (idx / METRIC_COUNT < font.strWidth.length
					&& font.strWidth[idx / METRIC_COUNT] == 0) {
				font.strWidth[idx / METRIC_COUNT]= gc.getStringWidth(s);
			}
		}
		
		private double checkCharAscentMean(final TestGC gc, final char[] chars) {
			final FontInstance font= gc.getFont();
			double mean= 0;
			for (int i= 0; i < chars.length; i++) {
				computeCharHeights(gc, chars[i], chars[i] * METRIC_COUNT);
				mean+= font.charMetrics[chars[i] * METRIC_COUNT + METRIC_IDX_ASCENT];
				gc.testGC.setFont(font.swtFont); // E-Bug #319125
			}
			mean /= chars.length;
			mean= polish(mean * 2.0, 1.0) / 2.0;
			for (int i= 0; i < chars.length; i++) {
				if (Math.abs(mean - font.charMetrics[chars[i] * METRIC_COUNT + METRIC_IDX_ASCENT]) > font.metricTolerance) {
					return Integer.MIN_VALUE;
				}
			}
			for (int i= 0; i < chars.length; i++) {
				font.charMetrics[chars[i] * METRIC_COUNT + METRIC_IDX_ASCENT]= mean;
			}
			return mean;
		}
		
		public synchronized double[] getStringWidth(final int style, final int size, final String text) {
			final FontInstance font;
			final double factor;
			final int chIdx;
			if (size < HR_MIN_FONTSIZE && text.length() == 1) {
				font= get(style, HR_FONTSIZE);
				factor= size / HR_FACTOR;
				chIdx= font.checkChar(text.charAt(0));
			}
			else {
				font= get(style, size);
				factor= 1.0;
				chIdx= -1;
			}
			
			final double[] answer= new double[] { (8 * text.length()) };
			
			if (chIdx < 0
					|| chIdx >= font.strWidth.length
					|| font.strWidth[chIdx] == 0) {
				synchronized (getTestLock()) {
					final TestGC gc= getTestGC();
					gc.setFont(font);
					
					final double width= gc.getStringWidth(text);
					answer[0]= width;
					if (chIdx >= 0) {
						if (font.strWidth.length == 0) {
							font.strWidth= new double[Math.max(512, chIdx + 256)];
						}
						else if (chIdx >= font.strWidth.length) {
							final double[] newWidth= new double[chIdx + 128];
							System.arraycopy(font.strWidth, 0, newWidth, 0, font.strWidth.length);
							font.strWidth= newWidth;
						}
						font.strWidth[chIdx]= width;
					}
				}
			}
			else {
				answer[0]= font.strWidth[chIdx];
			}
			if (factor != 1.0) {
//				this.currentAnswer[0]= Math.round((this.currentAnswer[0] * (factor * HR_ROUND_FACTOR)) + HR_ROUND_ADD) / HR_ROUND_FACTOR;
				answer[0]= polish(answer[0], factor);
			}
			
//			System.out.println("-> " + Arrays.toString(answer));
			return answer;
		}
		
		public synchronized double[] getSWTFontProperties(final int style, final int size) {
			final FontInstance font= get(style, size); // no HR!
			if (font.swtFontProperties == null) {
				synchronized (getTestLock()) {
					final TestGC gc= getTestGC();
					gc.setFont(font);
				}
			}
			return font.swtFontProperties;
		}
		
		private double polish(final double p, final double factor) {
			if (p == 0) {
				return 0;
			}
			final double add= (factor < POLISH_SMALL_MAX_FACTOR) ?
					(POLISH_SMALL_ADD_CORR / factor + POLISH_ADD_CONST) :
					(POLISH_SMALL_ADD_CORR/POLISH_SMALL_MAX_FACTOR + POLISH_ADD_CONST);
			if (p > 0) {
				return Math.round((p + POLISH_ADD_REL) * factor + add);
			}
			else {
				return Math.round((p - POLISH_ADD_REL) * factor - add);
			}
		}
		
		
		public void dispose() {
			for (int style= 0; style < R_STYLE_COUNT; style++) {
				final FontInstance[] styleFonts= this.fonts[style];
				if (styleFonts != null) {
					for (int i= 0; i < styleFonts.length; i++) {
						if (styleFonts[i] != null && styleFonts[i].swtFont != null) {
							if (!styleFonts[i].swtFont.isDisposed()) {
								styleFonts[i].swtFont.dispose();
							}
							styleFonts[i]= null;
						}
					}
				}
			}
		}
		
	}
	
	
	private final Display display;
	
	private final Object testGCLock= new Object();
	private TestGC testGC;
	private boolean disposed;
	
	private final Map<String, FontFamily> fontFamilies= new HashMap<>();
	
	
	public FontManager(final Display display) {
		this.display= display;
	}
	
	
	public synchronized FontFamily getFamily(final String family) {
		FontFamily fontFamily= this.fontFamilies.get(family);
		if (fontFamily == null) {
			fontFamily= new FontFamily(family);
			this.fontFamilies.put(family, fontFamily);
		}
		return fontFamily;
	}
	
	
	protected final Object getTestLock() {
		return this.testGCLock;
	}
	
	protected final TestGC getTestGC() {
		if (this.testGC == null) {
			this.display.syncExec(new Runnable() {
				@Override
				public void run() {
					if (!FontManager.this.disposed) {
						FontManager.this.testGC= new TestGC(FontManager.this.display);
					}
				}
			});
		}
		return this.testGC;
	}
	
	
	public void dispose() {
		this.disposed= true;
		for (final FontFamily fontFamily : this.fontFamilies.values()) {
			fontFamily.dispose();
		}
		this.fontFamilies.clear();
		
		if (this.testGC != null) {
			this.testGC.dispose();
			this.testGC= null;
		}
	}
	
}
