package de.superx.servlet;

import java.math.BigDecimal;
import java.sql.Date;
import java.text.ParseException;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;

import de.memtext.util.DateUtils;
import de.superx.common.Field;
import de.superx.common.Maske;
import de.superx.common.SxResultRow;
import de.superx.common.SxUser;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JRField;

public class SxJasperDataSource implements JRDataSource {
	private Maske maske;
	private String mandantenID;
	private int index = -1;
	private List headerCaptions;
	private Iterator it;
	private SxResultRow row;
	private SxUser user;
	private Locale desiredLocale;
	private static final String captionIds[] = { "REPORT_HEADING_INSTITUTION",
			"REPORT_HEADING_URL", "REPORT_LOGO_FILE", "REPORT_HEADING_ADRESS",
			"REPORT_EMAIL", "REPORT_DOCUMENTATION_URL"

	};

	SxJasperDataSource(String mandantenID,Locale desiredLocale,SxUser user, Maske maske) {
		this.mandantenID=mandantenID;
		this.desiredLocale=desiredLocale;
		this.user = user;
		this.maske = maske;
		headerCaptions = maske.getHeaderCaptionList(mandantenID,true);
		it = maske.getResult_el().getResultSet().iterator();

	}

	/**
	 * seltsam, man muss Jasper vorgaukeln, dass noch ein weiterer Datensatz
	 * kommt, damit er ihn auch verarbeitet, wenn dann der scheinbar nächste
	 * nachdem letzten aufgerufen wird, verhindert ein if vor it.next das er in
	 * einen Fehler rennt
	 */
	public boolean next() throws JRException {
		index++;
		// System.out.println("line " + index + "   of " +
		// maske.getResult_el().getResultSet().size());
		if (it.hasNext())
			row = (SxResultRow) it.next();
		// System.out.println("Budgetstelle "+getVal("Budgetstelle"));

		return it.hasNext()
				|| index < maske.getResult_el().getResultSet().size();

	}

	/**
 * 
 */
	public Object getFieldValue(JRField field) throws JRException {
		Object value = null;

		String fieldName = field.getName();
		if (fieldName.equals("Berichtsname"))
			value = maske.getName();
		else if (fieldName.equalsIgnoreCase("Erlaeuterung"))
			value = maske.getExplanation();
		else if (fieldName.equalsIgnoreCase("Hinweis"))
			value = maske.getHinweisCaption();
		else if (fieldName.equalsIgnoreCase("standdatum"))
			value = maske.getStandString();
		else if (fieldName.equalsIgnoreCase("user"))
			value = user.getName();
		else if (fieldName.startsWith("legende_")
				&& fieldName.endsWith("_value"))
			value = getLegendFieldValue(fieldName);
		else if (fieldName.startsWith("legende_")
				&& fieldName.endsWith("_label"))
			value = getLegendFieldLabel(fieldName);
		else if (isSxCaptionsField(fieldName))
					value=getSxCaption(fieldName);
		
		else
			value = getVal(fieldName);

		if (value instanceof Short)
			value = new Integer(((Short) value).intValue());
		if (value instanceof BigDecimal)
			value = new Double(((BigDecimal) value).doubleValue());
		//Datumsobjekte als String Formatieren
		//DQ 14.1.2012: Problem bei Konvertierung im Servlet Betrieb, daher entfernen
	/* if (value instanceof java.util.Date)
		value =DateUtils.format((Date) value);
	if (value instanceof java.sql.Date)
		value =DateUtils.format((java.sql.Date) value);*/
		// System.out.println("returning "+value+" for "+fieldName		 +" row "+index);
	
		return value;
	}

	private String getSxCaption(String fieldName) {
		
		return SxPools.get(mandantenID).getTranslationShort(fieldName,desiredLocale);
		
	}

	private boolean isSxCaptionsField(String fieldName) {
		boolean result=false;
		for (int i=0;i<captionIds.length;i++)
		{
			if (fieldName.equals(captionIds[i]))
			{
				result=true;
				break;
			}
		}
		return result;
	}

	private int getColNo(String fieldName) {
		int col = -1;
		//System.out.println("Suche x"+fieldName+"x");
		for (int i = 0; i < headerCaptions.size(); i++) {
			if (headerCaptions.get(i).toString().equals(fieldName)) {
				col = i;
				break;
			}
		}
		return col;
	}

	private Object getVal(String fieldName) {
		Object result = null;
		int colno = getColNo(fieldName);
		if (colno > -1)
			result = row.get(colno);
		/*DQ 14.1.2012: Unnötige Fehlermeldung, einfach NULL zurückgeben:
		 * else
			throw new IllegalArgumentException("JasperReport-Feld " + fieldName
					+ " wurde nicht im Ergebnis der Maske gefunden");*/
		if (result != null && result.equals(""))
			result = null;
		return result;
	}

	private String getLegendFieldValue(String fieldName) {
		String result = "";
		int pos = fieldName.indexOf("_value");

		Field f = maske.getField(fieldName.substring(8, pos));
		// result = f.getSelectedKey();
		try {
			result = f.getSelectedKeyValueCaption();
		} catch (ParseException e) {
			e.printStackTrace();
			throw new IllegalArgumentException("Ungültiger wert für Feld "
					+ f.getName() + "(" + f.getSelectedKey() + ")");
		}
		if (result == null)
			System.out.println("Warnung: JasperReport-Legende-Wert "
					+ fieldName.substring(7, pos)
					+ " wurde nicht im Ergebnis der Maske gefunden");
		return result;
	}

	private String getLegendFieldLabel(String fieldName) {
		String result = "";
		int pos = fieldName.indexOf("_label");

		Field f = maske.getField(fieldName.substring(8, pos));

		result = f.getName();
		if (f.getCaptionShort() != null && !f.getCaptionShort().equals(""))
			result = f.getCaptionShort();
		if (result == null)
			System.out.println("Warnung: JasperReport-Legende-Label "
					+ fieldName.substring(7, pos)
					+ " wurde nicht im Ergebnis der Maske gefunden");
		return result;
	}

}