package net.sourceforge.jsurveyor;
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import java.io.*;

//from the iText package

import com.lowagie.text.*;
import com.lowagie.text.pdf.*;

/**
 * Most of the standard code is taking from an example that Sean C. Sullivan
 * made on this page:
 * http://www.onjava.com/pub/a/onjava/2003/06/18/dynamic_files.html This
 * converts the data from report into a pdf document.
 * 
 * @version 1.0
 * @author Claus Methmann Christensen
 * @author Anders Spliid Hansen
 * @author Esben Iversen Hansen
 * @author Lars H Jensen
 * @author Marcus Overheu
 * @author Thomas Ramdal
 * @author Peter Thomsen
 */

public class ReportOutput extends HttpServlet {

	/**
	 * Field questionnaireID
	 */
	private String questionnaireID = new String();
	/**
	 * This is the deafult constructor for ReportOutput
	 */
	public ReportOutput() {

	}

	/**
	 * The standard doGet is overwriten with a method that takes an
	 * questionnaireID as the HttpServletRequest req's parameter, and creates
	 * the necesary http output and conversions of bytedata.
	 * 
	 * @param req
	 *                    HttpServletRequest
	 * @param resp
	 *                    HttpServletResponse
	 * @throws ServletException
	 * @throws java.io.IOException
	 */
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
		throws ServletException, java.io.IOException {

		DocumentException ex = null;
		ByteArrayOutputStream reportPDF = null;
		this.questionnaireID = (String) req.getParameter("questionnaireID");

		/**
		 * Here the the method generatePDFDocument is called and the pdf
		 * document is given a name.
		 */

		try {
			reportPDF = generatePDFDocument(req, this.getServletContext());

			StringBuffer sbFilename = new StringBuffer();
			sbFilename.append("Report");
			sbFilename.append(".pdf");

			/**
			 * HTTP responds headers which takes care of http contenttype and
			 * the link to the file
			 */

			resp.setHeader("Cache-Control", "max-age=30");
			resp.setContentType("application/pdf");

			StringBuffer sbContentDispValue = new StringBuffer();
			sbContentDispValue.append("inline");
			sbContentDispValue.append("; filename=");
			sbContentDispValue.append(sbFilename);

			resp.setHeader(
				"Content-disposition",
				sbContentDispValue.toString());

			resp.setContentLength(reportPDF.size());

			ServletOutputStream sos;

			sos = resp.getOutputStream();

			reportPDF.writeTo(sos);

			sos.flush();

		} catch (DocumentException dex) {

			resp.setContentType("text/html");
			PrintWriter writer = resp.getWriter();
			writer.println(
				this.getClass().getName()
					+ " caught an exception: "
					+ dex.getClass().getName()
					+ "<br>");
			writer.println("<pre>");
			dex.printStackTrace(writer);
			writer.println("</pre>");

		} finally {
			if (reportPDF != null) {
				reportPDF.reset();
			}
		}
	}

	/**
	 * The method generates a pdf document, getting all data from report, and
	 * setting it up.
	 * 
	 * @param req
	 *                    HttpServletRequest
	 * @param ctx
	 *                    ServletContext
	 * @return ByteArrayOutputStream
	 * @throws DocumentException
	 */
	public ByteArrayOutputStream generatePDFDocument(
		final HttpServletRequest req,
		final ServletContext ctx)
		throws DocumentException {
		Document doc = new Document();
		Report tempReport = new Report();
		ByteArrayOutputStream reportPDF = new ByteArrayOutputStream();
		PdfWriter docWriter = null;
		/**
		 * Constructing the report from the inputtet questionnaireID
		 */
		try {
			tempReport = new Report(Integer.parseInt(questionnaireID));
		} catch (Exception e) {
			System.err.println(e);
		}

		/**
		 * Inputs and set's up the data in the document, taking data from the
		 * Report.
		 */
		try {
			docWriter = PdfWriter.getInstance(doc, reportPDF);
			doc.open();

			Paragraph questionnaireText =
				new Paragraph(
					" Report for " + tempReport.getQuestionnaireName(),
					new Font(Font.TIMES_ROMAN, 16, Font.BOLD));
			doc.add(questionnaireText);
			doc.add(
				new Paragraph(
					"\n"
						+ "  "
						+ tempReport.getQuestionnaireIntroText()
						+ "\n"
						+ "\n",
					new Font(Font.TIMES_ROMAN, 12, Font.BOLD)));
			int i;
			com.lowagie.text.List index = new com.lowagie.text.List(false, 10);
			doc.add(new Paragraph("\n" + "Question with choices"));

			for (i = 0;
				i < tempReport.getInnerAnswerMultipleChoiceSize();
				i++) {

				index.add(
					new ListItem(
						""
							+ tempReport
								.getInnerAnswerMultipleChoiceQuestionText(
								i)));
			}

			doc.add(new Paragraph("\n" + "Question with text answers "));
			for (i = 0; i < tempReport.getInnerFreeTextSize(); i++) {
				index.add(
					new ListItem(
						tempReport.getInnerQuestionFreeText(i) + "\n"));
			}
			doc.add(index);
			for (i = 0;
				i < tempReport.getInnerAnswerMultipleChoiceSize();
				i++) {
				String[] questionsChoices =
					tempReport.getInnerAnswerMultipleChoiceText(i);
				Paragraph questionText =
					new Paragraph(
						tempReport.getInnerAnswerMultipleChoiceQuestionText(i),
						new Font(Font.TIMES_ROMAN, 12, Font.BOLD));
				int NumColumns = 5;
				PdfPTable questionTable = new PdfPTable(NumColumns);
				questionTable.getDefaultCell().setBorderWidth(2);
				questionTable.getDefaultCell().setHorizontalAlignment(
					Element.ALIGN_CENTER);

				for (int h = 0; h < questionsChoices.length; h++) {
					questionTable.addCell(questionsChoices[h]);
				}
				int[] answers =
					tempReport.getInnerAnswerMultipleChoiceDistribution(i);
				for (int j = 0;
					j
						< tempReport.getInnerAnswerMultipleChoiceDistribution(
							i).length;
					j++) {

					questionTable.addCell("" + answers[j]);

				}

				doc.add(questionText);
				doc.add(questionTable);

			}

			for (i = 0; i < tempReport.getInnerFreeTextSize(); i++) {
				doc.add(
					new Paragraph(
						tempReport.getInnerQuestionFreeText(i),
						new Font(Font.TIMES_ROMAN, 16, Font.BOLD)));
				String answerStrings[] = tempReport.getInnerAnswerText(i);
				String userStrings[] = tempReport.getInnerUserText(i);
				for (int j = 0;
					j < tempReport.getInnerAnswerText(i).length;
					j++) {
					doc.add(new Paragraph("USER: " + userStrings[j] + " \n"));
					doc.add(new Paragraph(answerStrings[j]));
				}
			}
			doc.close();

		} catch (DocumentException dex) {
			reportPDF.reset();
			throw dex;
		} finally {
			if (doc != null) {
				doc.close();
			}
			if (docWriter != null) {
				docWriter.close();
			}
		}
		if (reportPDF.size() < 1) {
			throw new DocumentException(
				"document has " + reportPDF.size() + " bytes");
		}
		return reportPDF;
	}
}