package cz.cuni.lf1.lge.ThunderSTORM.results;
import cz.cuni.lf1.lge.ThunderSTORM.UI.RenderingOverlay;
import cz.cuni.lf1.lge.ThunderSTORM.estimators.PSF.Molecule;
import cz.cuni.lf1.lge.ThunderSTORM.estimators.PSF.MoleculeDescriptor;
import ij.IJ;
import ij.ImagePlus;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Vector;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTable;
import javax.swing.SwingWorker;
final class TableRowsPopUpMenu implements ActionListener {
private final IJResultsTable rt;
private final ResultsTableWindow tableWindow;
private final GenericTableModel tableModel;
private final JTable jtable;
private final JMenuItem highlightMoleculeMenuItem;
private final JMenuItem deleteMoleculeMenuItem;
private final JMenuItem mergedMoleculesMenuItem;
public TableRowsPopUpMenu(MouseEvent evt, ResultsTableWindow table) {
tableWindow = table;
tableModel = table.getModel();
jtable = table.getView();
rt = IJResultsTable.getResultsTable();
//
highlightMoleculeMenuItem = new JMenuItem("highlight selected molecules in overlay");
deleteMoleculeMenuItem = new JMenuItem("filter out selected molecules");
mergedMoleculesMenuItem = new JMenuItem("show list of merged molecules");
//
highlightMoleculeMenuItem.addActionListener(this);
deleteMoleculeMenuItem.addActionListener(this);
mergedMoleculesMenuItem.addActionListener(this);
//
JPopupMenu popup = new JPopupMenu();
if(rt.getAnalyzedImage() != null) {
popup.add(highlightMoleculeMenuItem);
}
popup.add(deleteMoleculeMenuItem);
if(jtable.getSelectedRowCount() == 1) {
int rowIndex = jtable.convertRowIndexToModel(jtable.getSelectedRow());
if(tableModel.findColumn(MoleculeDescriptor.LABEL_DETECTIONS) != GenericTableModel.COLUMN_NOT_FOUND) {
if(tableModel.getValueAt(rowIndex, MoleculeDescriptor.LABEL_DETECTIONS) > 1) {
popup.add(mergedMoleculesMenuItem);
}
}
}
popup.show(evt.getComponent(), evt.getX(), evt.getY());
}
@Override
public void actionPerformed(ActionEvent evt) {
if(evt.getSource() == highlightMoleculeMenuItem) {
new SwingWorker() {
@Override
protected Object doInBackground() throws Exception {
try {
highlightMolecules();
} catch(Exception e) {
IJ.handleException(e);
}
return null;
}
}.execute();
} else if(evt.getSource() == deleteMoleculeMenuItem) {
filterMolecules();
} else if(evt.getSource() == mergedMoleculesMenuItem) {
showMergedMolecules();
}
}
private void highlightMolecules() {
ImagePlus imp = rt.getAnalyzedImage();
if(imp != null) {
IJ.showStatus("Building new overlay...");
imp.setOverlay(null);
//
int[] rows = jtable.getSelectedRows();
HashSet<Integer> rowIndices = new HashSet<Integer>();
for(int r = 0; r < rows.length; r++) {
rowIndices.add(jtable.convertRowIndexToModel(rows[r]));
}
List<Molecule> selectedMolecules = new ArrayList<Molecule>();
List<Molecule> notSelectedMolecules = new ArrayList<Molecule>();
for(int r = 0, rm = rt.getRowCount(); r < rm; r++) {
Molecule mol = rt.getRow(r);
if(rowIndices.contains(r)) {
selectedMolecules.add(mol);
if(!mol.isSingleMolecule()) {
selectedMolecules.addAll(mol.getDetections());
}
} else {
notSelectedMolecules.add(mol);
if(!mol.isSingleMolecule()) {
notSelectedMolecules.addAll(mol.getDetections());
}
}
}
RenderingOverlay.showPointsInImage(selectedMolecules.toArray(new Molecule[0]), imp, null, Color.GREEN, RenderingOverlay.MARKER_CIRCLE);
RenderingOverlay.showPointsInImage(notSelectedMolecules.toArray(new Molecule[0]), imp, null, Color.RED, RenderingOverlay.MARKER_CROSS);
//
IJ.showProgress(1.0);
IJ.showStatus("");
}
}
private void filterMolecules() {
int[] rows = jtable.getSelectedRows();
Vector<Integer> rowIds = new Vector<Integer>();
for(int r = 0; r < rows.length; r++) {
int rowIndex = jtable.convertRowIndexToModel(rows[r]);
rowIds.add(tableModel.getValueAt(rowIndex, MoleculeDescriptor.LABEL_ID).intValue());
}
Collections.sort(rowIds);
int start, end;
StringBuilder sb = new StringBuilder();
for(int r = 0, rm = rowIds.size(); r < rm; r++) {
if(r > 0) {
sb.append("&");
}
start = rowIds.get(r);
if((r + 1) >= rm) {
sb.append("(id!=").append(start).append(")");
} else {
end = rowIds.get(r + 1);
if((end - start) > 1) {
sb.append("(id!=").append(start).append(")");
} else {
sb.append("(id<").append(start).append("|");
while(((r + 1) < rm) && ((end - start) <= 1)) {
start = rowIds.get(r);
end = rowIds.get(r + 1);
r++;
}
if((end - start) > 1) {
sb.append("id>").append(start).append(")");
} else {
sb.append("id>").append(end).append(")");
}
}
}
}
//
String formula = sb.toString();
ResultsFilter filter = tableWindow.getFilter();
filter.setFilterFormula(formula);
filter.run();
}
private void showMergedMolecules() {
int row = jtable.getSelectedRow();
int rowIndex = jtable.convertRowIndexToModel(row);
Molecule mol = tableModel.getRow(rowIndex);
List<Molecule> detections = mol.getDetections();
Collections.sort(detections);
new MergedMoleculesPopUp(jtable, row, 0, detections);
}
}