package hibergui.assoc;

import static hibergui.HiberGUI.SINGLE_SELECTION;

import java.lang.reflect.ParameterizedType;
import java.util.List;

import hibergui.Form;

import org.eclipse.swt.widgets.Composite;

public abstract class M2OEdit<T> extends AssociationEdit<T, T> {

	protected final Class<T> persistentClass;

	public M2OEdit(Form<?> form, Composite cptParent, int style, String prop, String name) {
		super(form, cptParent, style, prop, name);

		persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}

	@Override
	protected void setSelection(T[] value) {
		set(value[0]);
	}

	protected final Form<T> createForm(Composite cptParent) {
		Form<T> f = createForm(cptParent, SINGLE_SELECTION);
		if (value == null) {
			T t = extract();
			if (t != null) {
				fillForm(f);
			}
//			f.setSearchMode(true);
		}
		else {
			T t = get();
			f.set(t);
//			if (!SessionManager.session().contains(t))
//				f.setSearchMode(true);
		}
		return f;
	}

	/**
	 * Fills the corresponding fields of the form, according to the content of the
	 * editor. This is only invoked when no object has been set as the input the editor
	 * yet. 
	 * @param f
	 */
	protected void fillForm(Form<T> f) {
		f.fill(extract());
	}
	
	protected abstract Form<T> createForm(Composite cptParent, int style);

    public abstract void extract(T t);
    
	/**
     * It should do something like that (unfortunately, generic parameter
     * types cannot be instantiated):
     * 
     * public final T extract() {
     *     T t = new T();
     *     extract(t);
     *     return t;
     * }
     * 
     * */
    public T extract() {
    	T t = null;
    	try {
			t = persistentClass.newInstance();
			extract(t);
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return t;
    }

	protected abstract List<T> findSuch();
    protected abstract List<T> findAll();

}
