/*
 * File:     InterlinearPrintable.java
 * Project:  MPI Linguistic Application
 * Date:     03 April 2006
 *
 * Copyright (C) 2001-2006  Max Planck Institute for Psycholinguistics
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package mpi.eudico.client.annotator.interlinear;

import mpi.eudico.client.annotator.commands.PrintCommand;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Pageable;
import java.awt.print.Printable;
import java.awt.print.PrinterException;


/**
 * The Pritable and Pageable class for Interlinear objects.
 *
 * @author HS
 * @version 1.0
 */
public class InterlinearPrintable implements Printable, Pageable {
    private Interlinear interlinear;

    /**
     * Creates a new InterlinearPrintable instance
     *
     * @param interlinear the Interlinear object containing the interlinearized
     *        content
     */
    public InterlinearPrintable(Interlinear interlinear) {
        this.interlinear = interlinear;
    }

    /**
     * Checks whether the page format is the same as the pageformat of the
     * Interlinear object. If not the interlinearisation has to be
     * recalculated. The rendering is delegated to the Interlinear object.
     *
     * @param graphics the printer graphics
     * @param pageFormat the format of the printer page
     * @param pageIndex the page to print
     *
     * @return PAGE_EXISTS or NO_SUCH_PAGE
     *
     * @throws PrinterException any exception while printing
     *
     * @see java.awt.print.Printable#print(java.awt.Graphics,
     *      java.awt.print.PageFormat, int)
     */
    public int print(Graphics graphics, PageFormat pageFormat, int pageIndex)
        throws PrinterException {
        int pw = (int) pageFormat.getImageableWidth();
        int ph = (int) pageFormat.getImageableHeight();

        if ((interlinear.getWidth() != pw) ||
                (interlinear.getPageHeight() != ph)) {
            interlinear.setWidth(pw);
            interlinear.setPageHeight(ph);
            interlinear.calculateMetrics(graphics);
        }

        if (pageIndex > (getNumberOfPages() - 1)) {
            return NO_SUCH_PAGE;
        }

        Graphics2D g2d = (Graphics2D) graphics;
        g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
        interlinear.renderPage(g2d, pageIndex);

        return PAGE_EXISTS;
    }

    /**
     * Returns the calculated number of pages.
     *
     * @return the number of pages in the document
     *
     * @see java.awt.print.Pageable#getNumberOfPages()
     */
    public int getNumberOfPages() {
        return interlinear.getMetrics().getPageBreaks().size();
    }

    /**
     * This method is called before <code>print</code>.
     *
     * @param pageIndex the index of the page to print
     *
     * @return the PageFormat for the specified page index
     *
     * @throws IndexOutOfBoundsException if pageIndex less than 0 or > number
     *         of pages - 1
     *
     * @see java.awt.print.Pageable#getPageFormat(int)
     */
    public PageFormat getPageFormat(int pageIndex)
        throws IndexOutOfBoundsException {
        if (pageIndex < 0) {
            throw new IndexOutOfBoundsException("Page Index: " + pageIndex +
                " < 0");
        }

        if (pageIndex >= getNumberOfPages()) {
            throw new IndexOutOfBoundsException("Page Index: " + pageIndex +
                " > " + (getNumberOfPages() - 1));
        }

        return PrintCommand.pageFormat;
    }

    /**
     * Returns the Printable object (== this)
     *
     * @param pageIndex the page to get the printable object for, zero based
     *
     * @return the printable object for the specified page index, is
     *         <code>this</code>
     *
     * @throws IndexOutOfBoundsException if pageIndex less than 0 or > number
     *         of pages - 1
     *
     * @see java.awt.print.Pageable#getPrintable(int)
     */
    public Printable getPrintable(int pageIndex)
        throws IndexOutOfBoundsException {
        if (pageIndex < 0) {
            throw new IndexOutOfBoundsException("Page Index: " + pageIndex +
                " < 0");
        }

        if (pageIndex >= getNumberOfPages()) {
            throw new IndexOutOfBoundsException("Page Index: " + pageIndex +
                " > " + (getNumberOfPages() - 1));
        }

        return this;
    }
}
