package usda.weru.gis.gui;

import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;
import org.geotools.map.Layer;
import org.geotools.map.MapLayerListListener;
import org.geotools.map.MapLayerListEvent;
import org.geotools.tile.util.TileLayer;

/**
 *
 * @author Joseph A. Levin <joelevin@weru.ksu.edu>
 */
public class LayerTableModel extends AbstractTableModel implements MapLayerListListener {

    private static final long serialVersionUID = 1L;
    
    MapViewer viewer;
    ArrayList <Layer> layerList;

    public LayerTableModel(MapViewer v) {
        viewer = v;
        layerList = new ArrayList<>();
    }
    
    @Override
    public void layerAdded(MapLayerListEvent event) {
        Layer l = event.getElement();
        layerList.add(event.getElement());
        fireTableRowsInserted(invertIndex(event.getFromIndex()), invertIndex(event.getToIndex()));
    }

    @Override
    public void layerRemoved(MapLayerListEvent event) {
        layerList.remove(event.getElement());
        fireTableRowsDeleted(invertIndex(event.getFromIndex()), invertIndex(event.getToIndex()));
    }

    @Override
    public void layerChanged(MapLayerListEvent event) {
        fireTableRowsUpdated(invertIndex(event.getFromIndex()), invertIndex(event.getToIndex()));
    }

    @Override
    public void layerMoved(MapLayerListEvent event) {
        fireTableDataChanged();
    }

    private int invertIndex(int index) {
        return getRowCount() - 1 - index;
    }

    @Override
    public int getRowCount() {
        return layerList.size();
    }

    @Override
    public int getColumnCount() {
        return 2;
    }

    
    public Layer getLayer(int rowIndex) {
        int idx = invertIndex(rowIndex);
        return layerList.get(idx);
    }

    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Layer layer = getLayer(rowIndex);
        if (layer == null) {
            return null;
        }
        switch (columnIndex) {
            case 0:
                return layer.isVisible();
            case 1:
                return layer.getTitle();
            default:
                return null;
        }
    }

    @Override
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        switch (columnIndex) {
            case 0:
                boolean value = false;
                if (aValue instanceof Boolean) {
                    value = (Boolean) aValue;
                }
                Layer layer = getLayer(rowIndex);
                if (layer == null) {
                    return;
                }
                layer.setVisible(value);
                if (value && layer.getTitle().contentEquals(MapViewerLayersContent.prismDataLayerName)) {
                    int i = 1;
                    if (viewer != null && viewer.getMapController() instanceof MapRenderLayer) {
                        ((MapRenderLayer)viewer.getMapController()).getContent().updatePrismDataLocationLayer();
                    }
                }
                if (layer instanceof TileLayer) {
                    // forces the MapRenderLayer to redraw and preload the cache.
                    ((MapRenderLayer)viewer.getMapController()).preloadMapCache();
                }
                break;
            default:
        }
    }

    @Override
    public String getColumnName(int columnIndex) {
        switch (columnIndex) {
            case 0:
                return "Visible";
            case 1:
                return "Layer";
            default:
                return null;
        }
    }

    @Override
    public Class<?> getColumnClass(int columnIndex) {
        switch (columnIndex) {
            case 0:
                return Boolean.class;
            case 1:
                return String.class;
            default:
                return super.getColumnClass(columnIndex);
        }
    }

    @Override
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return columnIndex == 0;
    }

    @Override
    public void layerPreDispose(MapLayerListEvent arg0) {

    }
    
    public int findLayerIndex (String title) {
        for (int i = 0; i < layerList.size(); i++) {
            if (layerList.get(i).getTitle().contentEquals(title)) {
                return i;
            }
        }
        return -1;
    }
    
    public void updateLayer (int idx, Layer newLayer) {
        layerList.set(idx, newLayer);
        fireTableRowsUpdated(invertIndex(idx), invertIndex(idx));
    }

}
