/*
 * MiningMart Version 1.0
 * 
 * Copyright (C) 2006 Martin Scholz, Timm Euler, 
 *                    Daniel Hakenjos, Katharina Morik
 *
 * Contact: miningmart@ls8.cs.uni-dortmund.de
 *
 * A list of contributing developers (other than the copyright 
 * holders) can be found at
 * http://mmart.cs.uni-dortmund.de/downloads/download.html
 * 
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program, see the file MM_HOME/LICENSE; if not, write
 * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
 * Floor, Boston, MA 02110-1301, USA.
 */
package edu.udo.cs.miningmart.operator;


import edu.udo.cs.miningmart.db.DB;
import edu.udo.cs.miningmart.exception.M4CompilerError;
import edu.udo.cs.miningmart.m4.Column;
import edu.udo.cs.miningmart.m4.Value;

/**
 * The class <i>TimeIntervalManualDiscretization</i> implements method
 * generateSQL creating virtual column definition for discretization of
 * numerical intervals according to given discretization specification.
 * NOTE: Physical database table is created, containing the specification. It does
 * not correspond to any M4 ColumnSet object.
 * 
 * @author Cezary Chudzian
 * @version $Id: TimeIntervalManualDiscretization.java,v 1.5 2006/04/11 14:10:11 euler Exp $
 */
public class TimeIntervalManualDiscretization extends ManualDiscretization {

	// private String tableName;
	private boolean usingPostgres = false;

	public Value getTimeFormat() throws M4CompilerError {
		return (Value) this.getSingleParameter("TimeFormat");
	}

	/*
	 * Method handling discretization table creation.
	 *
	private void createTable(String schema) throws M4CompilerError {
		this.tableName =
			"M4_DT_"
				+ this.getStep().getId()
				+ "_"
				+ this.getCurrentLoopNumber();
		try {
			this.getM4Db().executeBusinessSqlWrite("DROP TABLE " + tableName);
		}
		catch (SQLException e) {
			this.doPrint(
				Print.MAX,
				"Discretization table for this step didn't exist. OK!");
		}
		String create_table =
			"CREATE TABLE "
				+ tableName
				+ " (int_start date, int_end date, value varchar2(100), left_b char(1), right_b char(1))";
		try {
			this.getM4Db().executeBusinessSqlWrite(create_table);
		}
		catch (SQLException e) {
			throw new M4CompilerError(
				"Error trying to create the table "
					+ tableName
					+ ": "
					+ e.getMessage());
		}
		String alter_table =
			"ALTER TABLE "
				+ tableName
				+ " ADD CONSTRAINT "
				+ tableName
				+ "_chk CHECK ((left_b IN ('I','E')) AND (right_b IN ('I','E')))";
		try {
			this.getM4Db().executeBusinessSqlWrite(alter_table);
			this.getM4Db().commitBusinessTransactions();
		}
		catch (SQLException e) {
			throw new M4CompilerError(
				"Error trying to alter the table "
					+ tableName
					+ ": "
					+ e.getMessage());
		}
		this.getM4Db().addTableToTrash(tableName, schema, getStep().getId());
		String insert_query = null;
		for (int i = 0; i < this.getIntervalStart().length; i++) {
			insert_query =
				"INSERT INTO "
					+ schema
					+ "."
					+ tableName
					+ " VALUES (to_date('"
					+ this.getIntervalStart()[i].getValue()
					+ "','"
					+ this.getTimeFormat().getValue()
					+ "'),to_date('"
					+ this.getIntervalEnd()[i].getValue()
					+ "','"
					+ this.getTimeFormat().getValue()
					+ "'),'"
					+ this.getMapTo()[i].getValue()
					+ "', '"
					+ this.getStartIncExc()[i].getValue()
					+ "','"
					+ this.getEndIncExc()[i].getValue()
					+ "')";
			try {
				this.getM4Db().executeBusinessSqlWrite(insert_query);
				this.getM4Db().commitBusinessTransactions();
			}
			catch (SQLException e) {
				throw new M4CompilerError(
					"Error trying to fill the discretization table "
						+ tableName
						+ ": "
						+ e.getMessage());
			}
		}
	}
	*/

	private String getStringToDateConversion(String value, boolean quoteTheValue) throws M4CompilerError {
		
		// default: Oracle
		String conversionFunction = "to_date";
		
		if (this.usingPostgres) {
			conversionFunction = "to_timestamp";
		}
		if (quoteTheValue) {
			value = "'" + value + "'";
		}
		return conversionFunction + "(" + value + ", '" + this.getTimeFormat().getValue() + "')";
	}
	
	/** Generates a sql-function to describe a new column.
	 * This method generates a sql-function to describe a new
	 * column. Also creates the discretization table.
	 * @return the SQL-function call
	 */
	public String generateSQL(Column theTargetAttributeColumn) throws M4CompilerError {
			
		// NEW Version:
		this.usingPostgres = (this.getM4Db().getBusinessDbms() == DB.POSTGRES);
		
		String timeFormat = "'" + this.getTimeFormat().getValue() + "'";
		
		// to_char gives the time of day; to_date converts that to Oracle date format:
		String inputColumn = this.getStringToDateConversion("to_char(" + 
		                                                    theTargetAttributeColumn.getSQLDefinition() + 
		                                                    ", " + timeFormat + ")", false);
		                     
		int numberOfIntervals = this.getIntervalStart().length;
		
		String sql = "(CASE ";
		
		for (int i = 0; i < numberOfIntervals; i++) {
			String oneIntervalQuery = "WHEN (";
			oneIntervalQuery += inputColumn + 
			                    this.getGreater(i, true) + 
			                    this.getStringToDateConversion(this.getIntervalStart()[i].getValue(), true) +
			                    ") AND (" +
			                    inputColumn + 
			                    this.getSmaller(i, false) + 
			                    this.getStringToDateConversion(this.getIntervalEnd()[i].getValue(), true) + 
			                    ") THEN '" + this.getMapTo()[i].getValue() + "' ";
			sql += oneIntervalQuery;
		}
		sql += "ELSE '" + this.getDefaultValue().getValue() + "' END)";
		
		return sql;
			
			
		/* OLD Version:
		createTable(theTargetAttributeColumn.getColumnset().getSchema());

		String return_query = null;

		return_query =
			"time_interv_to_cat("
				+ theTargetAttributeColumn.getSQLDefinition()
				+ ",'"
				+ this.getTimeFormat().getValue()
				+ "',"
				+ "'"
				+ theTargetAttributeColumn.getColumnset().getSchema()
				+ "."
				+ tableName
				+ "',"
				+ "'"
				+ this.getDefaultValue().getValue()
				+ "')";

		this.doPrint(Print.OPERATOR, "generatedSQL: "+ return_query);

		return return_query;
		*/
	}
}
/*
 * Historie
 * --------
 *
 * $Log: TimeIntervalManualDiscretization.java,v $
 * Revision 1.5  2006/04/11 14:10:11  euler
 * Updated license text.
 *
 * Revision 1.4  2006/04/06 16:31:11  euler
 * Prepended license remark.
 *
 * Revision 1.3  2006/03/30 16:07:12  scholz
 * fixed author tags for release
 *
 * Revision 1.2  2006/03/23 11:13:44  euler
 * Improved exception handling.
 *
 * Revision 1.1  2006/01/03 09:54:22  hakenjos
 * Initial version!
 *
 */
