package rapport;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;

import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;

/**
 * generate deposit repport
 * @author martin
 *
 */
public class RapportDepot extends RapportLandscape{
	private static class Row{
		public int numeroFermeture;
		public Date dateFermeture;
		public String nomEmploye;
		public BigDecimal argent;
		public BigDecimal interac;
		public BigDecimal cheque;
		public BigDecimal amex;
		public BigDecimal visa;
		public BigDecimal mastercard;
		public BigDecimal autres;
		private Row(int numeroFermeture, Date dateFermeture, String nomEmploye,
				BigDecimal argent, BigDecimal interac, BigDecimal cheque,
				BigDecimal amex, BigDecimal visa, BigDecimal mastercard,
				BigDecimal autres) {
			super();
			this.numeroFermeture = numeroFermeture;
			this.dateFermeture = dateFermeture;
			this.nomEmploye = nomEmploye;
			this.argent = argent;
			this.interac = interac;
			this.cheque = cheque;
			this.amex = amex;
			this.visa = visa;
			this.mastercard = mastercard;
			this.autres = autres;
		}
	};
	
	private int numeroDepot;
	private Date dateDepot;
	private String nomEmploye;
	public Date dateGenerer;
	private List<Row> fermetureLst;

	private int cursor;
	
	private PDFont bold;
	private PDFont font;
	
	/**
	 * constructor
	 * @throws IOException
	 */
	public RapportDepot() throws IOException{
		super();
		bold = PDType1Font.HELVETICA_BOLD;
		font = PDType1Font.HELVETICA;
		fermetureLst = new ArrayList<>();
		cursor=0;
		dateGenerer = new Date(System.currentTimeMillis());
	}
	/*_______________________________________________________________________*/
	//override rapport
	//tel how to generate document
	/*_______________________________________________________________________*/

	@Override
	public int countPage(){
		return fermetureLst.size()/28 + (fermetureLst.size()%28==0?0:1);
	}
	
	@Override
	public void firstPageHeader() throws IOException{
		//date
		addTextLeftAlign("Date", font, 12, 75, 125,15);
		addTextLeftAlign(dateDepot.toString(), font, 12, 200, 125, 20);
		
		//employe
		addTextLeftAlign("Nom de l'employé", font, 12, 75, 150,15);
		addTextLeftAlign(nomEmploye, font, 12, 200, 150, 20);
	}
	
	@Override
	public void header() throws IOException{
		addText("Dépôt", bold, 24, getW()/2, 50);
		addTextInBox(""+numeroDepot, bold, 12, 75, 100, 15);
	}
	
	@Override
	public void footer() throws IOException{
		//addSeparator(getH()-16);
		//date impresion
		addTextLeftAlign(dateGenerer.toString(), bold, 12, 80, getH()-12, 20);
		//numero de page
		int nbPage = fermetureLst.size()/28;
		addTextLeftAlign("Page "+currentPage()+" de "+countPage(), bold, 12, getW()-10, getH()-12, 20);
	}
	
	@Override
	public void lastPageFooter() throws IOException{
		BigDecimal argent = BigDecimal.valueOf(0),
		           interac = BigDecimal.valueOf(0),
		           cheque = BigDecimal.valueOf(0),
		           amex = BigDecimal.valueOf(0),
		           visa = BigDecimal.valueOf(0),
		           mastercard = BigDecimal.valueOf(0),
		           autre = BigDecimal.valueOf(0);
		for (Row row : fermetureLst){
			argent = argent.add(row.argent);
			interac = interac.add(row.interac);
			cheque = cheque.add(row.cheque);
			amex = amex.add(row.amex);
			visa = visa.add(row.visa);
			mastercard = mastercard.add(row.mastercard);
			autre = autre.add(row.autres);
		}
		BigDecimal total = argent.add(interac).add(cheque).add(amex).add(visa).add(mastercard).add(autre);
		
		addSeparator(getH()-66);
		addTextRightAlign("Total", bold, 12, getW()-460, getH()-60, 5);
		addTextInBox(argent.toPlainString()+"$", bold, 10, getW()-390, getH()-60, 10);
		addTextInBox(interac.toPlainString()+"$", bold, 10, getW()-330, getH()-60, 10);
		addTextInBox(cheque.toPlainString()+"$", bold, 10, getW()-270, getH()-60, 10);
		addTextInBox(amex.toPlainString()+"$", bold, 10, getW()-210, getH()-60, 10);
		addTextInBox(visa.toPlainString()+"$", bold, 10, getW()-150, getH()-60, 10);
		addTextInBox(mastercard.toPlainString()+"$", bold, 10, getW()-90, getH()-60, 10);
		addTextInBox(autre.toPlainString()+"$", bold, 10, getW()-30, getH()-60, 10);
		
		addTextInBox(total.toPlainString()+"$", bold, 12, getW()-60, getH()-40, 15);
		addTextRightAlign("Grand Total", bold, 12, getW()-200, getH()-40, 9);
	}

