package com.rjconsultores.ventaboletos.relatorios.impl;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listhead;
import org.zkoss.zul.Listheader;

import com.rjconsultores.ventaboletos.web.utilerias.MyListbox;

import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRLineBox;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRMapCollectionDataSource;
import net.sf.jasperreports.engine.design.JRDesignBand;
import net.sf.jasperreports.engine.design.JRDesignConditionalStyle;
import net.sf.jasperreports.engine.design.JRDesignExpression;
import net.sf.jasperreports.engine.design.JRDesignField;
import net.sf.jasperreports.engine.design.JRDesignLine;
import net.sf.jasperreports.engine.design.JRDesignSection;
import net.sf.jasperreports.engine.design.JRDesignStaticText;
import net.sf.jasperreports.engine.design.JRDesignStyle;
import net.sf.jasperreports.engine.design.JRDesignTextField;
import net.sf.jasperreports.engine.design.JRDesignVariable;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.export.JExcelApiExporter;
import net.sf.jasperreports.engine.export.JExcelApiExporterParameter;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRPdfExporterParameter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
import net.sf.jasperreports.engine.type.HorizontalAlignEnum;
import net.sf.jasperreports.engine.type.VerticalAlignEnum;
import net.sf.jasperreports.engine.type.WhenNoDataTypeEnum;

public class RelatorioInformeViajesOcasionalesPdf {
	
//	private static Logger log = LogManager.getLogger(RelatorioDispositivoEmbarcada.class);
	public MyListbox viajeExpresosList;
	
	public RelatorioInformeViajesOcasionalesPdf(final MyListbox expresosList) throws Exception {
		this.viajeExpresosList = expresosList;
		
	}

	public File generateReport(boolean isPdf) throws JRException, IOException {

		System.setProperty("jasper.reports.compile.class.path", System.getProperty("java.io.tmpdir"));

		JasperDesign jasperDesign = createDesign();
		JasperReport jasperReport = JasperCompileManager
				.compileReport(jasperDesign);

		File file = null;

		JRDataSource jrDataSource = prepareDataSource();
		Map<String, Object> params = new HashMap<String, Object>();

		JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,
				params, jrDataSource);

