package rapport;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Date;
import java.text.DecimalFormat;
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;

/**
 * closing report generator
 * @author martin
 *
 */
public class RapportFermeture extends RapportLandscape{
	private static class Row{
		public int numeroFacture;
		public String numeroChambreOuNomGroupe;
		public BigDecimal soustotal;
		public BigDecimal tps;
		public BigDecimal tvq;
		public BigDecimal total;
		public BigDecimal argent;
		public BigDecimal interac;
		public BigDecimal cheque;
		public BigDecimal amex;
		public BigDecimal visa;
		public BigDecimal mastercard;
		public BigDecimal autres;
		private Row(int numeroFacture, String numeroChambreOuNomGroupe,
				BigDecimal soustotal, BigDecimal tps, BigDecimal tvq,
				BigDecimal total, BigDecimal argent, BigDecimal interac,
				BigDecimal cheque, BigDecimal amex, BigDecimal visa,
				BigDecimal mastercard, BigDecimal autres) {
			super();
			this.numeroFacture = numeroFacture;
			this.numeroChambreOuNomGroupe = numeroChambreOuNomGroupe;
			this.soustotal = soustotal;
			this.tps = tps;
			this.tvq = tvq;
			this.total = total;
			this.argent = argent;
			this.interac = interac;
			this.cheque = cheque;
			this.amex = amex;
			this.visa = visa;
			this.mastercard = mastercard;
			this.autres = autres;
		}
	};
	
	private int numeroFermeture;
	private Date dateFermeture;
	private String nomEmploye;
	public Date dateGenerer;
	private List<Row> factureLst;

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

	@Override
	public int countPage(){
		return factureLst.size()/30 + (factureLst.size()%30==0?0:1);
	}
	
	@Override
	public void firstPageHeader() throws IOException{
		//date
		addTextLeftAlign("Date", font, 12, 75, 125,15);
		addTextLeftAlign(dateFermeture.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("Fermeture", bold, 24, getW()/2, 50);
		addTextInBox(""+numeroFermeture, 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 = factureLst.size()/30;
		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),
				   total = BigDecimal.valueOf(0),
				   tps = BigDecimal.valueOf(0),
				   tvq = BigDecimal.valueOf(0),
				   soustotal = BigDecimal.valueOf(0);
		for (Row row : factureLst){
			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);
			soustotal = soustotal.add(row.soustotal);
			tvq = tvq.add(row.tvq);
			tps = tps.add(row.tps);
			total = total.add(row.total);
		}
		DecimalFormat format = new DecimalFormat("0.00");
		
		addSeparator(getH()-42);
		addTextRightAlign("Total", bold, 12, 110, getH()-36, 5);
		addTextInBox(format.format(soustotal)+"$", bold, 10, getW()-610, getH()-36, 10);
		addTextInBox(format.format(tps)+"$", bold, 10, getW()-550, getH()-36, 10);
		addTextInBox(format.format(tvq)+"$", bold, 10, getW()-500, getH()-36, 10);
		addTextInBox(format.format(total)+"$", bold, 10, getW()-450, getH()-36, 10);
		addTextInBox(format.format(argent)+"$", bold, 10, getW()-390, getH()-36, 10);
		addTextInBox(format.format(interac)+"$", bold, 10, getW()-330, getH()-36, 10);
		addTextInBox(format.format(cheque)+"$", bold, 10, getW()-270, getH()-36, 10);
		addTextInBox(format.format(amex)+"$", bold, 10, getW()-210, getH()-36, 10);
		addTextInBox(format.format(visa)+"$", bold, 10, getW()-150, getH()-36, 10);
		addTextInBox(format.format(mastercard)+"$", bold, 10, getW()-90, getH()-36, 10);
		addTextInBox(format.format(autre)+"$", bold, 10, getW()-30, getH()-36, 10);
	}

