package daruma.sql;

import daruma.global_switch.ImplementationSwitches;

// XXX: should be an abstract class ?
public class SQLDataType
{
	// XXX: should be abstract method of DatabaseConnection?
	private static final int	INDEX_LENGTH = 128;

	private	String	sqlBaseDataTypeName;
 	/* !!! [09/08/26 21:00 I.Noda] !!! */
        private String  sqlBaseDataTypeOption ; 
	private	String	sqlRetrieveFunction;
	private	Class	javaClass;

	public	SQLDataType( String  sqlBaseDataTypeName ,
			     String  sqlBaseDataTypeOption,
			     String  sqlRetrieveFunction ,
			     Class  javaClass )
	{
		this.sqlBaseDataTypeName = sqlBaseDataTypeName;
		this.sqlBaseDataTypeOption = sqlBaseDataTypeOption ;
		this.sqlRetrieveFunction = sqlRetrieveFunction;
		this.javaClass           = javaClass;
	}

	public	SQLDataType( String  sqlBaseDataTypeName ,
			     String  sqlRetrieveFunction ,
			     Class  javaClass )
	{
		this.sqlBaseDataTypeName = sqlBaseDataTypeName;
		this.sqlBaseDataTypeOption = null ;
		this.sqlRetrieveFunction = sqlRetrieveFunction;
		this.javaClass           = javaClass;
	}

	public	SQLDataType( String  sqlBaseDataTypeName ,
			     Class  javaClass )
	{
		this.sqlBaseDataTypeName = sqlBaseDataTypeName;
		this.sqlBaseDataTypeOption = null ;
		this.sqlRetrieveFunction = null;
		this.javaClass           = javaClass;
	}

	public	String	getSQLBaseDataTypeString()
	{
		return( this.sqlBaseDataTypeName );
	}

 	/* !!! [09/08/26 21:00 I.Noda] !!! */
	public	String	getSQLBaseDataTypeOptionString()
	{
		return( this.sqlBaseDataTypeOption );
	}

	public	String	getSQLRetrieveColumnString( String  columnName )
	{
		if ( this.sqlRetrieveFunction != null )
		{
		    return this.sqlRetrieveFunction + "_" + columnName;
		}
		else
		{
			return( columnName );
		}
	}

	public	String	getSQLRetrieveColumnStringForRawSQLString
							( String  columnName )
	{
		if ( this.sqlRetrieveFunction != null )
		{
			return( this.sqlRetrieveFunction
				+ "(" + columnName + ")"
				+ " AS " + this.sqlRetrieveFunction
				+ "_" + columnName );
		}
		else
		{
			return( columnName );
		}
	}

	public	String	getIndexString( String  columnName )
	{
		if ( this.isSpatialType() )
		{
			if ( ImplementationSwitches.instance()
			     .getCreateGeometryIndex() )
			{
				//  doesn't work with non null entry
				//  !!! [09/08/26 21:00 I.Noda] !!!
				return( "SPATIAL INDEX(" + columnName + ")" );
			}
			else
			{
				return( null );
			}
		}
		else if ( this.needsIndexLength() )
		{
			return( "INDEX(" + columnName + "("
				+ SQLDataType.INDEX_LENGTH + "))" );
		}
		else
		{
			return( "INDEX(" + columnName + ")" );
		}
	}

	private	boolean	needsIndexLength()
	{
		return( (this.sqlBaseDataTypeName.equals( "blob" )
		      || this.sqlBaseDataTypeName.equals
			 ( SQLDataTypeConstant.BLOB
			   .getSQLBaseDataTypeString() ) ) );
	}

	public	boolean	isTimeFamilyType()
	{
		return( this.sqlBaseDataTypeName.equals( "timestamp" )
		     || this.sqlBaseDataTypeName.equals( "datetime" ) );
	}

	private	boolean	isSpatialType()
	{
		return( this.sqlBaseDataTypeName.equals( "geometry" ) );
	}

	/*
	public	boolean	isNotNull()
	{
	}
	*/

	// XXX: boolean needQuotes() or escapeValue( String  value ) etc...

	public	Class  getJavaClass()
	{
		return( this.javaClass );
	}
}
