/******************************************************************************
 * Copyright (c) 2008, 2009 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    IBM Corporation - initial API and implementation 
 ****************************************************************************/

package org.eclipse.gmf.runtime.diagram.ui.printing.internal.util;

import java.util.Iterator;

import org.eclipse.core.runtime.Assert;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.SWTGraphics;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.RootEditPart;
import org.eclipse.gmf.runtime.common.ui.util.DisplayUtils;
import org.eclipse.gmf.runtime.diagram.core.preferences.PreferencesHint;
import org.eclipse.gmf.runtime.diagram.core.util.ViewUtil;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editparts.DiagramRootEditPart;
import org.eclipse.gmf.runtime.diagram.ui.internal.pagesetup.PageInfoHelper;
import org.eclipse.gmf.runtime.diagram.ui.internal.pagesetup.PageInfoHelper.PageMargins;
import org.eclipse.gmf.runtime.diagram.ui.internal.properties.WorkspaceViewerProperties;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramEditor;
import org.eclipse.gmf.runtime.diagram.ui.parts.DiagramGraphicalViewer;
import org.eclipse.gmf.runtime.diagram.ui.util.DiagramEditorUtil;
import org.eclipse.gmf.runtime.draw2d.ui.internal.graphics.MapModeGraphics;
import org.eclipse.gmf.runtime.draw2d.ui.internal.graphics.PrinterGraphics;
import org.eclipse.gmf.runtime.draw2d.ui.internal.graphics.ScaledGraphics;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;
import org.eclipse.gmf.runtime.draw2d.ui.render.internal.graphics.RenderedScaledGraphics;
import org.eclipse.gmf.runtime.notation.Diagram;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.printing.Printer;
import org.eclipse.swt.printing.PrinterData;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.PlatformUI;

/**
 * This class supports printing using the SWT printing constructs.
 * Much of the paging code was derived from the previous <code> DiagramPrinter </code>.
 *
 * @author Wayne Diu, wdiu
 */
