package com.opendoorlogistics.studio.components.map.plugins.selection;
import gnu.trove.set.hash.TLongHashSet;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.border.EmptyBorder;
import com.opendoorlogistics.api.standardcomponents.map.MapApi;
import com.opendoorlogistics.api.standardcomponents.map.MapApiListeners;
import com.opendoorlogistics.api.standardcomponents.map.MapDataApi;
import com.opendoorlogistics.api.tables.ODLListener;
import com.opendoorlogistics.api.tables.ODLTableReadOnly;
import com.opendoorlogistics.codefromweb.WrapLayout;
import com.opendoorlogistics.studio.tables.grid.GridEditPermissions;
import com.opendoorlogistics.studio.tables.grid.ODLGridTable;
import com.opendoorlogistics.studio.tables.grid.PreferredColumnWidths;
import com.opendoorlogistics.studio.tables.grid.SelectionManager;
import com.opendoorlogistics.studio.tables.grid.adapter.RowStyler;
class SelectObjectsPopup extends JDialog implements MapApiListeners.OnObjectsChanged{
private final MapApi api;
private final TablesPanel tablesPanel ;
private final ODLListener listener = new ODLListener() {
@Override
public void tableChanged(int tableId, int firstRow, int lastRow) {
updateTables();
}
@Override
public ODLListenerType getType() {
return ODLListenerType.DATASTORE_STRUCTURE_CHANGED;
}
@Override
public void datastoreStructureChanged() {
updateTables();
}
};
private final PreferredColumnWidths preferredColumnWidths;
private final MapApiListeners.OnChangeListener selectionChangeListener = new MapApiListeners.OnChangeListener() {
@Override
public void onChanged(MapApi api) {
tablesPanel.repaint();
}
};
private Rectangle boundsOnDispose;
SelectObjectsPopup(MapApi api,Rectangle preferredBounds,PreferredColumnWidths preferredColumnWidths) {
super(SwingUtilities.getWindowAncestor(api.getMapWindowComponent()), ModalityType.APPLICATION_MODAL);
this.api = api;
this.preferredColumnWidths = preferredColumnWidths;
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
MapDataApi mapDataApi = api.getMapDataApi();
mapDataApi.getGlobalDatastore().addListener(listener);
tablesPanel = new TablesPanel(mapDataApi.getGlobalDatastore());
if(preferredBounds!=null){
setBounds(preferredBounds);
}
setLayout(new BorderLayout());
// JLabel topLabel = new JLabel("Search for objects and select them in the map");
// topLabel.setBorder( new EmptyBorder(5, 5, 5, 5));
// add(topLabel, BorderLayout.NORTH);
add(tablesPanel, BorderLayout.CENTER);
JPanel buttonsPanel = new JPanel(new WrapLayout(FlowLayout.CENTER,1,5));
add(buttonsPanel, BorderLayout.SOUTH);
for(Action action : createActions()){
JButton button= new JButton(action);
button.setMargin(new Insets(0,0,0,0));
button.setBorder(new EmptyBorder(6, 8, 6, 8));
buttonsPanel.add(button);
}
api.registerObjectsChangedListener(this, 0);
api.registerSelectionChanged(selectionChangeListener, 0);
updateTables();
setTitle("Search for objects and select them in the map");
if(preferredBounds==null){
pack();
}
// pack();
}
private enum UpdateSelOp{
ADD,
REPLACE,
REMOVE
}
private ArrayList<Action> createActions(){
ArrayList<Action> ret = new ArrayList<Action>();
class UpdateSelectionAction extends AbstractAction{
private final boolean allRows;
private final UpdateSelOp option;
UpdateSelectionAction(String text, boolean allRows, UpdateSelOp option){
super(text);
this.allRows = allRows;
this.option = option;
}
@Override
public void actionPerformed(ActionEvent e) {
// get the current rows
TLongHashSet selected = new TLongHashSet(api.getSelectedIds());
// get the rows
TLongHashSet operationSet = new TLongHashSet(tablesPanel.getRowIds(!allRows));
if(option == UpdateSelOp.REPLACE){
selected.clear();
selected.addAll(operationSet);
}
else if (option== UpdateSelOp.ADD){
selected.addAll(operationSet);
}else if(option == UpdateSelOp.REMOVE){
selected.removeAll(operationSet);
}
api.setSelectedIds(selected.toArray());
dispose();
}
}
ret.add(new UpdateSelectionAction("Add visible rows", true, UpdateSelOp.ADD));
ret.add(new UpdateSelectionAction("Add highlighted rows", false, UpdateSelOp.ADD));
ret.add(new UpdateSelectionAction("Replace with visible rows", true, UpdateSelOp.REPLACE));
ret.add(new UpdateSelectionAction("Replace with highlighted rows", false, UpdateSelOp.REPLACE));
ret.add(new UpdateSelectionAction("Remove visible rows", true, UpdateSelOp.REMOVE));
ret.add(new UpdateSelectionAction("Remove highlighted rows", false, UpdateSelOp.REMOVE));
ret.add(new AbstractAction("Close") {
@Override
public void actionPerformed(ActionEvent e) {
dispose();
}
});
return ret;
}
@Override
public void dispose(){
boundsOnDispose = getBounds();
super.dispose();
api.getMapDataApi().getGlobalDatastore().removeListener(listener);
api.removeObjectsChangedListener(this);
api.removeSelectionChangedListener(selectionChangeListener);
}
private void updateTables(){
// get all input row ids
TLongHashSet filtered = new TLongHashSet();
ODLTableReadOnly active = api.getMapDataApi().getUnfilteredActiveTable();
if(active!=null){
int n = active.getRowCount();
for(int i =0 ; i < n ; i++){
filtered.add(active.getRowId(i));
}
}
// update the filter datastore
tablesPanel.filteredDs.update(filtered, false);
// then the tabs
tablesPanel.updateTableTabs(true, new ODLGridTableFactory() {
@Override
public ODLGridTable createODLGridTable(int tableId) {
// to do add custom row style which shows a blue font for rows selected in the map...
RowStyler styler = new RowStyler() {
@Override
public Color getRowFontColour(long rowId) {
return api.isSelectedId(rowId) ? Color.BLUE : Color.BLACK;
}
};
ODLGridTable ret = new ODLGridTable(tablesPanel.filteredDs, tableId, true, styler, api.getMapDataApi().getGlobalDatastore(), new GridEditPermissions(false, false, false, false, false), preferredColumnWidths){
@Override
protected SelectionManager createSelectionManager(){
return new SelectionManager(this,true);
}
};
ret.setShowFilters(true);
return ret;
}
});
}
@Override
public void onObjectsChanged(MapApi api) {
updateTables();
}
Rectangle getBoundsOnDispose(){
return boundsOnDispose;
}
}