/*=============================================================================#
 # Copyright (c) 2012, 2021 Original NatTable authors 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.
 # 
 # SPDX-License-Identifier: EPL-2.0
 # 
 # Contributors:
 #     Original NatTable authors and others - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.ecommons.waltable.print;

import java.text.SimpleDateFormat;
import java.util.Date;

import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Transform;
import org.eclipse.swt.printing.PrintDialog;
import org.eclipse.swt.printing.Printer;
import org.eclipse.swt.printing.PrinterData;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

import org.eclipse.statet.ecommons.waltable.Messages;
import org.eclipse.statet.ecommons.waltable.config.IConfigRegistry;
import org.eclipse.statet.ecommons.waltable.coordinate.LRectangle;
import org.eclipse.statet.ecommons.waltable.layer.ILayer;
import org.eclipse.statet.ecommons.waltable.swt.SWTUtil;
import org.eclipse.statet.ecommons.waltable.ui.IClientAreaProvider;


/**
 * This class is used to print a layer.
 * Usually you create an instance by using the top most layer in the layer stack.
 * For grids this is the GridLayer, otherwise the ViewportLayer is a good choice.
 */
public class LayerPrinter {

	private final IConfigRegistry configRegistry;
	private final ILayer layer;
	private final IClientAreaProvider originalClientAreaProvider;
	public static final int FOOTER_HEIGHT_IN_PRINTER_DPI= 300;

	final SimpleDateFormat dateFormat= new SimpleDateFormat("EEE, d MMM yyyy HH:mm a"); //$NON-NLS-1$
	private final String footerDate;

	/**
	 * 
	 * @param layer The layer to print. Usually the top most layer in the layer stack.
	 * 			For grids this should be the GridLayer, for custom CompositeLayer compositions
	 * 			the CompositeLayer, otherwise the ViewportLayer is a good choice.
	 * @param configRegistry The ConfigRegistry needed for rendering to the print GC.
	 */
	public LayerPrinter(final ILayer layer, final IConfigRegistry configRegistry) {
		this.layer= layer;
		this.configRegistry= configRegistry;
		this.originalClientAreaProvider= layer.getClientAreaProvider();
		this.footerDate= this.dateFormat.format(new Date());
	}

	/**
	 * Computes the scale factor to match the printer resolution.
	 * @param printer The printer that will be used.
	 * @return The amount to scale the screen resolution by, to match the 
	 * 			printer the resolution.
	 */
	private Point computeScaleFactor(final Printer printer) {
		final Point screenDPI= Display.getDefault().getDPI();
		final Point printerDPI= printer.getDPI();

		final int scaleFactorX= printerDPI.x / screenDPI.x;
		final int scaleFactorY= printerDPI.y / screenDPI.y;
		return new Point(scaleFactorX, scaleFactorY);
	}

	/**
	 * @return The size of the layer to fit all the contents.
	 */
	private LRectangle getTotalArea() {
		return new LRectangle(0, 0, this.layer.getWidth(), this.layer.getHeight());
	}

	/**
	 * Calculates number of horizontal and vertical pages needed
	 * to print the entire layer.
	 * @param printer The printer that will be used.
	 * @return The number of horizontal and vertical pages that are
	 * 			needed to print the layer.
	 */
	private Point getPageCount(final Printer printer){
		final LRectangle layerArea= getTotalArea();
		final LRectangle printArea= computePrintArea(printer);
		final Point scaleFactor= computeScaleFactor(printer);

		final int numOfHorizontalPages= (int) (layerArea.width / (printArea.width / scaleFactor.x));
		final int numOfVerticalPages= (int) (layerArea.height / (printArea.height / scaleFactor.y));

		// Adjusting for 0 index
		return new Point(numOfHorizontalPages + 1, numOfVerticalPages + 1);
	}

	/**
	 * Will first open the PrintDialog to let a user configure the print job
	 * and then starts the print job.
	 * @param shell The shell which should be the parent of the PrintDialog.
	 */
	public void print(final Shell shell) {
		//turn viewport off to ensure calculation of the print pages for the whole table
		this.layer.doCommand(new TurnViewportOffCommand());
		
		final Printer printer= setupPrinter(shell);
		if (printer == null) {
			return;
		}

		//turn viewport on
		this.layer.doCommand(new TurnViewportOnCommand());
		
		//Note: As we are operating on the same layer instance that is shown in the UI
		//		executing the print job asynchronously will not cause a real asynchronous
		//		execution. The UI will hang until the print job is done, because we access
		//		the information to print from the same instance. 
		//		For further developments we need to ensure that for printing a deep copy 
		//		of the layer needs to be performed instead of operating on the same instance.
		Display.getDefault().asyncExec(new PrintJob(printer));
	}