		if (isPdf) {
			file = File.createTempFile("pdf", ".pdf");

			if (!file.exists()) {
				file.mkdir();
				file.setWritable(true);
			}

			JRPdfExporter exporter = new JRPdfExporter();
			exporter.setParameter(JRPdfExporterParameter.JASPER_PRINT, jasperPrint);
			exporter.setParameter(JRPdfExporterParameter.OUTPUT_FILE_NAME, file.getPath());
			exporter.exportReport();
		} else {
			file = File.createTempFile("xlsx", ".xlsx");

			if (!file.exists()) {
				file.mkdir();
				file.setWritable(true);
			}

			JRXlsxExporter exporter = new JRXlsxExporter();
			exporter.setParameter(JRXlsExporterParameter.JASPER_PRINT, jasperPrint);
			exporter.setParameter(JRXlsExporterParameter.OUTPUT_FILE_NAME, file.getPath());
			exporter.exportReport();
		}
		return file;

	}
	
	public byte[] generateReportRender(boolean isPdf) throws Exception {
		
		System.setProperty("jasper.reports.compile.class.path", System.getProperty("java.io.tmpdir"));
		System.setProperty("net.sf.jasperreports.compiler.temp.dir", System.getProperty("java.io.tmpdir"));

		JasperDesign jasperDesign = createDesign();
		JasperReport jasperReport = JasperCompileManager
				.compileReport(jasperDesign);

		byte[] conteudo = null;

		JRDataSource jrDataSource = prepareDataSource();
		Map<String, Object> params = new HashMap<String, Object>();

		JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,
				params, jrDataSource);

		if (isPdf) {
			conteudo = this.renderPdf(jasperPrint);
		} else {
			conteudo = this.renderXls(false, jasperPrint);
		}
		return conteudo;

	}
	
	private JRDataSource prepareDataSource() {
		List<Map<String, ?>> preparedData = new ArrayList<Map<String, ?>>();
		Map<String, Object> map;
		map = new HashMap<String, Object>();
		Boolean isValid = viajeExpresosList.getPaginal() != null;
		Integer paginaActual = isValid ? viajeExpresosList.getPaginal().getActivePage() : null; 
		
		if (isValid) {
            for (int i = 0; i < viajeExpresosList.getPaginal().getPageCount(); i++) {
            	viajeExpresosList.getPaginal().setActivePage(i);
            	viajeExpresosList.renderAll();
            }
        }
		
		for (Integer i = 0; i < viajeExpresosList.getSize(); i++) {
			List list = viajeExpresosList.getItemAtIndex(i).getChildren();
			
			map = new HashMap<String, Object>();
			for (Integer j = 0; j < list.size(); j++) {
				Listcell linha = (Listcell) list.get(j);
				map.put(j.toString(),linha.getLabel());
			}
			preparedData.add(map);
		}
		
		if (isValid && paginaActual != null) {
			viajeExpresosList.getPaginal().setActivePage(paginaActual);
        }
		
		return new JRMapCollectionDataSource(preparedData);
	}
	
	public JasperDesign createDesign() throws JRException {

		JRDesignStaticText staticText = null;

		JRDesignTextField textField = null;

		JRDesignBand band = null;

		JRDesignExpression expression = null;

		@SuppressWarnings("unused")
		JRDesignLine line = null;

		JRDesignField field = null;

		@SuppressWarnings("unused")
		JRDesignConditionalStyle conditionalStyle = null;

		JRLineBox lineBox = null;

		JRDesignVariable variable = null;

		int x;
		int y;
		final int ROW_HEIGHT = 15;
		final int COLUMN_WIDTH = 90;

		JasperDesign jasperDesign = new JasperDesign();
		jasperDesign.setName("Aba 1");
		jasperDesign.setPageWidth(2000);
		jasperDesign.setPageHeight(800);
		jasperDesign.setColumnWidth(COLUMN_WIDTH);
		jasperDesign.setColumnSpacing(0);
		jasperDesign.setLeftMargin(40);
		jasperDesign.setRightMargin(40);
		jasperDesign.setTopMargin(40);
		jasperDesign.setBottomMargin(40);
		jasperDesign.setIgnorePagination(true);
		jasperDesign.setWhenNoDataType(WhenNoDataTypeEnum.ALL_SECTIONS_NO_DETAIL);

		JRDesignStyle normalStyle = new JRDesignStyle();
		normalStyle.setName("normal");
		normalStyle.setDefault(true);
		normalStyle.setFontName("SansSerif");
		normalStyle.setFontSize((int) 7.5f);
		lineBox = normalStyle.getLineBox();
		lineBox.getTopPen().setLineWidth(0.5f);
		lineBox.getRightPen().setLineWidth(0.5f);
		lineBox.getBottomPen().setLineWidth(0.5f);
		lineBox.getLeftPen().setLineWidth(0.5f);
		jasperDesign.addStyle(normalStyle);

		JRDesignStyle headerStyle = new JRDesignStyle();
		headerStyle.setName("header");
		headerStyle.setDefault(true);
		headerStyle.setFontName("SansSerif");
		headerStyle.setFontSize((int) 8.5f);
		headerStyle.setBold(true);
		lineBox = headerStyle.getLineBox();
		lineBox.getTopPen().setLineWidth(0.5f);
		lineBox.getRightPen().setLineWidth(0.5f);
		lineBox.getBottomPen().setLineWidth(0.5f);
		lineBox.getLeftPen().setLineWidth(0.5f);
		jasperDesign.addStyle(headerStyle);

		for (Integer i = 0; i < viajeExpresosList.getItemAtIndex(0).getChildren().size(); i++) {
			field = new JRDesignField();
			field.setName(i.toString());
			field.setValueClass(java.lang.String.class);
			jasperDesign.addField(field);
		}

		band = new JRDesignBand();

		jasperDesign.setTitle(band);

		x = 0;
		y = 0;
		band = new JRDesignBand();
		band.setHeight(ROW_HEIGHT);
		
		Listhead listHead =  (Listhead) viajeExpresosList.getHeads().iterator().next();
		for (Iterator iterator = listHead.getChildren().iterator(); iterator.hasNext();) {
			Listheader child = (Listheader) iterator.next();
			staticText = montaHeader(x, y, ROW_HEIGHT, COLUMN_WIDTH, headerStyle, child.getLabel());
			staticText.setVerticalAlignment(VerticalAlignEnum.JUSTIFIED);
			band.addElement(staticText);
			x += staticText.getWidth();
		}
		
		jasperDesign.setColumnHeader(band);


		band = new JRDesignBand();
		band.setHeight(ROW_HEIGHT);
		x = 0;
		y = 0;
		
		
		
		for (Integer i = 0; i < viajeExpresosList.getItemAtIndex(0).getChildren().size(); i++) {

			textField = new JRDesignTextField();
			textField.setX(x);
			textField.setY(y);
			textField.setWidth(COLUMN_WIDTH);
			textField.setHeight(ROW_HEIGHT);
			textField.setStretchWithOverflow(true);
			textField.setHorizontalAlignment(HorizontalAlignEnum.CENTER);
			textField.setVerticalAlignment(VerticalAlignEnum.MIDDLE);
			expression = new JRDesignExpression();
			expression.setText("$F{" + i.toString() + "}");
			textField.setExpression(expression);
			textField.setStyle(normalStyle);
			band.addElement(textField);
			x += textField.getWidth();
		}

		((JRDesignSection) jasperDesign.getDetailSection()).addBand(band);

		band = new JRDesignBand();
		jasperDesign.setColumnFooter(band);

		band = new JRDesignBand();
		jasperDesign.setPageFooter(band);

		return jasperDesign;
	}

	private static JRDesignStaticText montaHeader(int x, int y, final int ROW_HEIGHT, final int COLUMN_WIDTH, JRDesignStyle headerStyle, String nomeColuna) {
		JRDesignStaticText staticText;
		staticText = new JRDesignStaticText();
		staticText.setX(x);
		staticText.setY(y);
		staticText.setWidth(COLUMN_WIDTH);
		staticText.setHeight(ROW_HEIGHT);
		staticText.setHorizontalAlignment(HorizontalAlignEnum.CENTER);
		staticText.setStyle(headerStyle);
		staticText.setText(nomeColuna);
		return staticText;
	}
	
	
	private byte[] renderXls(boolean isCustomXls, JasperPrint jasperPrint) throws Exception {
		JExcelApiExporter exporterXLS = new JExcelApiExporter();
		ByteArrayOutputStream output = new ByteArrayOutputStream();

		// As duas propriedades são para quando o arquivo xls chegar no máximo de linhas pular para a próxima aba do arquivo mantis #11294
		exporterXLS.setParameter(JExcelApiExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.TRUE);
		exporterXLS.setParameter(JExcelApiExporterParameter.MAXIMUM_ROWS_PER_SHEET, 65500);

		exporterXLS.setParameter(JExcelApiExporterParameter.JASPER_PRINT, jasperPrint);
		exporterXLS.setParameter(JExcelApiExporterParameter.OUTPUT_STREAM, output);

		if (!isCustomXls) {
			exporterXLS.setParameter(JExcelApiExporterParameter.IS_ONE_PAGE_PER_SHEET, Boolean.FALSE);
			exporterXLS.setParameter(JExcelApiExporterParameter.IS_DETECT_CELL_TYPE, Boolean.TRUE);
			exporterXLS.setParameter(JExcelApiExporterParameter.IS_WHITE_PAGE_BACKGROUND, Boolean.FALSE);
			exporterXLS.setParameter(JExcelApiExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, Boolean.TRUE);
			exporterXLS.setParameter(JExcelApiExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_COLUMNS, Boolean.TRUE);
		}

		// collapseRowSpan
		// JRXlsExporterParameter.
		exporterXLS.exportReport();
		return output.toByteArray();
	}

	private byte[] renderPdf(JasperPrint jasperPrint) throws Exception {
		return JasperExportManager.exportReportToPdf(jasperPrint);
	}
	
}
