package com.k_int.generic.schema.hdo;

import com.k_int.generic.schema.ref.SchemaTypeEnum;
import java.util.List;
import java.util.SortedSet;
import java.util.TreeSet;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.Lob;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.Sort;
import org.hibernate.annotations.SortType;

@Entity
@Table(name="SCHEMA_DEFINITION")
public class SchemaHDO implements Comparable<SchemaHDO>
{
	private Long id;
	private String name = null;
	private String description = null;
	private SortedSet<SchemaSectionHDO> ordered_sections = new TreeSet<SchemaSectionHDO>();
        private Integer schemaTypeOrdinal = new Integer(SchemaTypeEnum.UNKNOWN.ordinal());
	
	protected SchemaHDO(){;}
	
	public SchemaHDO(String name)
	{
		this.name = name;
	}
	
	@Id
	@Column(name="ID")
	@GeneratedValue(strategy=GenerationType.AUTO)
	public Long getId()
	{ 
		return id;                          
	} 
	
	protected void setId(Long id)
	{ 
		this.id = id;
	}
	
	@Column(name="NAME")
	public String getName() 
	{
		return name;
	}

	public void setName(String name) 
	{
		this.name = name;
	}
	
	@Column(name="DESCRIPTION", length=1000)
	@Lob
	public String getDescription() 
	{
		return description;
	}

	public void setDescription(String description) 
	{
		this.description = description;
	}
	
	@OneToMany(fetch=FetchType.EAGER)
	@JoinTable(name="SCHEMA_SECTIONS_LINK",
	         joinColumns=@JoinColumn(name="SCHEMA_FK", referencedColumnName="ID"),
	         inverseJoinColumns= @JoinColumn(name="SCHEMA_SECTION_FK", referencedColumnName="ID"))  
	@Cascade({org.hibernate.annotations.CascadeType.SAVE_UPDATE})
	@Sort(type = SortType.NATURAL)
	public SortedSet<SchemaSectionHDO> getOrderedSections()
	{
		return ordered_sections;
	}
	
	public void setOrderedSections(SortedSet<SchemaSectionHDO> ordered_sections)
	{
		this.ordered_sections = ordered_sections;
	}
        
        
        @Column(name="SCHEMA_TYPE")
        public Integer getSchemaTypeOrdinal() {
            return this.schemaTypeOrdinal;
        }
        
        public void setSchemaTypeOrdinal(Integer newSchemaTypeOrdinal) {
            this.schemaTypeOrdinal = newSchemaTypeOrdinal;
        }
			
	public static SchemaHDO lookupOrCreate(Session session, Long id)
	{
		SchemaHDO retval = SchemaHDO.lookupById(session, id);
		
		if (retval == null) 
		{
			try
			{
				retval = new SchemaHDO(); 
				session.save(retval);
				session.flush();				 
			}
			catch (HibernateException he) 
			{
				throw new HibernateException(he);
			}    		 
		}
		return retval;
	}
	
	public static SchemaHDO lookupById(Session session, Long id)
	{		
		if(id == null)
		{
			return null;
		}
			
		try 
		{
			Query q = session.createQuery("Select x from com.k_int.generic.schema.hdo.SchemaHDO x where x.id = ?");
			q.setLong(0, id);
			
			return (SchemaHDO) q.uniqueResult();
		}
		catch (HibernateException he) 
		{
			throw new HibernateException(he);
		}    
	}
	
	public static List<SchemaHDO> lookupByName(Session session, String name) throws HibernateException
	{		
		if(name == null)
		{
			return null;
		}
			
                Query q = session.createQuery("Select x from com.k_int.generic.schema.hdo.SchemaHDO x where x.name = ?");
                q.setParameter(0, name);

                return (List<SchemaHDO>)q.list();
	}
        
        public static List<SchemaHDO> lookupByNameAndType(Session session, String name, Integer typeOrdinal) throws HibernateException {
            List<SchemaHDO> retval = null;

            if ( name != null && typeOrdinal != null ) {
                Query q = session.createQuery("select x from com.k_int.generic.schema.hdo.SchemaHDO x where x.name = ? and x.schemaTypeOrdinal = ?");
                q.setParameter(0, name);
                q.setParameter(1, typeOrdinal);
                
                retval = (List<SchemaHDO>)q.list();
            }
            
            return retval;
            
        }
	
	/* Comparator method used for sorting */
	public int compareTo(SchemaHDO o) 
	{
        return this.name.compareTo(o.name);
    }
}