	@Override
	public void body() throws IOException{
		//colname
		addSeparator(200);
		addText("Fermeture", bold, 12, 35, 188);
		addText("Date", bold, 12, 110, 188);
		addTextLeftAlign("Nom de l'employé", bold, 12, 230, 188,20);
		addText("Argent", bold, 12, getW()-390, 188);
		addText("Interac", bold, 12, getW()-330, 188);
		addText("Chèque", bold, 12, getW()-270, 188);
		addText("Amex", bold, 12, getW()-210, 188);
		addText("Visa", bold, 12, getW()-150, 188);
		addText("Mastercard", bold, 12, getW()-90, 188);
		addText("Autres", bold, 12, getW()-30, 188);
		
		//row
		int max = 28<fermetureLst.size()-cursor?28:fermetureLst.size()-cursor;
		for (int y = 0; y < max; y++){
			addText(""+fermetureLst.get(cursor+y).numeroFermeture, bold, 12, 35, 208+y*12);
			addText(fermetureLst.get(cursor+y).dateFermeture.toString(), bold, 12, 110, 208+y*12);
			addTextLeftAlign(fermetureLst.get(cursor+y).nomEmploye, bold, 12, 230, 208+y*12,20);
			addText(fermetureLst.get(cursor+y).argent.toPlainString()+"$", bold, 12, getW()-390, 208+y*12);
			addText(fermetureLst.get(cursor+y).interac.toPlainString()+"$", bold, 12, getW()-330, 208+y*12);
			addText(fermetureLst.get(cursor+y).cheque.toPlainString()+"$", bold, 12, getW()-270, 208+y*12);
			addText(fermetureLst.get(cursor+y).amex.toPlainString()+"$", bold, 12, getW()-210, 208+y*12);
			addText(fermetureLst.get(cursor+y).visa.toPlainString()+"$", bold, 12, getW()-150, 208+y*12);
			addText(fermetureLst.get(cursor+y).mastercard.toPlainString()+"$", bold, 12, getW()-90, 208+y*12);
			addText(fermetureLst.get(cursor+y).autres.toPlainString()+"$", bold, 12, getW()-30, 208+y*12);
		}
	}
	
	@Override
	public void generate() throws IOException{
		boolean lastpage = false;
		firstPageHeader();
		while(!lastpage){
			header();
			body();
			footer();
			cursor += 28;
			lastpage = fermetureLst.size() <= cursor;
			if (!lastpage)
				nextPage();
		}
		lastPageFooter();
	}
	
	/*_______________________________________________________________________*/
	//data
	/*_______________________________________________________________________*/

	/**
	 * set deposit number
	 * @param numeroDepot
	 */
	public void setNumeroDepot(int numeroDepot) {
		this.numeroDepot = numeroDepot;
	}

	/**
	 * set date of the deposit
	 * @param dateDepot
	 */
	public void setDateDepot(Date dateDepot) {
		this.dateDepot = dateDepot;
	}

	/**
	 * set employe name who generated deposit
	 * @param nomEmploye
	 */
	public void setNomEmploye(String nomEmploye) {
		this.nomEmploye = nomEmploye;
	}

	/**
	 * add new closing
	 * @param numeroFermeture as closing number
	 * @param dateFermeture as closing date
	 * @param nomEmploye as employe name who generated deposit
	 * @param argent as amount of money cash
	 * @param interac as amount of money interac
	 * @param cheque as amount of money by check
	 * @param amex as amount of money american express
	 * @param visa as amount of money visa
	 * @param mastercard as amount of money mastercard
	 * @param autres as amount of money from other source
	 * @return
	 */
	public boolean add(int numeroFermeture, Date dateFermeture, String nomEmploye,
			BigDecimal argent, BigDecimal interac, BigDecimal cheque,
			BigDecimal amex, BigDecimal visa, BigDecimal mastercard,
			BigDecimal autres) {
		return fermetureLst.add(new Row(numeroFermeture, dateFermeture, nomEmploye, argent, interac, cheque, amex, visa, mastercard, autres));
	}

	/*_______________________________________________________________________*/
	//test
	/*_______________________________________________________________________*/

	private static PDDocument test() throws IOException{
		RapportDepot rapport = new RapportDepot();
		
		rapport.setNomEmploye("MAURICE");
		rapport.setDateDepot(Date.valueOf("1999-02-02"));
		rapport.setNumeroDepot(12);
		
		for (int i=0;i<57;i++)
			rapport.add(13, Date.valueOf("1998-01-01"), "MAURICE", new BigDecimal("10.01"), BigDecimal.valueOf(10), BigDecimal.valueOf(10), BigDecimal.valueOf(10), BigDecimal.valueOf(10), BigDecimal.valueOf(10), BigDecimal.valueOf(10));
		
		rapport.generate();
		return rapport.getDocument();
	}
	
	public static void main(String ... args) throws IOException, COSVisitorException{
		PDDocument document = test();
		document.save("test.pdf");
		document.close();
	    File myFile = new File("test.pdf");
	    Desktop.getDesktop().open(myFile);
	}
}
