/*
 * Created on Aug 14, 2004
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package hibergui.hibernate;

import hibergui.Edit;
import hibergui.Form;
import hibergui.assoc.M2OEdit;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Composite;

/**
 * @author espakm
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public abstract class HibernateForm<T> extends Form<T> {
	
	protected Session session;
	protected Transaction tx;
	
	public HibernateForm(Composite parent, int style) {
		super(parent, style);
	}
	
	protected void init() {
		super.init();
		session = SessionManager.instance().getSession();
	}
	
//	protected void dispose() {
//		if (tx != null && tx.isActive())
//			tx.rollback();
//		super.dispose();
//	}
	
	public Session getSession() {
		return session;
	}
	
	@Override
	public void commit() {
		tx.commit();
	}
	
	@Override
	public void rollback() {
		tx.rollback();
	}
	
	@Override
	protected void save(T object) {
		tx = session.beginTransaction();
		session.save(object);
		session.flush();
		tx.commit();
	}
	
	@Override
	protected void update(T object) {
		tx = session.beginTransaction();
		session.update(object);
		session.flush();
		tx.commit();
	}
	
	@Override
	protected void delete(T object) {
		tx = session.beginTransaction();
		session.delete(object);
		session.flush();
		tx.commit();
	}

	@Override
	public void refresh() {
		T value = get();
		if (value != null)
			session.refresh(value);
		super.refresh();
	}
	
    @SuppressWarnings("unchecked")
	@Override
	protected List<T> findSuch() {
		return createCriteriaByExample().list();
	}
	
    protected Criteria createCriteria() {
    	String orderBy = getSortProperty();
    	int direction = getSortDirection();
    	Criteria crit = session.createCriteria(persistentClass, "root");
    	for (Edit edit: fieldEditors)
    		if (edit instanceof M2OEdit && edit.isFixed())
    			crit.add(Restrictions.eq(edit.getPropertyName(), edit.get()));
    	
    	
    	if (orderBy.indexOf('.') == -1)
    		crit.addOrder(direction == SWT.UP ? Order.asc(orderBy) : Order.desc(orderBy));
//    	else {
//    		crit = crit.createCriteria("root." + orderBy.substring(0, orderBy.indexOf('.')));
//    		crit.addOrder(direction == SWT.UP ? Order.asc(orderBy.substring(orderBy.indexOf('.')+1)) : Order.desc(orderBy.substring(orderBy.indexOf('.')+1)));
//    	}
    	return crit;
    }
    
    protected Criteria createCriteriaByExample() {
    	Criteria crit = createCriteria().add(createExample(extract()));
    	for (Edit edit: fieldEditors)
    		if (edit instanceof M2OEdit && !edit.isFixed()) {
    			Object x = edit.extract();
    			if (x == null)
    				continue;
    			crit = crit.createCriteria("root."+ edit.getPropertyName());
    			if (edit instanceof HibernateM2OEdit)
    				crit.add(((HibernateM2OEdit) edit).createExample(x));
    			else
    				crit.add(createExample(x));
    		}
    	return crit;
    }
	
	public Example createExample(Object sample) {
		return Example.create(sample).
//		excludeZeroes().
		ignoreCase().
		enableLike(MatchMode.START);
	}
}