/**
 * 
 */
package it.mice.voila.runtime.jasper.view;

import it.mice.voila.runtime.jasper.JasperReportDefinition;
import it.mice.voila.runtime.jasper.view.helpers.AbstractJasperReportsView;
import it.mice.voila.runtime.jasper.view.helpers.JasperReportsCsvView;
import it.mice.voila.runtime.jasper.view.helpers.JasperReportsPdfView;
import it.mice.voila.runtime.jasper.view.helpers.JasperReportsXlsView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import net.sf.jasperreports.engine.JRExporterParameter;
import net.sf.jasperreports.engine.JasperPrint;

import org.springframework.context.ApplicationContext;
import org.springframework.web.servlet.support.RequestContext;
//import org.springframework.web.servlet.view.jasperreports.AbstractJasperReportsView;
//import org.springframework.web.servlet.view.jasperreports.JasperReportsCsvView;
//import org.springframework.web.servlet.view.jasperreports.JasperReportsMultiFormatView;
//import org.springframework.web.servlet.view.jasperreports.JasperReportsPdfView;
//import org.springframework.web.servlet.view.jasperreports.JasperReportsXlsView;

/**
 *
 */
public class JasperReportDefinitionAdapterView extends JasperReportsMultiFormatView {
	/**
	 * Costruttore di classe.
	 */
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public JasperReportDefinitionAdapterView() {
		Map formatMappings = new HashMap<String, Class<? extends AbstractJasperReportsView>>(5);
		formatMappings.put("csv", JasperReportsCsvView.class);
		formatMappings.put("html", JasperReportsHtmlView.class);
		formatMappings.put("pdf", JasperReportsPdfView.class);
		formatMappings.put("xls", JasperReportsXlsView.class);
		formatMappings.put("rtf", JasperReportsRtfView.class);
		setFormatMappings(formatMappings);
	}

	/**
	 * Stores the headers to written with each response
	 */
	private Properties headers;

	/**
	 * Stores the headers to written with each response
	 */
	private JasperReportDefinition reportDefinition;

	/**
	 * Getter per la proprietà reportDefinition.
	 * @return la proprietà reportDefinition
	 */
	public JasperReportDefinition getReportDefinition() {
		return reportDefinition;
	}

	/**
	 * Setter per la proprietà reportDefinition.
	 * @param reportDefinition la proprietà reportDefinition da settare
	 */
	public void setReportDefinition(JasperReportDefinition reportDefinition) {
		this.reportDefinition = reportDefinition;
	}

	/** {@inheritDoc}
	 * @see org.springframework.web.context.support.WebApplicationObjectSupport#initApplicationContext(org.springframework.context.ApplicationContext)
	 */
	@Override
	protected void initApplicationContext(ApplicationContext context) {

		if (this.headers == null) {
			this.headers = new Properties();
		}
		if (!this.headers.containsKey(HEADER_CONTENT_DISPOSITION)) {
			this.headers.setProperty(HEADER_CONTENT_DISPOSITION, CONTENT_DISPOSITION_INLINE);
		}

		setFormatKey(getReportDefinition().getFormatKey());
		
		onInit();
	}

	/**
	 * Finds the report data to use for rendering the report and then invokes the
	 * {@link #renderReport} method that should be implemented by the subclass.
	 * @param model the model map, as passed in for view rendering. Must contain
	 * a report data value that can be converted to a <code>JRDataSource</code>,
	 * acccording to the rules of the {@link #fillReport} method.
	 */
	@Override
	protected void renderMergedOutputModel(
			Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {

		RequestContext rc = new RequestContext(request, getServletContext());
		// Prepare response and render report.
		
		JasperPrint filledReport = reportDefinition.preparePrintReport(model, rc.getLocale(), rc.getMessageSource());
		
		populateHeaders(response);
		renderReport(filledReport, model, response);
	}

	/** {@inheritDoc}
	 * @see it.mice.voila.runtime.jasper.view.helpers.AbstractJasperReportsView.AbstractJasperReportsView#getExporterParameters()
	 */
	@Override
	public Map<?, ?> getExporterParameters() {
		return reportDefinition.getExporterParameters();
	}

	/** {@inheritDoc}
	 * @see it.mice.voila.runtime.jasper.view.helpers.AbstractJasperReportsView.AbstractJasperReportsView#getConvertedExporterParameters()
	 */
	@Override
	protected Map<JRExporterParameter, Object> getConvertedExporterParameters() {
		return reportDefinition.getConvertedExporterParameters();
	}

	/**
	 * Populates the headers in the <code>HttpServletResponse</code> with the
	 * headers supplied by the user.
	 */
	private void populateHeaders(HttpServletResponse response) {
		// Apply the headers to the response.
		for (Enumeration en = this.headers.propertyNames(); en.hasMoreElements();) {
			String key = (String) en.nextElement();
			response.addHeader(key, this.headers.getProperty(key));
		}
	}
	
}