	@Override
	public void body() throws IOException{
		
		DecimalFormat format = new DecimalFormat("0.00");
		
		//colname
		addSeparator(200);
		addText("Facture", bold, 12, 35, 188);
		addText("ChmbrGrp", bold, 12, 110, 188);
		addText("Sout-total", bold, 12, getW()-610, 188);
		addText("TPS", bold, 12, getW()-550, 188);
		addText("TVQ", bold, 12, getW()-500, 188);
		addText("Total", bold, 12, getW()-450, 188);
		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 = 30<factureLst.size()-cursor?30:factureLst.size()-cursor;
		for (int y = 0; y < max; y++){
			addText(""+factureLst.get(cursor+y).numeroFacture, bold, 12, 35, 208+y*12);
			
			addText(format.format(factureLst.get(cursor+y).soustotal)+"$", bold, 12, getW()-610, 208+y*12);
			addText(format.format(factureLst.get(cursor+y).tps)+"$", bold, 12, getW()-550, 208+y*12);
			addText(format.format(factureLst.get(cursor+y).tvq)+"$", bold, 12, getW()-500, 208+y*12);
			addText(format.format(factureLst.get(cursor+y).total)+"$", bold, 12, getW()-450, 208+y*12);
			
			addText(format.format(factureLst.get(cursor+y).argent)+"$", bold, 12, getW()-390, 208+y*12);
			addText(format.format(factureLst.get(cursor+y).interac)+"$", bold, 12, getW()-330, 208+y*12);
			addText(format.format(factureLst.get(cursor+y).cheque)+"$", bold, 12, getW()-270, 208+y*12);
			addText(format.format(factureLst.get(cursor+y).amex)+"$", bold, 12, getW()-210, 208+y*12);
			addText(format.format(factureLst.get(cursor+y).visa)+"$", bold, 12, getW()-150, 208+y*12);
			addText(format.format(factureLst.get(cursor+y).mastercard)+"$", bold, 12, getW()-90, 208+y*12);
			addText(format.format(factureLst.get(cursor+y).autres)+"$", bold, 12, getW()-30, 208+y*12);
		}
	}
	
	@Override
	public void generate() throws IOException{
		boolean lastpage = false;
		firstPageHeader();
		while(!lastpage){
			header();
			body();
			footer();
			cursor += 30;
			lastpage = factureLst.size() <= cursor;
			if (!lastpage)
				nextPage();
		}
		lastPageFooter();
	}
	
	/*_______________________________________________________________________*/
	//data
	/*_______________________________________________________________________*/

	/**
	 * set closing number
	 * @param numeroFermeture
	 */
	public void setNumeroFermeture(int numeroFermeture) {
		this.numeroFermeture = numeroFermeture;
	}

	/**
	 * set closing date
	 * @param dateFermeture
	 */
	public void setDateFermeture(Date dateFermeture) {
		this.dateFermeture = dateFermeture;
	}

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

	/**
	 * add new bill to the closing
	 * @param numeroFacture				as int
	 * @param numeroChambreOuNomGroupe  as string
	 * @param soustotal					as bigdecimal
	 * @param tps						as bigdecimal
	 * @param tvq as bigdecimal
	 * @param total as bigdecimal
	 * @param argent as bigdecimal
	 * @param interac as bigdecimal
	 * @param cheque as bigdecimal
	 * @param amex as bigdecimal
	 * @param visa as bigdecimal
	 * @param mastercard as bigdecimal
	 * @param autres as bigdecimal
	 * @return
	 */
	public boolean add(int numeroFacture, String numeroChambreOuNomGroupe,
			BigDecimal soustotal, BigDecimal tps, BigDecimal tvq,
			BigDecimal total, BigDecimal argent, BigDecimal interac,
			BigDecimal cheque, BigDecimal amex, BigDecimal visa,
			BigDecimal mastercard, BigDecimal autres) {
		return factureLst.add(new Row(numeroFacture, 
				                      numeroChambreOuNomGroupe, 
				                      soustotal, 
				                      tps, 
				                      tvq, 
				                      total, 
				                      argent, 
				                      interac, 
				                      cheque, 
				                      amex, 
				                      visa, 
				                      mastercard, 
				                      autres));
	}

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

	private static PDDocument test() throws IOException{
		RapportFermeture rapport = new RapportFermeture();
		
		rapport.setNomEmploye("MAURICE");
		rapport.setDateFermeture(Date.valueOf("1999-02-02"));
		rapport.setNumeroFermeture(12);
		
		for (int i=0;i<60;i++)
			rapport.add(13, 
					    "ChienEtChat", 
					    new BigDecimal("0"), new BigDecimal("0"), new BigDecimal("0"), new BigDecimal("0"), 
					    new BigDecimal("0"), new BigDecimal("0"), new BigDecimal("0"), 
					    new BigDecimal("0"), new BigDecimal("0"), new BigDecimal("0"), new BigDecimal("0"));
		
		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);
	}
}
