package ai.codestatistics.preferences;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class DomainConfigDialog extends Dialog {
private static abstract class Entry {
protected Control ctrl;
private Button btn;
public Entry(Button btn, Control ctrl){
this.btn = btn;
this.ctrl = ctrl;
}
public abstract String getRepr();
}
private static class BoxThresEmpty extends Entry {
public BoxThresEmpty(Button btn, Control ctrl) {
super(btn, ctrl);
}
@Override
public String getRepr() {
return DomainEntry.reprBoxesEmpty();
}
}
private static class BoxThresBox extends Entry {
public BoxThresBox(Button btn, Text ctrl) {
super(btn, ctrl);
}
@Override
public String getRepr() {
return DomainEntry.reprBoxesBox(Integer.parseInt(((Text)this.ctrl).getText()));
}
}
private static class BoxThresArg extends Entry {
public BoxThresArg(Button btn, Text ctrl) {
super(btn, ctrl);
}
@Override
public String getRepr() {
return DomainEntry.reprBoxesArg(Integer.parseInt(((Text)this.ctrl).getText()));
}
}
private Text nameField;
private final Set<String> existingNames;
private String selectedRepr;
private List<Entry> boxesSettings;
private DomainEntry entry;
// private Map<Button, Control> boxesSettings;
protected DomainConfigDialog(Shell shell, Set<String> existingNames) {
super(shell);
this.existingNames = existingNames;
}
@Override
protected void configureShell(Shell newShell) {
super.configureShell(newShell);
newShell.setText("Configure domain");
}
private static void recursiveSetEnabled(Control ctrl, boolean enabled) {
if (ctrl instanceof Composite) {
Composite comp = (Composite) ctrl;
for (Control c : comp.getChildren())
recursiveSetEnabled(c, enabled);
} else {
ctrl.setEnabled(enabled);
}
}
private void updateSelected(List<Entry> items, Button selectedButton) {
for (Entry entry : items) {
Button btn = entry.btn;
boolean selected = (selectedButton != null) ? btn == selectedButton : btn.getSelection();
if (selected)
selectedRepr = entry.getRepr();
Control control = entry.ctrl;
if (control == null)
continue;
control.setEnabled(selected);
}
}
private Composite createDomainsChoice(Composite parent) {
Group domainGroup = new Group(parent, SWT.SHADOW_IN);
domainGroup.setText("Domain");
domainGroup.setLayout(new RowLayout(SWT.VERTICAL));
Button intvButton = new Button(domainGroup, SWT.RADIO);
intvButton.setText("Bool x Intv");
Button boxesButton = new Button(domainGroup, SWT.RADIO);
boxesButton.setText("Bool x Boxes, widening threshold settings:");
boxesSettings = new LinkedList<Entry>();
final Composite boxesComposite = new Composite(domainGroup, SWT.NONE);
GridLayout gl = new GridLayout();
gl.numColumns = 3;
boxesComposite.setLayout(gl);
Button emptyThresholds = new Button(boxesComposite, SWT.RADIO);
emptyThresholds.setText("Empty");
GridData gd = new GridData();
gd.horizontalSpan = 3;
emptyThresholds.setLayoutData(gd);
boxesSettings.add(new BoxThresEmpty(emptyThresholds, null));
Button boxThresholds = new Button(boxesComposite, SWT.RADIO);
boxThresholds.setText("Surrounding box from ");
Text text = new Text(boxesComposite, SWT.BORDER | SWT.NO_SCROLL);
GC gc = new GC(text);
FontMetrics fm = gc.getFontMetrics();
int width = 7 * fm.getAverageCharWidth();
GridData textGridData = new GridData();
textGridData.minimumWidth = width;
textGridData.grabExcessHorizontalSpace = true;
text.setLayoutData(textGridData);
text.setText("1");
text.addVerifyListener(Shared.NUMBER_VERIFIER);
text.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
updateSelected(boxesSettings, null);
}
});
Label l = new Label(boxesComposite, SWT.LEFT);
l.setText("first arguments");
l.setLayoutData(new GridData());
boxesSettings.add(new BoxThresBox(boxThresholds, text));
Button argThresholds = new Button(boxesComposite, SWT.RADIO);
argThresholds.setText("Local special points from ");
Text argText = new Text(boxesComposite, SWT.BORDER | SWT.NO_SCROLL);
GridData argTextGridData = new GridData();
argTextGridData.minimumWidth = width;
argTextGridData.grabExcessHorizontalSpace = true;
argText.setLayoutData(argTextGridData);
argText.setText("1");
argText.addVerifyListener(Shared.NUMBER_VERIFIER);
argText.addModifyListener(new ModifyListener() {
@Override
public void modifyText(ModifyEvent e) {
updateSelected(boxesSettings, null);
}
});
Label argL = new Label(boxesComposite, SWT.LEFT);
argL.setText("first arguments");
argL.setLayoutData(new GridData());
boxesSettings.add(new BoxThresArg(argThresholds, argText));
// events
intvButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
recursiveSetEnabled(boxesComposite, false);
selectedRepr = DomainEntry.reprIntv();
}
});
boxesButton.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
// we enable only currently selected
recursiveSetEnabled(boxesComposite, true);
updateSelected(boxesSettings, null);
}
});
for(Entry entry: boxesSettings) {
entry.btn.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
updateSelected(boxesSettings, (Button) e.item);
}
});
}
intvButton.setSelection(true);
intvButton.notifyListeners(SWT.Selection, new Event());
emptyThresholds.setSelection(true);
return domainGroup;
}
@Override
protected Control createDialogArea(Composite parent) {
Composite composite = (Composite) super.createDialogArea(parent);
GridLayout gl = (GridLayout) composite.getLayout();
gl.numColumns = 2;
Label nameLabel = new Label(composite, SWT.LEFT);
nameLabel.setText("Name:");
nameLabel.setLayoutData(new GridData());
nameField = new Text(composite, SWT.SINGLE | SWT.BORDER);
nameField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
GridData gd = new GridData(GridData.FILL_BOTH);
gd.horizontalSpan = 2;
createDomainsChoice(composite).setLayoutData(gd);
return composite;
}
@Override
protected void okPressed() {
String name = nameField.getText().trim();
if (name.length() == 0)
return;
if (existingNames.contains(name))
return;
entry = new DomainEntry(nameField.getText().trim(), selectedRepr);
super.okPressed();
}
public DomainEntry getSelectedDomainSettings() {
return entry;
}
}