	/**
	 * Checks if a given page number should be printed.
	 * Page is allowed to print if:
	 * 	  User asked to print all pages or Page in a specified range
	 * @param printerData The printer settings made by the user. Needed to determine
	 * 			if a page should be printed dependent to the scope
	 * @param currentPage The page that should be checked
	 * @return <code>true</code> if the given page should be printed, 
	 * 			<code>false</code> if not 
	 */
	private boolean shouldPrint(final PrinterData printerData, final int totalPageCount) {
		if (printerData.scope == PrinterData.PAGE_RANGE) {
			return totalPageCount >= printerData.startPage && totalPageCount <= printerData.endPage;
		}
		return true;
	}

	/**
	 * Opens the PrintDialog to let the user specify the printer and print configurations to use.
	 * @param shell The Shell which should be the parent for the PrintDialog
	 * @return The selected printer with the print configuration made by the user.
	 */
	private Printer setupPrinter(final Shell shell) {
		final Printer defaultPrinter= new Printer();
		final Point pageCount= getPageCount(defaultPrinter);
		defaultPrinter.dispose();

		final PrintDialog printDialog= new PrintDialog(shell);
		printDialog.setStartPage(1);
		printDialog.setEndPage(pageCount.x * pageCount.y);
		printDialog.setScope(PrinterData.ALL_PAGES);

		final PrinterData printerData= printDialog.open();
		if (printerData == null){
			return null;
		}
		return new Printer(printerData);
	}

	/**
	 * Computes the print area, including margins
	 * @param printer The printer that will be used.
	 * @return The print area that will be used to render the table.
	 */
	private LRectangle computePrintArea(final Printer printer) {
		// Get the printable area
		final org.eclipse.swt.graphics.Rectangle rect= printer.getClientArea();

		// Compute the trim
		final org.eclipse.swt.graphics.Rectangle trim= printer.computeTrim(0, 0, 0, 0);

		// Get the printer's DPI
		final Point dpi= printer.getDPI();
		dpi.x= dpi.x / 2;
		dpi.y= dpi.y / 2;

		// Calculate the printable area, using 1 inch margins
		int left= trim.x + dpi.x;
		if (left < rect.x) {
			left= rect.x;
		}

		int right= (rect.width + trim.x + trim.width) - dpi.x;
		if (right > rect.width) {
			right= rect.width;
		}

		int top= trim.y + dpi.y;
		if (top < rect.y) {
			top= rect.y;
		}

		int bottom= (rect.height + trim.y + trim.height) - dpi.y;
		if (bottom > rect.height) {
			bottom= rect.height;
		}

		return new LRectangle(left, top, right - left, bottom - top);
	}
	

	/**
	 * The job for printing the layer.
	 */
	private class PrintJob implements Runnable {
		/**
		 * The printer that will be used.
		 */
		private final Printer printer;

		/**
		 * @param printer The printer that will be used.
		 */
		private PrintJob(final Printer printer) {
			this.printer= printer;
		}

