view flys-client/src/main/java/de/intevation/flys/client/client/ui/GaugePanel.java @ 3840:cf64f54aa39c

Refactor to avoid code duplication flys-client/trunk@5555 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Bjoern Ricks <bjoern.ricks@intevation.de>
date Fri, 21 Sep 2012 11:34:28 +0000
parents 509ef6ec93af
children 5877d6900e34
line wrap: on
line source
package de.intevation.flys.client.client.ui;

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

import com.google.gwt.core.client.GWT;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;
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.HorizontalPanel;
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.types.Overflow;
import com.smartgwt.client.widgets.events.ResizedEvent;
import com.smartgwt.client.widgets.events.ResizedHandler;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.SectionStackSection;
import com.smartgwt.client.widgets.layout.VLayout;

import de.intevation.flys.client.client.FLYSConstants;
import de.intevation.flys.client.client.services.GaugeOverviewInfoService;
import de.intevation.flys.client.client.services.GaugeOverviewInfoServiceAsync;
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;

/**
 * The GaugePanel is intendet to be used within a SectionStackSection
 * It extends the VLayout by two methods to show and hide the
 * section stack section.
 */
public class GaugePanel extends VLayout implements ResizedHandler {

    /** SectionStackSection where this GaugePanel belongs in*/
    private SectionStackSection sectionStack;

    /** Name of the river */
    private String river;

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

    protected GaugeOverviewInfoServiceAsync gaugeOverviewInfoService =
        GWT.create(GaugeOverviewInfoService.class);

    protected GaugeTree gaugetree = new GaugeTree();

    protected RiverInfoPanel riverinfopanel;

    /**
     * Creates a new VLayout with a SectionStackSection
     * The GaugePanel's SectionStackSection is hidden by default.
     * @param sectionStack The section stack section to place the VLayout in.
     */
    public GaugePanel(SectionStackSection sectionStack) {
        setOverflow(Overflow.HIDDEN);
        sectionStack.setHidden(true);
        sectionStack.setItems(this);
        this.sectionStack = sectionStack;
        setStyleName("gaugepanel");
        addResizedHandler(this);
    }

    /**
     * Sets and loads the river data if river is not the current set river
     */
    public void setRiver(String river) {
        if (!river.equals(this.river)) {
            this.river = river;
            this.refresh();
        }
    }

    /**
     * Sets the data and closes not corresponding folds in the gauge tree
     */
    public void setData(DataList[] data) {
        gaugetree.setData(data);
    }

    /**
     * Loads the river info and renders it afterwards
     */
    public void refresh() {
        gaugeOverviewInfoService.getRiverInfo(this.river, new AsyncCallback<RiverInfo>() {
            public void onFailure(Throwable e) {
                GWT.log("Could not load the river info." + e);
            }

            public void onSuccess(RiverInfo riverinfo) {
                GWT.log("Loaded river info");
                renderGaugeOverviewInfo(riverinfo);
            }
        });
    }

    public void renderGaugeOverviewInfo(RiverInfo riverinfo) {
        removeMembers(getMembers());

        riverinfopanel = new RiverInfoPanel(riverinfo);
        addMember(riverinfopanel);
        addMember(gaugetree);

        gaugetree.setGauges(riverinfo);
    }

    @Override
    public void onResized(ResizedEvent event) {
        /* this height calculation is only an approximation and doesn't reflect
         * the real height of the the gaugetree. */
        int height = getInnerContentHeight() -
            (RiverInfoPanel.HEIGHT +
            (2 * RiverInfoPanel.BORDER_WIDTH) +
            (2 * RiverInfoPanel.PADDING) +
            (2 * RiverInfoPanel.MARGIN));

        if (height < 0) {
            height = 0;
        }

        gaugetree.setHeight("" + height + "px");
    }


    /**
     * Hide the section stack section.
     */
    public void hide() {
        GWT.log("GaugePanel - hide");
        this.sectionStack.setHidden(true);
    }

    /**
     * Show the section stack section.
     */
    public void show() {
        GWT.log("GaugePanel - show");
        this.sectionStack.setHidden(false);
    }

    class GaugeTree extends ScrollPanel {

        private Tree tree;
        private DataList[] data;

        public GaugeTree() {
            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(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> curvelocations = 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.distance") ||
                            state.equals("state.winfo.distance_only") ||
                            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_mode")) {
                                GWT.log("GaugeTree - setData - ld_mode " + d.getStringValue());
                            }
                        }

