/*
 * Created on 2005.06.01.
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package com.etixpert.evolution;

/**
 * @author aintitfun
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
import java.math.BigDecimal;
import java.sql.Connection;
import java.text.DateFormat;
import java.util.*;
import com.etixpert.evolution.*;
import com.etixpert.evolution.gui.servlets.FormHelper;

import org.apache.log4j.*;

import javax.servlet.jsp.jstl.fmt.*;


public class SuperPO {
	PersistableObject po;
	Map main = new HashMap();
	String tableName;
	String[] needNames;
	String[] needTypes;
	String[] keys;
	Logger logger;
	
	public Map getMain() {
		return main;
	}
	
	public SuperPO(String tableName, Logger logger) throws Exception {
		this.tableName = tableName;
		if (!TableConstant.tableInfos.containsKey(tableName)) throw new Exception("TableInfo missing!");
		TableInfo ti = (TableInfo)TableConstant.tableInfos.get(tableName);
		needNames = ti.getNeedNames();
		needTypes = ti.getNeedTypes();
		keys = ti.getKeys();
		this.logger = logger;
		setBooleanValues();
	}
	
	private int checkColumn(String column) {
		for (int i = 0; i<needNames.length; i++) {
			if (needNames[i].equals(column)) return i;
		}
		return -1;
	}
	
	
	public void setColumn(String columnName, String value) throws Exception {
		int columnIndex;
		if ((columnIndex=checkColumn(columnName))==-1) return;
		Object valueObj = null;
		if (!value.trim().equals(""))
			valueObj = convertString2Obj(columnName, columnIndex, value);
		else if ("".equals(value) && (columnName.equals("inventory") || columnName.equals("minimum_inventory")))
			valueObj = new Integer(0);
		else if ("".equals(value) && (columnName.equals("order_price")))
			valueObj = new Double(0);
		main.put(columnName, valueObj);
	}
	
	public void setPOColumn(String column, Object value) throws Exception {
	    main.put(column, value);
	}
	
	public Object getPOColumn(String column) {
	    return main.get(column);
	}
	public String getColumn(String columnName) throws Exception {
		int columnIndex = checkColumn(columnName);
		if (columnIndex==-1) throw new EvolutionException("This columnname is invalid for (table, column) : ("+tableName+", "+columnName+")");
		
		String type = needTypes[columnIndex];		
		String ret = convertObj2String(columnIndex, main.get(columnName));
		return ret;
	}
	
	public void setMain(Map m) {
		main = m;
		setBooleanValues();
	}
	
	public Map getCheckedTextMap() throws Exception{
		Map textMap  = new Hashtable();
		logger.info("textMap");
		Set keys = main.keySet();
		Iterator it = keys.iterator();
		while (it.hasNext()) {
			String actualName = (String)it.next();
			Object value = main.get(actualName);
			String textValue = getColumn(actualName);
			logger.info(actualName+":"+textValue);
			if (textValue!=null) {
				if (textValue.indexOf("\"")!=-1) {
					textValue = textValue.replaceAll("\"", "&quot;");
				}
				textMap.put(actualName, new String[] {textValue});
			}
		}
		
		return textMap;
	}	
	
	public Map getTextMap() throws Exception{
		Map textMap  = new Hashtable();
		logger.info("textMap");
		Set keys = main.keySet();
		Iterator it = keys.iterator();
		while (it.hasNext()) {
			String actualName = (String)it.next();
			Object value = main.get(actualName);
			String textValue = getColumn(actualName);
			logger.info(actualName+":"+textValue);
			if (textValue!=null)
				textMap.put(actualName, new String[] {textValue});
		}
		
		return textMap;
	
	}
	
	public void addMap(Map toAdd) throws Exception {
		if (toAdd == null) return;
		Set keys = toAdd.keySet();
		Iterator it = keys.iterator();
		while (it.hasNext()) {			
			String actualName = (String)it.next();
			String value;
			if (toAdd.get(actualName) instanceof String[])
				value = ((String[])toAdd.get(actualName))[0];
			else
				value = (String)toAdd.get(actualName);
			logger.info("setting column: "+actualName+": "+value);
			setColumn(actualName, value);
		}
	}

	public void setBooleanValues() {
		for (int i=0; i<needTypes.length; i++)
			if (needTypes[i].equals("boolean") && main.get(needNames[i])==null)
				main.put(needNames[i], new Boolean(false));
	}
	
	public void update() throws Exception {
		PersistableObject po = new PersistableObject(tableName, keys, main);
		try {
			po.update();
		} catch (Exception e) {
			
			throw new EvolutionException("Database error: "+e.getMessage());
		}
	}
	
	public void update (java.sql.Connection conn) throws Exception {
		PersistableObject po = new PersistableObject(tableName, keys, main);
		try {
			po.update(conn);
		} catch (Exception e) {
			throw new EvolutionException("Database error: "+e.getMessage());
		}		
	}
	
	public void delete() throws Exception {
		PersistableObject po = new PersistableObject(tableName, keys, main);
		po.setLogger(logger);
		try {
			po.delete();
		} catch (Exception e) {
			throw new EvolutionException("Database error: "+e.getMessage());
		}
	}
	
	public void delete (java.sql.Connection conn) throws Exception {
		PersistableObject po = new PersistableObject(tableName, keys, main);
		try {
			po.delete(conn);
		} catch (Exception e) {
			throw new EvolutionException("Database error: "+e.getMessage());
		}		
	}

	
	public void insert() throws Exception {
		PersistableObject po = new PersistableObject(tableName, keys, main);
		try {
			po.insert();
		} catch (Exception e) {
			throw new EvolutionException("Database error: "+e.getMessage());
		}
	}
	
	public void insert (java.sql.Connection conn) throws Exception {
		PersistableObject po = new PersistableObject(tableName, keys, main);
		try {
			po.insert(conn);
		} catch (Exception e) {
			throw new EvolutionException("Database error: "+e.getMessage());
		}		
	}

	public Map load() throws Exception {
		PersistableObject po = new PersistableObject(tableName, keys, main);
		try {
			po.load();
			main = po.getValues();
			return getTextMap();
		} catch (Exception e) {
			throw new EvolutionException("Database error: "+e.getMessage());
		}		
	}
	
	public Map load(java.sql.Connection conn) throws Exception {
		PersistableObject po = new PersistableObject(tableName, keys, main);
		try {
			po.load(conn);
			main = po.getValues();
			return getTextMap();
		} catch (Exception e) {
			throw new EvolutionException("Database error: "+e.getMessage());
		}		
	}

	private Object convertString2Obj(String columnName, int columnIndex, String value) throws Exception {
		String type = needTypes[columnIndex];
		if (type.equals("string")) {
			if (value.trim().equals("")) return null;
			else return value;
		} else if ("numeric".equals(type)) {
			BigDecimal bd;
			try {	
				bd = new BigDecimal(value);
			} catch (Exception e) {
				String plus = "";
				if (value.indexOf(",")!=-1)
				plus = "<br>Komma bitte als Punkt eingeben!";
				throw new EvolutionException("Zahlenformat ist nicht korrekt: "+needNames[columnIndex]+": "+value+plus);			
			}
			return bd;
		}
		else if ("boolean".equals(type)) {
			return new Boolean(true);
		}
		else if ("integer".equals(type)) {
			int i;
			try {
				i = Integer.parseInt(value);
			} catch (NumberFormatException nfe) {
				String plus = "";
				if (value.indexOf(",")!=-1)
				plus = "<br>Komma bitte als Punkt eingeben!";
				throw new EvolutionException("Zahlenformat ist nicht korrekt: "+needNames[columnIndex]+": "+value+plus);			
			}
			return new Integer(i);
		} else if ("long".equals(type)) {
			long i;
			try {
				i = Long.parseLong(value);
			} catch (NumberFormatException nfe) {
				String plus = "";
				if (value.indexOf(",")!=-1)
				plus = "<br>Komma bitte als Punkt eingeben!";
				throw new EvolutionException("Zahlenformat ist nicht korrekt: "+needNames[columnIndex]+": "+value+plus);			
			}
			return new Long(i);
		}else if ("double".equals(type)) {
			double i;
			try {
				i = Double.parseDouble(value);
			} catch (NumberFormatException nfe) {
				String plus = "";
				if (value.indexOf(",")!=-1)
				plus = "<br>Komma bitte als Punkt eingeben!";
				throw new EvolutionException("Zahlenformat ist nicht korrekt: "+needNames[columnIndex]+": "+value+plus);			
			}
			return new Double(i);
		}else if ("float".equals(type)) {
			float i;
			try {
				i = Float.parseFloat(value);
			} catch (NumberFormatException nfe) {
				String plus = "";
				if (value.indexOf(",")!=-1)
				plus = "<br>Komma bitte als Punkt eingeben!";
				throw new EvolutionException("Zahlenformat ist nicht korrekt: "+needNames[columnIndex]+": "+value+plus);			
			}
			return new Float(i);
		}
		else if ("date".equals(type)) {
			java.sql.Date date;
			DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.GERMAN);
			try {
				java.util.Date d = df.parse(value);
				date = new java.sql.Date(d.getTime());
			} catch (Exception e) {
				//this should be impossible
				throw new EvolutionException("Date format is not valid: "+needNames[columnIndex]+". "+value);
				}
			return date; 
		} else if ("bonusdate".equals(type)) {
			java.sql.Date date;
			DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.GERMAN);
			String value2 = "";
			try {
				String year = value.substring(0,4);
				String month = value.substring(4);
				String day = "01";
				
				if ("valid_to".equals(columnName))
					day = FormHelper.months_last_days[new Integer(month).intValue()-1];
				
				value2 = day+"."+month+"."+year;
				
				java.util.Date d = df.parse(value2);
				date = new java.sql.Date(d.getTime());
			} catch (Exception e) {
				//this should be impossible
				throw new EvolutionException("Date format is not valid: "+needNames[columnIndex]+". "+value);
				}
			return date; 			
			
		} else throw new EvolutionException("type undefined for column: "+needNames[columnIndex]+": "+type);
		
	}
	
	private String convertObj2String(int columnIndex, Object value) throws Exception {
		if (value == null) return "";
		String type = needTypes[columnIndex];
		if ("string".equals(type)) {
			return (String)value;
		} else if ("boolean".equals(type)) {
			Boolean b = (Boolean)value;
			boolean bval = b.booleanValue();
			if (bval) return "true";
			else return null;
		}else if ("integer".equals(type)) {
			return String.valueOf((Integer)value);
		} else if ("long".equals(type)) {
			return String.valueOf((Long)value);
		}else if ("double".equals(type)) {
			return String.valueOf((Double)value);
		}else if ("float".equals(type)) {
			return String.valueOf((Float)value);
		}else if ("numeric".equals(type)) {
			return ((BigDecimal)value).toString();
		} else if ("date".equals(type)) {
			try {
				DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.GERMAN);
				String s =  df.format((java.sql.Date)value);
				return s;
			} catch (Exception e) {
				throw new EvolutionException("Error on converting date of : table: "+tableName+", column: "+needNames[columnIndex]);
			}	
		} else if ("bonusdate".equals(type)) {
			try {
				DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.GERMAN);
				String s =  df.format((java.sql.Date)value);
				return s.substring(6)+s.substring(3,5);
			} catch (Exception e) {
				throw new EvolutionException("Error on converting date of : table: "+tableName+", column: "+needNames[columnIndex]);
			}	
		} else throw new EvolutionException("type undefined for column: "+needNames[columnIndex]+": "+type);
			
			
		
	}
}
