/**
 *
 */


package gov.va.med.cds.persistence.hibernate.common;


import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.type.StandardBasicTypes;
import org.hibernate.type.Type;


public class VistaPointInTimeUserTypeQuery
    extends
        AbstractPointInTimeUserType
{

    public Object getPropertyValue( Object value, int property )
        throws HibernateException
    {
    	if ( value instanceof PointInTime )
        {
            PointInTime pointInTime = ( PointInTime )value;
            return ( property == 1 ) ? isoTime2Double( pointInTime.getTimestamp() ) : pointInTime.getTimestamp();
        }
        else if(value instanceof gov.va.med.cds.template.generated.basedatatypes.PointInTime){
        	gov.va.med.cds.template.generated.basedatatypes.PointInTime pointInTime = ( gov.va.med.cds.template.generated.basedatatypes.PointInTime )value;
            return ( property == 1 ) ? isoTime2Double( pointInTime.getLiteral() ) : pointInTime.getLiteral();
        }
    	return null;
    }


    public String[] getPropertyNames( )
    {
        return new String[] { "timestamp", "namespace" };
    }


    public Type[] getPropertyTypes( )
    {
        return new Type[] { StandardBasicTypes.STRING, StandardBasicTypes.STRING };
    }


    public Object assemble( Serializable cached, Object owner )
        throws HibernateException
    {
        return cached;
    }


    public Object assemble( Serializable cached, SessionImplementor sessionImplementor, Object owner )
        throws HibernateException
    {
        return cached;
    }


    public Object deepCopy( Object value )
        throws HibernateException
    {
        return value;
    }


    public Serializable disassemble( Object value, SessionImplementor sessionImplementor )
        throws HibernateException
    {
        return ( Serializable )value;
    }


    public boolean equals( Object x, Object y )
        throws HibernateException
    {
        return false;
    }


    public int hashCode( Object x )
        throws HibernateException
    {
        if ( x == null )
        {
            return 0;
        }

        return x.hashCode();
    }


    public Object nullSafeGet( ResultSet rs, String[] names, SessionImplementor sessionImplementor, Object owner )
        throws HibernateException,
            SQLException
    {
        String rawDate = rs.getString( names[0] );
        String namespace = rs.getString( names[1] );

        if ( rawDate == null )
        {
            return null;
        }

        String timestamp = null;
        if ( rawDate.indexOf( "-" ) > 0 )
        {
            timestamp = formatHdrTime( rawDate, namespace );
        }
        else
        {
            timestamp = formatVistaTime( rawDate, namespace );
        }

       
            gov.va.med.cds.template.generated.basedatatypes.PointInTime pointInTime = new gov.va.med.cds.template.generated.basedatatypes.PointInTime();
           
            pointInTime.setLiteral(timestamp);
            
            return pointInTime;
       
    }


    public void nullSafeSet( PreparedStatement st, Object value, int index, SessionImplementor sessionImplementor )
        throws HibernateException,
            SQLException
    {
        //this method is implemented to set query parameters in the sql for a read - but not to write data to vista.
        if ( value == null )
        {
            st.setNull( index, StandardBasicTypes.DATE.sqlType() );
        }
        else
        {
        	 if ( value instanceof PointInTime )
             {
                 PointInTime pointInTime = ( PointInTime )value;
                 java.sql.Date timestamp = isoTime2Date( pointInTime.getTimestamp() );
                 if ( timestamp != null )
                 {
                     st.setDate( index, timestamp );
                 }
                 else
                 {
                     st.setNull( index, StandardBasicTypes.DATE.sqlType() );
                 }
             }
             else if(value instanceof gov.va.med.cds.template.generated.basedatatypes.PointInTime)
             {
             	gov.va.med.cds.template.generated.basedatatypes.PointInTime pointInTime = (gov.va.med.cds.template.generated.basedatatypes.PointInTime)value;
             	java.sql.Date timestamp = isoTime2Date( pointInTime.getLiteral() );
                 if ( timestamp != null )
                 {
                     st.setDate( index, timestamp );
                 }
                 else
                 {
                     st.setNull( index, StandardBasicTypes.DATE.sqlType() );
                 }
             }
            else
            {
            	 throw new HibernateException( "The value parameter must of type PointInTime. The actual type was " + value.getClass().getName() );
            }
        }
    }


    public Class<PointInTime> returnedClass( )
    {
        return PointInTime.class;
    }


    public int[] sqlTypes( )
    {
        return new int[] { StandardBasicTypes.DATE.sqlType() };
    }

}
