package hibergui.assoc;

import static org.eclipse.swt.SWT.PUSH;

import hibergui.Edit;
import hibergui.Form;
import hibergui.FormDialog;

import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Shell;

/**
 * 
 * @author espakm
 *
 * @param <T> Association "To".
 * @param <C> Collection or map type. (T, Set<T> or List<T>.) 
 */

public abstract class AssociationEdit<T, C> extends Edit<C> {

    protected FormDialog<T> dlgAssoc;
	protected Button btnAssoc;
	
//	private boolean hasChanged;
	
	public AssociationEdit(Form<?> form, Composite cptParent, int style, String prop, String name) {
		super(form, cptParent, style, prop, name);
		
		// if the edit is fixed, btnAssoc may be null
		if (btnAssoc != null) {
	        btnAssoc.setText(getName());
			btnAssoc.addKeyListener(lsn_WIDGET_KEY);
			btnAssoc.addFocusListener(lsn_WIDGET_FOCUS);
	        btnAssoc.addTraverseListener(lsn_TRAVERSE);
		}
	}

	@Override
	public C extract() {
		return get();
	}
	
//	@Override
//	public void fill() {
//	}

	public void refresh() {
	}
	
	protected Button createAssocDialogButton(final Composite cptParent) {

        btnAssoc = new Button(cptParent, PUSH);
        btnAssoc.addSelectionListener(new SelectionAdapter(){
			public void widgetSelected(SelectionEvent e){
		       	dlgAssoc = createAssocDialog(cptParent.getShell());
		       	if (value == null)
		       		dlgAssoc.getForm().setSearchMode(true);
                dlgAssoc.open();
                if (dlgAssoc.getForm().hasChanged()) {
                	refresh();
                }
                T[] result = dlgAssoc.getResult();
                
                if (result.length != 0)
                	setSelection(result);
            }
        });
		return btnAssoc;
	}

	protected abstract void setSelection(T[] value);
	
	/**
	 *	The implementation should look like the following code where the 
	 *	SomeForm class extends Form<T>.
	 * 
	 *	FormDialog<T> dlg= new FormDialog<T>(cptParent.getShell()) {
	 * 		protected Form<T> createForm(Composite cptParent) {
	 * 			SomeForm f = return new SomeForm(cptParent, Form.NONE);
	 * 			f.setFixedField(get());
	 * 			return f;
	 * 		}
	 * 	};
	 */
	protected final FormDialog<T> createAssocDialog(final Shell shell) {
        FormDialog<T> dlg = new FormDialog<T>(shell) {
			@Override
            protected Form<T> createForm(final Composite cpt) {
				return AssociationEdit.this.createForm(cpt);
            }                    
        };
        dlg.create();
        return dlg;
	}

	protected abstract Form<T> createForm(final Composite cpt);

	@Override
	public void clear() {
		btnAssoc.setEnabled(false);
	}
	
	@Override
	public void setBackground(Color clr) {
		btnAssoc.setBackground(clr);
	}

	@Override
	public boolean setFocus() {
		return btnAssoc.setFocus();
	}

	@Override
	public boolean isEnabled() {
		return btnAssoc.isEnabled();
	}

	@Override
	public void setEnabled(boolean b) {
		btnAssoc.setEnabled(b);
	}
    
    @Override
    public void setEditable(boolean b) {
    	if (!isFixed() || !b)
    		setEnabled(b);
    }
}