		@Override
		public void run() {
			if (this.printer.startJob("NatTable")) { //$NON-NLS-1$
				//if a SummaryRowLayer is in the layer stack, we need to ensure that the values are calculated
//				LayerPrinter.this.layer.doCommand(new CalculateSummaryRowValuesCommand());

				//ensure that the viewport is turned off
				LayerPrinter.this.layer.doCommand(new TurnViewportOffCommand());
				
				//set the size of the layer according to the print setttings made by the user
				setLayerSize(this.printer.getPrinterData());
				
				final LRectangle printerClientArea= computePrintArea(this.printer);
				final Point scaleFactor= computeScaleFactor(this.printer);
				final Point pageCount= getPageCount(this.printer);
				final GC gc= new GC(this.printer);

				// Print pages Left to Right and then Top to Down
				int currentPage= 1;
				for (int verticalPageNumber= 0; verticalPageNumber < pageCount.y; verticalPageNumber++) {

					for (int horizontalPageNumber= 0; horizontalPageNumber < pageCount.x; horizontalPageNumber++) {

						// Calculate bounds for the next page
						final org.eclipse.swt.graphics.Rectangle printBounds= SWTUtil.toSWT(new LRectangle(
								(printerClientArea.width / scaleFactor.x) * horizontalPageNumber,
								((printerClientArea.height - FOOTER_HEIGHT_IN_PRINTER_DPI) / scaleFactor.y) * verticalPageNumber,
								printerClientArea.width / scaleFactor.x,
								(printerClientArea.height - FOOTER_HEIGHT_IN_PRINTER_DPI) / scaleFactor.y));

						if (shouldPrint(this.printer.getPrinterData(), currentPage)) {
							this.printer.startPage();

							final Transform printerTransform= new Transform(this.printer);

							// Adjust for DPI difference between display and printer
							printerTransform.scale(scaleFactor.x, scaleFactor.y);

							// Adjust for margins
							printerTransform.translate(printerClientArea.x / scaleFactor.x, printerClientArea.y / scaleFactor.y);

							// Grid will not automatically print the pages at the left margin.
							// Example: page 1 will print at x= 0, page 2 at x= 100, page 3 at x= 300
							// Adjust to print from the left page margin. i.e x= 0
							printerTransform.translate(-1 * printBounds.x, -1 * printBounds.y);
							gc.setTransform(printerTransform);

							printLayer(gc, printBounds);

							printFooter(gc, currentPage, printBounds);

							this.printer.endPage();
							printerTransform.dispose();
						}
						currentPage++;
					}
				}

				this.printer.endJob();

				gc.dispose();
				this.printer.dispose();
			}
			restoreLayerState();
		}

		/**
		 * Set the client area of the layer so it matches the print settings made by the user. 
		 * In case a user selected to print everything, the size needs to be extended so that
		 * all the contents fit in the viewport to ensure that we print the <i>entire</i> table.
		 * @param printerData The PrinterData that was configured by the user on the PrintDialog.
		 */
		private void setLayerSize(final PrinterData printerData) {
			if (printerData.scope == PrinterData.SELECTION) {
				LayerPrinter.this.layer.setClientAreaProvider(LayerPrinter.this.originalClientAreaProvider);
			}
			else {
				final LRectangle fullLayerSize= getTotalArea();
				
				LayerPrinter.this.layer.setClientAreaProvider(new IClientAreaProvider(){
					@Override
					public LRectangle getClientArea() {
						return fullLayerSize;
					}
				});
				
				//in case the whole layer should be printed or only the selected pages,
				//we need to ensure to set the starting point to 0/0
				LayerPrinter.this.layer.doCommand(new PrintEntireGridCommand());
			}
		}

		/**
		 * Print the part of the layer that matches the given print bounds.
		 * @param gc The print GC to render the layer to.
		 * @param printBounds The bounds of the print page.
		 */
		private void printLayer(final GC gc, final org.eclipse.swt.graphics.Rectangle printBounds) {
			LayerPrinter.this.layer.getLayerPainter().paintLayer(LayerPrinter.this.layer, gc, 0, 0, printBounds, LayerPrinter.this.configRegistry);
		}

		/**
		 * Print the footer to the page.
		 * @param gc The print GC to render the footer to.
		 * @param totalPageCount The total number of pages that are printed.
		 * @param printBounds The bounds of the print page.
		 */
		private void printFooter(final GC gc, final int totalPageCount, final org.eclipse.swt.graphics.Rectangle printBounds) {
			gc.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
			gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));

			gc.drawLine(printBounds.x,
			            printBounds.y + printBounds.height+10,
			            printBounds.x + printBounds.width,
			            printBounds.y + printBounds.height+10);

			gc.drawText(Messages.getString("Printer.page") + " " + totalPageCount, //$NON-NLS-1$ //$NON-NLS-2$
			            printBounds.x,
			            printBounds.y + printBounds.height + 15);

			// Approximate width of the date string: 140
			gc.drawText(LayerPrinter.this.footerDate,
			            printBounds.x + printBounds.width - 140,
			            printBounds.y + printBounds.height + 15);
		}
		
		/**
		 * Restores the layer state to match the display characteristics again.
		 * This is done by resetting the client area provider and turning the viewport
		 * on again.
		 */
		private void restoreLayerState() {
			LayerPrinter.this.layer.setClientAreaProvider(LayerPrinter.this.originalClientAreaProvider);
			LayerPrinter.this.layer.doCommand(new TurnViewportOnCommand());
		}

	}

}