public class SWTDiagramPrinter extends DiagramPrinter
    implements Runnable {

	protected Printer printer;
    
    private GC gc;
        
    private PrinterGraphics printerGraphics;
    
    private Point printerOffset;

    private Rectangle logicalClientArea;
        
  
    /**
     * Creates a new instance. The following variables must be initialized
     * before calling <code>run()</code>:
     * <li><code>printer</code></li>
     * <li><code>display_dpi</code></li>
     * <li><code>diagrams</code></li>
     * @param mm <code>IMapMode</code> to do the coordinate mapping
     */    
    public SWTDiagramPrinter(PreferencesHint preferencesHint, IMapMode mm) {
		super(preferencesHint, mm);
	}
    
    /**
     * Creates a new instance. The following variables must be initialized
     * before calling <code>run()</code>:
     * <li><code>printer</code></li>
     * <li><code>display_dpi</code></li>
     * <li><code>diagrams</code></li>
     * @param mapMode <code>IMapMode</code> to do the coordinate mapping
     */
    public SWTDiagramPrinter(PreferencesHint preferencesHint) {
        this(preferencesHint, MapModeUtil.getMapMode());
  }
     /**
     * Sets the printer.
     * 
     * @param printer
     *            The printer to set.
     */
    public void setPrinter(Printer printer) {
        this.printer = printer;
    }
     

    /**
     * Prints the contents of the diagram editor part.
     */
    public void run() {
        assert null != printer : "printer must be set"; //$NON-NLS-1$
        if (!(printer.startJob("Printing"))) { //$NON-NLS-1$
          return;
        }
        
        assert diagrams != null;
        Iterator<Diagram> it = diagrams.iterator();

        Shell shell = new Shell();
        try {
            while (it.hasNext()) {
                Object obj = it.next();
                //the diagrams List is only supposed to have Diagram objects
                Assert.isTrue(obj instanceof Diagram);
                Diagram diagram = (Diagram)obj;
                DiagramEditor openedDiagramEditor = DiagramEditorUtil
						.findOpenedDiagramEditorForID(ViewUtil
								.getIdStr(diagram));
				DiagramEditPart dgrmEP = openedDiagramEditor == null ? PrintHelperUtil
						.createDiagramEditPart(diagram, preferencesHint, shell)
						: openedDiagramEditor.getDiagramEditPart();
                
                boolean loadedPreferences = openedDiagramEditor != null || PrintHelperUtil.initializePreferences(dgrmEP, preferencesHint);

                RootEditPart rep = dgrmEP.getRoot();
                if (rep instanceof DiagramRootEditPart) 
                    this.mapMode = ((DiagramRootEditPart)rep).getMapMode();
                
                initialize();
                
                
                IPreferenceStore pref = null;
                
                assert dgrmEP.getViewer() instanceof DiagramGraphicalViewer;
        
                pref = ((DiagramGraphicalViewer)dgrmEP.getViewer()).getWorkspaceViewerPreferenceStore();
                
                if (pref.getBoolean(WorkspaceViewerProperties.PREF_USE_WORKSPACE_SETTINGS)) {
                    
                    //get workspace settings...
                    if (dgrmEP.getDiagramPreferencesHint().getPreferenceStore() != null){
                        pref = (IPreferenceStore)dgrmEP.getDiagramPreferencesHint().getPreferenceStore();
                    }
                }
                
            	// Ensure the preference value is properly updated when the
				// user overrides the preference store with values from the
				// print settings.
				// Printing and preview use the preference settings, to
				// calculate page size.
				PrinterData printerData = printer.getPrinterData();
				if (printerData != null) {
					boolean useLandscape = (printerData.orientation == PrinterData.LANDSCAPE);
					if (pref.getBoolean(WorkspaceViewerProperties.PREF_USE_LANDSCAPE) != useLandscape) {
						pref.setValue(
								WorkspaceViewerProperties.PREF_USE_LANDSCAPE,
								useLandscape);
					}
					if (pref.getBoolean(WorkspaceViewerProperties.PREF_USE_PORTRAIT) == useLandscape) {
						pref.setValue(
								WorkspaceViewerProperties.PREF_USE_PORTRAIT,
								!useLandscape);
					}
				}
                
                doPrintDiagram(dgrmEP, loadedPreferences, pref);
                
                dispose();
            }
            printer.endJob();
        } finally {
            shell.dispose();
        }        
    }
       

    /**
     * Prints to scale or prints to rows x columns pages
     */
    protected void doPrintDiagram(DiagramEditPart dgrmEP, boolean loadedPreferences, IPreferenceStore fPreferences) {
        this.graphics.pushState();
        if (isScaledPercent) {
            printToScale(dgrmEP, loadedPreferences, fPreferences);
        } else {
            printToPages(dgrmEP, loadedPreferences, fPreferences);
        }
        this.graphics.popState();
    }

    protected void initialize() {

        assert null != printer : "printer must be set"; //$NON-NLS-1$
        
        //check for rtl orientation...
        int style = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell().getStyle();
        if ((style & SWT.MIRRORED) != 0)
            this.gc = new GC(printer, SWT.RIGHT_TO_LEFT);
        else
            this.gc = new GC(printer);

        gc.setXORMode(false);

        this.swtGraphics = new SWTGraphics(gc);
        this.printerGraphics = createPrinterGraphics(swtGraphics);
        this.graphics = createMapModeGraphics(printerGraphics);
        this.graphics.scale(computePrinterDisplayScale());
        
        this.logicalClientArea = this.graphics.getClip(new Rectangle(
            this.printer.getClientArea()));
        
    }
    
    /**
     * Usually, the printable area is less than the page.
     * This method returns the offset for each x margin and each y margin.
     * x margins are left and right
     * y margins are top and bottom
     * 
     * We'll assume the left and right offsets are the same and the
     * top and bottom offsets are the same.
     * 
     * @return Point with x and y offsets
     */
    protected Point getPrinterOffset() {
        if (printerOffset == null) {
            int offsetX = this.printer.getBounds().width
            - this.printer.getClientArea().width;
            int offsetY = this.printer.getBounds().height
            - this.printer.getClientArea().height;
        
            // assume half on each side
            offsetX = (int) (getMapMode()
                .DPtoLP((int) (offsetX / 2.0f * display_dpi.x / printer.getDPI().x)) / userScale);
            offsetY = (int) (getMapMode()
                .DPtoLP((int) (offsetY / 2.0f * display_dpi.y / printer.getDPI().y)) / userScale);
            
            printerOffset = new Point(offsetX, offsetY);
        }
        
        return printerOffset;
    }

    /**
     * Print the diagram figure using specified scale factor.
     * 
     * @param dgrmEP the DiagramEditPart that will be printed
     * @param loadedPreferences true if existing prefs could be loaded
     * successfully, false if not and defaults are being used.  This parameter
     * is important to obtain the correct page break bounds.
     * @param fPreferences the preferenceStore that could either contain
     * existing preferences or defaults
     */
    protected void printToScale(DiagramEditPart dgrmEP, boolean loadedPreferences, IPreferenceStore fPreferences) {

        assert null != printer : "printer must be set"; //$NON-NLS-1$
        Rectangle figureBounds = PrintHelperUtil.getPageBreakBounds(dgrmEP, loadedPreferences);
        org.eclipse.draw2d.geometry.Point pageBounds = PageInfoHelper.getPageSize(fPreferences, getMapMode());

        //translate to offset initial figure position
        translated = new Point((int) (-figureBounds.x * userScale), (int) (-figureBounds.y * userScale));
        
        //calculate the number of page rows and columns
        int numRows = 0, numCols = 0;
        
        PageMargins margins = PageInfoHelper.getPageMargins(fPreferences, getMapMode());
        adjustMargins(margins, userScale, getPrinterOffset());
        
        GC gc_ = new GC(DisplayUtils.getDisplay(), this.gc.getStyle());
        gc_.setAntialias(this.gc.getAntialias());

        FontData fontData = JFaceResources.getDefaultFont().getFontData()[0];
        Font font = new Font(printer, fontData);
        
        org.eclipse.draw2d.geometry.Point pageCount = getPageCount(dgrmEP, figureBounds, pageBounds, true);
        numCols = pageCount.x;
        numRows = pageCount.y;

        //finalRow and finalColumn will be used if we are printing within a page range...
        int row = 1, col = 1, finalRow = 0, finalColumn = 0;
        
        if (this.printRangePageSelection) {
            //print only the pages specified in the page range...
            row = calculateRowFromPage(this.pageFrom, numCols);
            col = calculateColumnFromPage(this.pageFrom, numCols, row);
            
            finalRow = calculateRowFromPage(this.pageTo, numCols);
            finalColumn = calculateColumnFromPage(this.pageTo, numCols, finalRow);
        }
        
        try {
            //print the pages in row, column order
            for (; row <= numRows; row++) {
                for (; col <= numCols; col++) {
                    printer.startPage();
                    drawPage(gc_, dgrmEP, fPreferences, figureBounds, margins, font, row, col);
                    printer.endPage();
                    
                    if (row == finalRow && col == finalColumn && this.printRangePageSelection == true)
                        break;
                }
                
                if (row == finalRow && col == finalColumn && this.printRangePageSelection == true)
                    break;
                
                col = 1;
            }
        } finally {
            //must dispose resources
            font.dispose();
            gc_.dispose();
        }
    }

    /**
     * Draw the header and footer
     * 
     * @param gc_,
     *            a graphics context that is not null which this method will use
     *            for figuring ouyt the font's extent
     * @param figureBounds,
     *            Rectangle with the bounds of the figure
     * @param rowIndex,
     *            int
     * @param colIndex,
     *            int
     */
    protected void drawHeaderAndFooter(GC gc_, DiagramEditPart dgrmEP, Rectangle figureBounds,
            Font font, int rowIndex, int colIndex) {

        int width = this.logicalClientArea.width;
        int height = this.logicalClientArea.height;

        this.graphics.pushState(); //draw text, don't make it too small or big
        this.graphics.setFont(font);

        this.graphics.scale(1.0f / userScale);
        this.graphics.translate(-translated.x, -translated.y);

        String headerOrFooter = HeaderAndFooterHelper.makeHeaderOrFooterString(
            WorkspaceViewerProperties.HEADER_PREFIX, rowIndex, colIndex,
            dgrmEP);

        this.graphics.drawText(headerOrFooter,
            getMapMode().DPtoLP(HeaderAndFooterHelper.LEFT_MARGIN_DP)
                + (width - getMapMode().DPtoLP(gc_.textExtent(headerOrFooter).x))
                / 2, getMapMode().DPtoLP(HeaderAndFooterHelper.TOP_MARGIN_DP));

        headerOrFooter = HeaderAndFooterHelper.makeHeaderOrFooterString(
            WorkspaceViewerProperties.FOOTER_PREFIX, rowIndex, colIndex,
            dgrmEP);

        this.graphics.drawText(headerOrFooter,
            getMapMode().DPtoLP(HeaderAndFooterHelper.LEFT_MARGIN_DP)
                + (width - getMapMode().DPtoLP(gc_.textExtent(headerOrFooter).x))
                / 2, height - getMapMode().DPtoLP(HeaderAndFooterHelper.BOTTOM_MARGIN_DP));

        this.graphics.popState(); //for drawing the text

    }
    
    /**
     * This method paints a portion of the diagram. (The area painted
     * representing one page.)
     * 
     * @param gc_ a graphics context that is not null which this method will use
     * for figuring out the font's extent
     * @param dgrmEP the DiagramEditPart that will be printed
     * @param fPreferences the preferenceStore that could either contain
     * existing preferences or defaults
     * @param figureBounds the page break bounds we'll have to offset by
     * @param font the Font to print the header or footer with
     * @param rowIndex index of row we're printing
     * @param colIndex index of column we're priniting
     * to check if it is the first time the method is getting called for the current
     * print.
     */
    protected void drawPage(GC gc_, DiagramEditPart dgrmEP,
            IPreferenceStore fPreferences, Rectangle figureBounds,
            PageMargins margins, Font font, int rowIndex, int colIndex) {

        org.eclipse.draw2d.geometry.Point pageSize = PageInfoHelper
            .getPageSize(fPreferences, false, getMapMode());
        boolean rtlEnabled = ( this.gc !=null) && ((this.gc.getStyle() & SWT.MIRRORED) != 0);
        if (rtlEnabled) 
        {
            // draw everything on an offscreen image first and then draw that image
            // onto the printer gc...this takes care of certain drawing bugs.
            // This causes issues with printing resolution as it uses a display image
            // which is typically 72dpi
            // This code should be removed when a resolution to Bugzilla 162459 is found

            Image image = new Image(DisplayUtils.getDisplay(), getMapMode().LPtoDP(pageSize.x), getMapMode().LPtoDP(pageSize.y));

            GC imgGC = new GC(image, (rtlEnabled) ? SWT.RIGHT_TO_LEFT : SWT.LEFT_TO_RIGHT);
            imgGC.setXORMode(false);
      
            SWTGraphics sg = new SWTGraphics(imgGC);
              
            //for scaling
            ScaledGraphics g1 = new RenderedScaledGraphics(sg);
          
            //for himetrics and svg
            MapModeGraphics mmg = createMapModeGraphics(g1);
              
            //if mmg's font is null, gc.setFont will use a default font
            imgGC.setFont(mmg.getFont());
              
            internalDrawPage(dgrmEP,figureBounds,fPreferences,margins,mmg,rowIndex, colIndex,true);
            
            this.graphics.pushState();
        
            this.graphics.drawImage(image, 0, 0);
              
            this.graphics.popState();

            //draw the header and footer after drawing the image to avoid getting the image getting drawn over them
            drawHeaderAndFooter(gc_, dgrmEP, figureBounds, font, rowIndex, colIndex);
            disposeImageVars(imgGC, image, sg, g1, mmg);
        } else {
            internalDrawPage(dgrmEP,figureBounds,fPreferences,margins,this.graphics,rowIndex, colIndex,false);
            //draw the header and footer after drawing the image to avoid getting the image getting drawn over them
           drawHeaderAndFooter(gc_, dgrmEP, figureBounds, font, rowIndex, colIndex);
        }
    }
    
    protected void internalDrawPage(DiagramEditPart dgrmEP,
            Rectangle figureBounds, IPreferenceStore fPreferences,
            PageMargins margins, Graphics g, int rowIndex, int colIndex,
            boolean RTL_ENABLED) {
        org.eclipse.draw2d.geometry.Point pageSize = PageInfoHelper
            .getPageSize(fPreferences, false, getMapMode());

        int width = pageSize.x, height = pageSize.y;

        g.pushState();

        g.translate(translated.x, translated.y);
        g.scale(userScale);

        int translateX = -(width * (colIndex - 1));
        int translateY = -(height * (rowIndex - 1));

        int scaledTranslateX = (int) (translateX / userScale);
        int scaledTranslateY = (int) (translateY / userScale);

        int scaledWidth = (int) (width / userScale);
        int scaledHeight = (int) (height / userScale);

        if (RTL_ENABLED) {
            scaledTranslateX += (margins.left * (colIndex - 1))
                + (margins.right * (colIndex));
            scaledTranslateY += ((margins.top * rowIndex) + (margins.bottom * (rowIndex - 1)));
        } else {
            scaledTranslateX += ((margins.left * colIndex) + (margins.right * (colIndex - 1)));
            scaledTranslateY += ((margins.top * rowIndex) + (margins.bottom * (rowIndex - 1)));
        }

        g.translate(scaledTranslateX, scaledTranslateY);

        Rectangle clip = new Rectangle(
            (scaledWidth - margins.left - margins.right) * (colIndex - 1)
                + figureBounds.x, (scaledHeight - margins.bottom - margins.top)
                * (rowIndex - 1) + figureBounds.y, scaledWidth - margins.right
                - margins.left, scaledHeight - margins.top - margins.bottom);
        g.clipRect(clip);

        dgrmEP.getLayer(LayerConstants.PRINTABLE_LAYERS).paint(g);

        g.popState();
    }

    /**
     * Print the diagram figure to fit the number and rows and columns
     * specified by the user.
     * 
     * @param dgrmEP the DiagramEditPart that will be printed
     * @param loadedPreferences true if existing prefs could be loaded
     * successfully, false if not and defaults are being used.  This parameter
     * is important to obtain the correct page break bounds.
     * @param fPreferences the preferenceStore that could either contain
     * existing preferences or defaults
     */
    protected void printToPages(DiagramEditPart dgrmEP,
            boolean loadedPreferences, IPreferenceStore fPreferences) {
        assert null != printer : "printer must be set"; //$NON-NLS-1$

        Rectangle figureBounds = PrintHelperUtil.getPageBreakBounds(dgrmEP,
            loadedPreferences);
        
        PageMargins margins = PageInfoHelper.getPageMargins(fPreferences, getMapMode());
        //do not include margins
        org.eclipse.draw2d.geometry.Point pageBounds = PageInfoHelper
            .getPageSize(fPreferences, getMapMode());
        org.eclipse.draw2d.geometry.Point pageCount = getPageCount(dgrmEP, figureBounds, pageBounds, false);
        int numCols = pageCount.x;
        int numRows = pageCount.y;
        
        float actualWidth = 0;
        float actualHeight = 0;
        if (this.rows==1 && this.columns==1 && fitToPage){
        	figureBounds = dgrmEP.getChildrenBounds();
            actualWidth = figureBounds.width;
            actualHeight = figureBounds.height;
        }else {
            actualWidth = numCols * pageBounds.x;
            actualHeight = numRows * pageBounds.y;
        }

        int totalHeight = (this.rows * pageBounds.y);
        int totalWidth  = (this.columns * pageBounds.x);

        float vScale =  totalHeight / actualHeight;
        float hScale = totalWidth / actualWidth;

        this.userScale = Math.min(hScale, vScale);

        // translate to offset figure position
        translated = new Point((int) (-figureBounds.x * userScale),
            (int) (-figureBounds.y * userScale));

        adjustMargins(margins, userScale, getPrinterOffset());

        GC gc_ = new GC(DisplayUtils.getDisplay());

        FontData fontData = JFaceResources.getDefaultFont().getFontData()[0];
        Font font = new Font(printer, fontData);

        int row = 1, col = 1, finalRow = 0, finalColumn = 0;
        
        if (this.printRangePageSelection) {
            //print only the pages specified in the page range
            //this corresponds to the physical pages, not the print range of pages on one physical page.
            row = calculateRowFromPage(this.pageFrom, this.columns);
            col = calculateColumnFromPage(this.pageFrom, this.columns, row);
            
            finalRow = calculateRowFromPage(this.pageTo, this.columns);
            finalColumn = calculateColumnFromPage(this.pageTo, this.columns, finalRow);
        }
        
        try {
            // print the pages in row, column order
            for (; row <= rows; row++) {
                for (; col <= columns; col++) {
                    printer.startPage();
                    drawPage(gc_, dgrmEP, fPreferences, figureBounds, margins,
                        font, row, col);
                    printer.endPage();
                    
                    if (row == finalRow && col == finalColumn && this.printRangePageSelection == true)
                        break;
                }
                
                if (row == finalRow && col == finalColumn && this.printRangePageSelection == true)
                    break;
                
                col = 1;
            }
        } finally {
            // must dispose resources
            font.dispose();
            gc_.dispose();
        }
    }

    /**
     * Return scale factor between printer and display.
     * 
     * @return float
     */
    private float computePrinterDisplayScale() {
        assert null != printer : "printer must be set"; //$NON-NLS-1$
        assert null != display_dpi : "display_dpi must be set"; //$NON-NLS-1$

        Point dpi = printer.getDPI();
        float scale = dpi.x / (float) display_dpi.x;
        
        return scale;
    }

    /**
     * Disposes of the resources.
     */
    protected void dispose() {
        if (this.graphics != null) {
            try {
                this.graphics.dispose();
            }
            catch (NullPointerException e) {
                //do nothing
            }
            finally {
                this.graphics = null;                
            }
        }
        
        if (this.printerGraphics != null) {
            try {
                this.printerGraphics.dispose();
            }
            catch (NullPointerException e) {
                //do nothing
            }
            finally {
                this.printerGraphics = null;
            }
        }
        
        if (this.swtGraphics != null) {
            try {
                this.swtGraphics.dispose();
            }
            catch (NullPointerException e) {
                //do nothing
            }
            finally {
                this.swtGraphics = null;
            }
        }
        
        if (this.gc != null) {
            try {
                this.gc.dispose();
            }
            catch (NullPointerException e) {
                //do nothing
            }
            finally {
                this.gc = null;
            }
        }
        
        //reset the printer offset, just in case the next diagram to be printed 
        //uses a different map mode.
        printerOffset = null;
        
    }
    
    private void disposeImageVars(GC imgGC, Image image, SWTGraphics sg, 
            ScaledGraphics g1, MapModeGraphics mmg) {
        
        if (mmg != null) {
            try {
                mmg.dispose();
            }
            catch (NullPointerException e) {
                //do nothing
            }
            finally {
                mmg = null;                
            }
        }
        
        if (g1 != null) {
            try {
                g1.dispose();
            }
            catch (NullPointerException e) {
                //do nothing
            }
            finally {
                g1 = null;                
            }
        }
        
        if (sg != null) {
            try {
                sg.dispose();
            }
            catch (NullPointerException e) {
                //do nothing
            }
            finally {
                sg = null;                
            }
        }
        
        if (imgGC != null) {
            try {
                imgGC.dispose();
            }
            catch (NullPointerException e) {
                //do nothing
            }
            finally {
                imgGC = null;                
            }
        }
        
        if (image != null) {
            try {
                image.dispose();
            }
            catch (NullPointerException e) {
                //do nothing
            }
            finally {
                image = null;                
            }
        }
    }

       
    /**
     * Creates the <code>PrinterGraphics</code>.
     * 
     * @param theGraphics
     *          the <code>Graphics</code> object
     * @return the new <code>PrinterGraphics</code>
     */
    protected PrinterGraphics createPrinterGraphics(Graphics theGraphics) {
        return new PrinterGraphics(theGraphics, printer, true);
    }
    
       
    /**
     * Adjust the given PageMargins by the scale and offset
     * 
     * @param margins PageMargins to adjust
     * @param scale margins will be scaled by this amount
     * @param offset to adjust margins by
     */
    protected void adjustMargins(PageMargins margins, float scale, Point offset) {
        //scale
        margins.left /= scale;
        margins.top /= scale;
        margins.right /= scale;
        margins.bottom /= scale;
        
        //offsets
        margins.left -= offset.x; 
        margins.right += offset.x;
        margins.top -= offset.y;
        margins.bottom += offset.y;
        
        // this is more readable than doing Math.min for all the above
        if (margins.left < 0)
            margins.left = 0;
        if (margins.right < 0)
            margins.right = 0;
        if (margins.top < 0)
            margins.top = 0;
        if (margins.bottom < 0)
            margins.bottom = 0;
    }
}
