/*
 * Copyright (c) 2011, Patrik Dufresne. All rights reserved.
 * Patrik Dufresne PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.planimod.ui.printing;

import java.util.Date;

import net.sf.paperclips.EmptyPrint;
import net.sf.paperclips.GridPrint;
import net.sf.paperclips.PageNumber;
import net.sf.paperclips.PageNumberFormat;
import net.sf.paperclips.PageNumberPrint;
import net.sf.paperclips.Print;
import net.sf.paperclips.TextPrint;

import org.eclipse.swt.SWT;

import com.patrikdufresne.printing.FontDataUtil;
import com.patrikdufresne.printing.IPrintFactory;
import com.patrikdufresne.printing.MultipleHeaderSingleFooterPrintFactory;
import com.patrikdufresne.util.DateFormatRegistry;
import com.patrikdufresne.util.Localized;

/**
 * Default implementation if {@link IPrintFactory} for Planimod application.
 * This factory provide default header and footer based on the title.
 * <p>
 * Sub-classes must implement the abstract function {@link #createBodyArea()} to
 * create the content of this print factory. Default header will be created if
 * the title or the subtitle is sets. Default footer is added with printing date
 * and page count.
 * 
 * @author Patrik Dufresne
 * 
 */
public abstract class PlanimodPrintFactory extends
		MultipleHeaderSingleFooterPrintFactory {

	/**
	 * Instance of this class represent a printing section with a different
	 * header. This implementation create header using the title and subtitle
	 * value.
	 * 
	 * @author Patrik Dufresne
	 * 
	 */
	public abstract class PlanimodSection implements HeaderSection {

		private String subTitle;

		private String title;

		/**
		 * Create a new printing section with title and subtitle specified.
		 * 
		 * @param title
		 * @param subTitle
		 */
		public PlanimodSection(String title, String subTitle) {
			this.title = title;
			this.subTitle = subTitle;
		}

		/**
		 * This implementation create header using the title and subtitle value
		 * if not null.
		 */
		@Override
		public Print createHeaderArea(PageNumber pageNumber) {
			if (this.title == null && this.subTitle == null) {
				return null;
			}
			GridPrint grid = new GridPrint("c:d:g"); //$NON-NLS-1$
			if (this.title != null) {
				grid.add(new TextPrint(this.title, FontDataUtil.HEADER1, SWT.CENTER));
			}
			if (this.subTitle != null) {
				grid.add(new TextPrint(this.subTitle, FontDataUtil.HEADER2, SWT.CENTER));
			}
			return grid;
		}

	}

	/*
	 * The printing date.
	 */
	private Date printTime;

	/**
	 * Sub title
	 */
	private String subTitle;

	/**
	 * title
	 */
	private String title;

	/**
	 * Create a new print factory. Subclasses should set default title and sub
	 * title.
	 * 
	 * @param jobName
	 *            the job name
	 */
	public PlanimodPrintFactory(String jobName) {
		super(jobName);
	}

	/**
	 * Sub-classes should implement this function.
	 * 
	 * @return the print body.
	 */
	protected Print createBodyArea() {
		return new TextPrint("TODO", FontDataUtil.DEFAULT); //$NON-NLS-1$
	}

	/**
	 * This implementation create a footer with the page count and the date.
	 */
	@Override
	protected Print createFooterArea(PageNumber pageNumber) {

		GridPrint grid = new GridPrint(
				"left:default:grow(1), center:default:grow(1), right:default:grow(1)"); //$NON-NLS-1$

		// Left
		grid.add(createLeftFooterPrint(pageNumber));

		// Middle
		grid.add(createMiddleFooterPrint(pageNumber));

		// Right
		grid.add(createRightFooterPrint(pageNumber));

		return grid;
	}

	/**
	 * This function is called to create the text value for the left sided
	 * footer. This implementation return a label 'print in date'.
	 * 
	 * @param pageNumber
	 *            The page number
	 * @return the text value
	 * @see #createBodyArea()
	 * 
	 */
	protected Print createLeftFooterPrint(PageNumber pageNumber) {
		String text = Localized.format(
				PlanimodPrintFactory.class,
				"PlanimodPrintFactory.printTime", DateFormatRegistry.format( //$NON-NLS-1$
						getPrintTime(), DateFormatRegistry.DATETIME
								| DateFormatRegistry.ISO));
		return new TextPrint(text, FontDataUtil.SMALL);
	}

	protected Print createMiddleFooterPrint(PageNumber pageNumber) {
		return new EmptyPrint();
	}

	/**
	 * This function is called to create the text value for the right sided
	 * footer. This implementation return the page count.
	 * 
	 * @param pageNumber
	 * @return
	 */
	protected Print createRightFooterPrint(PageNumber pageNumber) {
		PageNumberPrint pageNumberPrint = new PageNumberPrint(pageNumber,
				FontDataUtil.SMALL, SWT.RIGHT);
		pageNumberPrint.setPageNumberFormat(new PageNumberFormat() {
			@Override
			public String format(PageNumber pn) {
				return Localized.format(
						PlanimodPrintFactory.class,
						"PlanimodPrintFactory.pages", //$NON-NLS-1$
						Integer.valueOf(pn.getPageNumber() + 1),
						Integer.valueOf(pn.getPageCount()));
			}
		});
		return pageNumberPrint;
	}

	/**
	 * This implementation is creating a single section using the function
	 * #createBodyPrint to create the body of the section.
	 */
	@Override
	protected void createSections() {
		addSection(new PlanimodSection(getTitle(), getSubTitle()) {
			@Override
			public Print createBodyArea() {
				return PlanimodPrintFactory.this.createBodyArea();
			}
		});
	}

	/**
	 * Return the print time of this print.
	 * 
	 * @return
	 */
	protected Date getPrintTime() {
		if (this.printTime == null) {
			this.printTime = new Date();
		}
		return this.printTime;
	}

	/**
	 * Return the sub-title.
	 * 
	 * @return
	 */
	public String getSubTitle() {
		return this.subTitle;
	}

	/**
	 * Return the title.
	 * 
	 * @return
	 */
	public String getTitle() {
		return this.title;
	}

	/**
	 * Sets the sub title of this print factory.
	 * 
	 * @param subTitle
	 */
	public void setSubTitle(String subTitle) {
		this.subTitle = subTitle;
	}

	/**
	 * Sets the title of this print factory.
	 * 
	 * @param title
	 */
	public void setTitle(String title) {
		this.title = title;
	}

}