                        if (ldfrom != null) {
                            openOnDistance(ldfrom, ldto);
                            return;
                        }
                    }
                    else if (state.equals("state.winfo.location")) {
                        ArrayList<Double> locations = new ArrayList<Double>();
                        for (int j = dl.size()-1; j >= 0; --j) {
                            Data d = dl.get(j);
                            String label = d.getLabel();
                            GWT.log("GaugeTree - setData - location label " +
                                    label + " " + d.getStringValue());
                            if (label.equals("ld_locations")) {
                                getLocations(locations, d.getItems());
                            }
                        }
                        openOnLocations(locations);
                        return;
                    }
                    else if (state.equals("state.winfo.reference.curve.input.start")) {
                        for (int j = dl.size()-1; j >= 0; --j) {
                            Data d = dl.get(j);
                            String label = d.getLabel();
                            if (label.equals("reference_startpoint")) {
                                getLocations(curvelocations, d.getItems());
                            }
                        }
                    }
                    else if (state.equals("state.winfo.reference.curve.input.end")) {
                        for (int j = dl.size()-1; j >= 0; --j) {
                            Data d = dl.get(j);
                            String label = d.getLabel();
                            if (label.equals("reference_endpoint")) {
                                getLocations(curvelocations, d.getItems());
                            }
                        }
                    }
                    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) {
                                    Integer gaugereference = Integer.valueOf(tmp);
                                    if (gaugereference != null) {
                                    }
                                }
                            }
                        }
                    }
                }
            }
            if (!curvelocations.isEmpty()) {
                openOnLocations(curvelocations);
            }
            else {
                openAll();
            }
        }

        private void getLocations(List<Double> locations, DataItem[] items) {
            for (int k = 0; k < items.length; k++) {
                String tmp = items[k].getStringValue();
                if (tmp != null) {
                    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 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 {
                        if ((gitem.getStart() >= start && gitem.getStart() <= end) ||
                                (gitem.getEnd() >= start && gitem.getEnd() <= end)) {
                            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 RiverInfoPanel extends HorizontalPanel {

        public final static int HEIGHT = 30;
        public final static int BORDER_WIDTH = 3;
        public final static int PADDING = 8;
        public final static int MARGIN = 10;

        public RiverInfoPanel(RiverInfo riverinfo) {
            setStyleName("riverinfopanel");
            setHeight("" + HEIGHT + "px");
            setVerticalAlignment(ALIGN_MIDDLE);

            NumberFormat nf = NumberFormat.getDecimalFormat();

            addLabel(riverinfo.getName(), false);

            String kmtext = "";
            Double start = riverinfo.getKmStart();
            Double end = riverinfo.getKmEnd();

            if (!riverinfo.isKmUp()) {
                Double tmp = end;
                end = start;
                start = tmp;
            }
            if (end != null) {
                kmtext += nf.format(end);
                kmtext += " - ";
            }
            if (start != null) {
                kmtext += nf.format(start);
            }
            kmtext += " km";

            addLabel(kmtext, false);

            String qtext = "";
            Double qmin = riverinfo.getMinQ();
            Double qmax = riverinfo.getMaxQ();
            if (qmin != null) {
                qtext += nf.format(qmin);
                qtext += " " + MSG.gauge_q_unit();
                qtext += " - ";
            }
            if (qmax != null) {
                qtext += nf.format(qmax);
                qtext += " " + MSG.gauge_q_unit();
            }

            addLabel(qtext, false);

            Anchor anchor = new Anchor(MSG.gauge_river_info_link(), riverinfo.getInfoURL());
            add(anchor);
        }

        private void addLabel(String text, boolean wordwrap) {
            Label label = new Label(text, wordwrap);
            add(label);
            setCellHeight(label, "" + HEIGHT + "px");
        }
    }

    class GaugeInfoItem extends TreeItem {

        private GaugeInfo gauge;

        public GaugeInfoItem(GaugeInfo gauge) {
            GaugeInfoHead gaugeinfohead = new GaugeInfoHead(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();
        }
    }

    class GaugeInfoHead extends HLayout {

        public GaugeInfoHead(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);
            }

            addMember(new Anchor(MSG.gauge_info_link(), gauge.getInfoURL()));
        }
    }

    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