view flys-client/src/main/java/de/intevation/flys/client/client/ui/GaugeTree.java @ 4137:9be8d7942284

Open gauge and river info in a new browser window Fix for issue #918
author Björn Ricks <bjoern.ricks@intevation.de>
date Mon, 15 Oct 2012 15:23:13 +0200
parents 989f6f0d1986
children 3245bb4d600b 1755a1bfe5ce
line wrap: on
line source
package de.intevation.flys.client.client.ui;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.DecoratorPanel;
import com.google.gwt.user.client.ui.Grid;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;

import com.smartgwt.client.widgets.layout.HLayout;

import de.intevation.flys.client.client.FLYS;
import de.intevation.flys.client.client.FLYSConstants;
import de.intevation.flys.client.shared.model.Data;
import de.intevation.flys.client.shared.model.DataItem;
import de.intevation.flys.client.shared.model.DataList;
import de.intevation.flys.client.shared.model.GaugeInfo;
import de.intevation.flys.client.shared.model.RiverInfo;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;


public class GaugeTree extends ScrollPanel {

    private FLYS flys;
    private Tree tree;
    private DataList[] data;

    /** The message class that provides i18n strings.*/
    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);

    public GaugeTree(FLYS flys) {
        this.flys = flys;
        tree = new Tree();
        setWidget(tree);
    }

    /**
     * Resets the items of the tree.
     * If the list of gauges is empty or null the tree will be empty.
     */
    public void setGauges(RiverInfo riverinfo) {
        tree.clear();

        List<GaugeInfo> gauges = riverinfo.getGauges();

        if (gauges != null && !gauges.isEmpty()) {

            ArrayList<GaugeInfo> emptygauges = new ArrayList<GaugeInfo>();

            if (!riverinfo.isKmUp()) {
                for (GaugeInfo gauge : gauges) {
                    addGauge(gauge, emptygauges);
                }
            }
            else {
                for (int i = gauges.size()-1; i >= 0; i--) {
                    GaugeInfo gauge = gauges.get(i);
                    addGauge(gauge, emptygauges);
                }
            }

            // put empty gauges to the end
            for (GaugeInfo gauge : emptygauges) {
                addGauge(gauge);
            }

            open();
        }
    }

    private void addGauge(GaugeInfo gauge, List<GaugeInfo> empty) {
        if (gauge.getKmStart() != null && gauge.getKmEnd() != null) {
            addGauge(gauge);
        }
        else {
            empty.add(gauge);
        }
    }

    private void addGauge(GaugeInfo gauge) {
        GaugeInfoItem gaugeitem = new GaugeInfoItem(flys, gauge);
        tree.addItem(gaugeitem);
    }

    public void openAll() {
        GWT.log("GaugeTree - openAll");
        for (Iterator<TreeItem> it = tree.treeItemIterator(); it.hasNext();) {
            TreeItem item = it.next();
            item.setState(true);
        }
    }

    public void setData(DataList[] data) {
        this.data = data;
        if (tree.getItemCount() > 0) {
            open();
        }
    }

    public void open() {
        ArrayList<Double> locations = new ArrayList<Double>();

        if (data != null && data.length > 0) {
            for (int i = 0; i < data.length; i++) {
                DataList dl = data[i];
                String state = dl.getState();
                GWT.log("GaugeTree - setData " + state);
                if (state.equals("state.winfo.location_distance")) {
                    Double ldfrom = null;
                    Double ldto = null;

                    for (int j = dl.size()-1; j >= 0; --j) {
                        Data d = dl.get(j);
                        String label = d.getLabel();
                        GWT.log("GaugeTree - setData - label " + label + " " + d.getStringValue());
                        if (label.equals("ld_from")) {
                            ldfrom = getDoubleValue(d);
                        }
                        else if (label.equals("ld_to")) {
                            ldto = getDoubleValue(d);
                        }
                        else if (label.equals("ld_locations")) {
                            getLocationsFromData(locations, d);
                            openOnLocations(locations);
                            return;
                        }
                    }
                    if (ldfrom != null) {
                        openOnDistance(ldfrom, ldto);
                        return;
                    }
                }
                else if(state.equals("state.winfo.distance_only") ||
                        state.equals("state.winfo.distance")) {
                    Double ldfrom = null;
                    Double ldto = null;

                    for (int j = dl.size()-1; j >= 0; --j) {
                        Data d = dl.get(j);
                        String label = d.getLabel();
                        GWT.log("GaugeTree - setData - label " + label + " " + d.getStringValue());
                        if (label.equals("ld_from")) {
                            ldfrom = getDoubleValue(d);
                        }
                        else if (label.equals("ld_to")) {
                            ldto = getDoubleValue(d);
                        }
                    }

                    if (ldfrom != null) {
                        openOnDistance(ldfrom, ldto);
                        return;
                    }
                        }
                else if (state.equals("state.winfo.location")) {
                    getLocations("ld_locations", locations, dl);
                    openOnLocations(locations);
                    return;
                }
                else if (state.equals("state.winfo.reference.curve.input.start")) {
                    getLocations("reference_startpoint", locations, dl);
                }
                else if (state.equals("state.winfo.reference.curve.input.end")) {
                    getLocations("reference_endpoint", locations, dl);
                }
                else if (state.equals("state.winfo.historicalq.reference_gauge")) {
                    for (int j = dl.size()-1; j >= 0; --j) {
                        Data d = dl.get(j);
                        String label = d.getLabel();
                        if (label.equals("reference_gauge")) {
                            String tmp = d.getStringValue();
                            if (tmp != null) {
                                Long gaugereference = Long.valueOf(tmp);
                                if (gaugereference != null) {
                                    openOnReference(gaugereference);
                                    return;
                                }
                            }
                        }
                    }
                }
            }
        }
        if (!locations.isEmpty()) {
            openOnLocations(locations);
        }
        else {
            openAll();
        }
    }

    private void getLocations(String labelname, List<Double> locations, DataList dl) {
        for (int j = dl.size()-1; j >= 0; --j) {
            Data d = dl.get(j);
            String label = d.getLabel();
            if (label.equals(labelname)) {
                getLocationsFromData(locations, d);
            }
        }
    }

    private void getLocationsFromData(List<Double> locations, Data data) {
        DataItem[] items = data.getItems();
        for (int k = 0; k < items.length; k++) {
            String tmp = items[k].getStringValue();
            GWT.log("GaugeTree - getLocationsFromData " + tmp);
            if (tmp != null) {
                if (tmp.contains(" ")) {
                    // string contains several values ...
                    String[] values = tmp.split(" ");
                    for(int i=0; i < values.length; i++) {
                        Double value = Double.valueOf(values[i]);
                        if (value != null) {
                            locations.add(value);
                        }
                    }
                }
                else {
                    Double value = Double.valueOf(tmp);
                    if (value != null) {
                        locations.add(value);
                    }
                }
            }
        }
    }

    private Double getDoubleValue(Data d) {
        String tmp = d.getStringValue();
        if (tmp != null) {
            return Double.valueOf(tmp);
        }
        return null;
    }

    public void openOnReference(Long number) {
        GWT.log("GaugeTree - openOnReference " + number);
        for (Iterator<TreeItem> it = tree.treeItemIterator(); it.hasNext();) {
            TreeItem item = it.next();
            if (item instanceof GaugeInfoItem) {
                GaugeInfoItem gitem = (GaugeInfoItem)item;
                if (gitem.getReference().equals(number)) {
                    item.setState(true);
                }
                else {
                    item.setState(false);
                }
            }
        }
    }

    public void openOnDistance(Double start, Double end) {
        GWT.log("GaugeTree - openOnDistance " + start + " " + end + " " +
                tree.getItemCount());

        for (Iterator<TreeItem> it = tree.treeItemIterator(); it.hasNext();) {
            TreeItem item = it.next();
            /* Strange stuff is happening here:
             * GWT Tree.treeItemIterator returns another TreeItem for each
             * GaugeInfoItem */
            if (item instanceof GaugeInfoItem) {
                boolean setstate = false;
                GaugeInfoItem gitem = (GaugeInfoItem)item;
                if (end == null) {
                    if (gitem.getStart() >= start) {
                        setstate = true;
                    }
                }
                else {
                    // as getStart()/getEnd() return Double objects, they can be null and
                    // can cause NPEs when comparing with double... strange...
                    if (gitem.getStart() != null && gitem.getEnd() != null) {
                        GWT.log("GaugeTree - openOnDistance gitem " + gitem.getStart() + " " + gitem.getEnd());
                        if ((start >= gitem.getStart() && start <= gitem.getEnd()) ||
                              (end >= gitem.getStart() &&   end <= gitem.getEnd()) ||
                            (start <= gitem.getStart() &&   end >= gitem.getEnd())) {
                            setstate = true;
                        }
                    }
                }
                item.setState(setstate);
            }
        }
    }

    public void openOnLocations(List<Double> locations) {
        GWT.log("GaugeTree - openOnLocations " + locations + " " +
                tree.getItemCount());

        if (locations == null || locations.isEmpty()) {
            return;
        }

        for (Iterator<TreeItem> it = tree.treeItemIterator(); it.hasNext();) {
            TreeItem item = it.next();
            if (item instanceof GaugeInfoItem) {
                GaugeInfoItem gitem = (GaugeInfoItem)item;
                boolean isset = false;
                for (Double location: locations) {
                    if (locations == null) {
                        continue;
                    }
                    if (location >= gitem.getStart() &&
                            location <= gitem.getEnd()) {
                        isset = true;
                        break;
                            }
                }
                item.setState(isset);
            }
        }
    }

    class GaugeInfoItem extends TreeItem {

        private GaugeInfo gauge;

        public GaugeInfoItem(FLYS flys, GaugeInfo gauge) {
            GaugeInfoHead gaugeinfohead = new GaugeInfoHead(flys, gauge);
            GaugeInfoPanel gaugeinfopanel = new GaugeInfoPanel(gauge);
            setWidget(gaugeinfohead);
            addItem(gaugeinfopanel);
            this.gauge = gauge;
        }

        public Double getStart() {
            return gauge.getKmStart();
        }

        public Double getEnd() {
            return gauge.getKmEnd();
        }

        public Long getReference() {
            return gauge.getOfficialNumber();
        }
    }

    class GaugeInfoHead extends HLayout {

        public GaugeInfoHead(FLYS flys, GaugeInfo gauge) {
            setStyleName("gaugeinfohead");
            setAutoHeight();
            setAutoWidth();

            NumberFormat nf = NumberFormat.getDecimalFormat();

            Label label = new Label(gauge.getName(), true);
            addMember(label);

            Double start;
            Double end;

            if (!gauge.isKmUp()) {
                start = gauge.getKmStart();
                end   = gauge.getKmEnd();
            }
            else {
                start = gauge.getKmEnd();
                end   = gauge.getKmStart();
            }

            String kmtext = "";
            if (start != null) {
                kmtext += nf.format(start);
                kmtext += " - ";
            }
            if (end != null) {
                kmtext += nf.format(end);
            }
            if (start != null || end != null) {
                kmtext += " km";
            }

            label = new Label(kmtext);

            addMember(label);

            Double station = gauge.getStation();
            if (station != null) {
                String stext = nf.format(station);
                stext += " km";
                label = new Label(stext);
                addMember(label);
            }

            Long number = gauge.getOfficialNumber();
            String url = number != null ?
                MSG.gauge_url() + number :
                MSG.gauge_url();
            Anchor anchor = new Anchor(MSG.gauge_info_link(), url, "_blank");
            addMember(anchor);

            addMember(new GaugeCurveAnchor(flys, gauge));
        }
    }

    class GaugeCurveAnchor extends Anchor implements ClickHandler {

        private FLYS flys;
        private GaugeInfo gauge;

        public GaugeCurveAnchor(FLYS flys, GaugeInfo gauge) {
            super(MSG.gauge_curve_link());
            this.flys = flys;
            this.gauge = gauge;

            addClickHandler(this);
        }

        @Override
        public void onClick(ClickEvent ev) {
            GWT.log("GaugeCurveAnchor - onClick " + gauge.getRiverName() +
                    " " + gauge.getOfficialNumber());
            flys.newGaugeDischargeCurve(gauge.getRiverName(),
                    gauge.getOfficialNumber());
        }
    }

    class GaugeInfoPanel extends DecoratorPanel {

        public GaugeInfoPanel(GaugeInfo gauge) {
            setStyleName("gaugeinfopanel");
            Grid grid = new Grid(4, 2);

            NumberFormat nf = NumberFormat.getDecimalFormat();

            Double minw = gauge.getMinW();
            Double maxw = gauge.getMaxW();
            if (minw != null && maxw != null) {
                grid.setText(0, 0, MSG.wq_value_q());
                grid.setText(0, 1, "" + nf.format(minw) +
                        " - " + nf.format(maxw));
            }

            Double minq = gauge.getMinQ();
            Double maxq = gauge.getMaxQ();
            if (minq != null && maxq != null) {
                grid.setText(1, 0, MSG.wq_value_w());
                grid.setText(1, 1, "" + nf.format(minq) +
                        " - " + nf.format(maxq));
            }

            Double aeo = gauge.getAeo();
            if (aeo != null) {
                grid.setText(2, 0, "AEO [kmĀ²]");
                grid.setText(2, 1, "" + nf.format(aeo));
            }

            Double datum = gauge.getDatum();
            if (datum != null) {
                grid.setText(3, 0, MSG.gauge_zero() + " [" +
                        gauge.getWstUnit() + "]");
                grid.setText(3, 1, "" + nf.format(datum));
            }

            setWidget(grid);
        }
    }

}

http://dive4elements.wald.intevation.org