org.integratedmodelling.aries.webapp.view.storyline.ModelStorylineView.java Source code

Java tutorial

Introduction

Here is the source code for org.integratedmodelling.aries.webapp.view.storyline.ModelStorylineView.java

Source

/*
Copyright 2011 The ARIES Consortium (http://www.ariesonline.org)
    
This file is part of ARIES.
    
ARIES is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published
by the Free Software Foundation, either version 3 of the License,
or (at your option) any later version.
    
ARIES is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with ARIES.  If not, see <http://www.gnu.org/licenses/>.
*/

package org.integratedmodelling.aries.webapp.view.storyline;

import java.awt.image.BufferedImage;
import java.util.ArrayList;

import org.apache.commons.lang.StringUtils;
import org.integratedmodelling.aries.webapp.view.AriesBrowser;
import org.integratedmodelling.aries.webapp.view.STYLE;
import org.integratedmodelling.aries.webapp.visualization.WebZKVisualization;
import org.integratedmodelling.corescience.interfaces.IObservationContext;
import org.integratedmodelling.modelling.context.Context;
import org.integratedmodelling.modelling.storyline.ModelStoryline;
import org.integratedmodelling.modelling.storyline.Storyline;
import org.integratedmodelling.modelling.visualization.VisualizationFactory;
import org.integratedmodelling.modelling.visualization.WebVisualization;
import org.integratedmodelling.modelling.visualization.storyline.StorylineTemplate;
import org.integratedmodelling.modelling.visualization.storyline.StorylineTemplate.Page;
import org.integratedmodelling.thinklab.exception.ThinklabException;
import org.integratedmodelling.thinklab.exception.ThinklabRuntimeException;
import org.integratedmodelling.thinklab.interfaces.knowledge.IConcept;
import org.integratedmodelling.thinklab.webapp.ZK;
import org.integratedmodelling.thinklab.webapp.ZK.ZKComponent;
import org.integratedmodelling.utils.Pair;
import org.integratedmodelling.utils.image.ImageUtil;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.MouseEvent;
import org.zkoss.zul.Div;

/**
 * The view that allows data display for a computed visualization, or information display for one still to be
 * computed. Should have methods to interact with the storyline (e.g. to start the computation) and if the
 * storyline has any children (scenarios) it should allow comparison of the computed data with its own.
 * 
 * @author Ferdinando
 *
 */
public class ModelStorylineView extends StorylineView {

    private StorylineControlPanel cpanel;
    int patch = -1;
    private String[] currentPlotType;
    private String covUrl = null;

    public ModelStorylineView(Storyline s, AriesBrowser browser, StorylineControlPanel badge) {

        super(s, browser);
        this.cpanel = badge;

        try {
            render();
        } catch (ThinklabException e) {
            throw new ThinklabRuntimeException(e);
        }
    }

    public StorylineControlPanel getControlPanel() {
        return cpanel;
    }

    public void initPages() throws ThinklabException {

        showSequence();
        currentPlotType = new String[getPageSequence().size()];
        for (int i = 0; i < getPageSequence().size(); i++) {
            currentPlotType[i] = getPageSequence().get(i).getPlotType() + ".png";
        }
    }

    private static final long serialVersionUID = -7984552889374835100L;

    protected String getImage() throws ThinklabException {

        String ret = null;

        if (currentPage < 0) {

            if (storyline.getStatus() == ModelStoryline.COMPUTING
                    || storyline.getStatus() == ModelStoryline.PENDING) {

                ret = "/aries/images/computing.png";
                patch = (VIEWPORT_Y - 2 - 166) / 2;

            } else if (storyline.getStatus() == ModelStoryline.COMPUTED) {

                ret = "/aries/images/computed.png";
                patch = (VIEWPORT_Y - 2 - 166) / 2;
                initPages();

            } else if (storyline.getContext() != null) {

                if (covUrl == null) {

                    Pair<Integer, Integer> xy = VisualizationFactory.get().getPlotSize(vx - 2, vy - 2,
                            storyline.getContext());
                    patch = (vy - 2 - xy.getSecond()) / 2;

                    Pair<String, String> zr = browser.getApplication().getNewResourceUrl(".png",
                            browser.getSession());

                    /*
                     * create coverage image
                     */
                    BufferedImage bim = storyline.getCoverageMap(xy.getFirst(), xy.getSecond());
                    if (bim != null) {
                        ImageUtil.saveImage(bim, zr.getFirst());
                    }

                    patch = (VIEWPORT_Y - 2 - xy.getSecond()) / 2;
                    covUrl = zr.getSecond();

                }
                ret = covUrl;
            }

        } else {

            Pair<Integer, Integer> xy = VisualizationFactory.get().getPlotSize(vx - 2, vy - 2,
                    storyline.getContext());

            patch = (vy - 2 - xy.getSecond()) / 2;

            ret = ((WebZKVisualization) (storyline.getVisualization()))
                    .getStateUrl(getPageSequence().get(currentPage).getConcept(), currentPlotType[currentPage]);
        }
        return ret;
    }

    @Override
    protected boolean isPageEnabled(StorylineTemplate.Page page) {
        return !page.getBoolean("disabled")
                && Context.getState(page.getConcept(), (IObservationContext) storyline.getContext()) != null;
    }

    @Override
    protected ZKComponent getRibbon(int width, int height) throws ThinklabException {

        ZKComponent ret = null;

        if (storyline.getStatus() == ModelStoryline.IDLE) {

            /*
             * TODO message, launch button
             */
            ret = ZK.vbox(ZK.spacer(28),
                    ZK.label("Click the play button in the sidebar to start computing this storyline."))
                    .align("center").sclass(STYLE.TEXT_LARGE_BOLD_GREY);

        } else if (storyline.getStatus() == ModelStoryline.COMPUTING) {

            /*
             * TODO icon, progress bar etc
             */
            ret = ZK.vbox(ZK.spacer(28),
                    ZK.label("The storyline is being computed. Results will appear in this area.")).align("center")
                    .sclass(STYLE.TEXT_LARGE_BOLD_GREY);

        } else if (storyline.getStatus() == ModelStoryline.ERROR) {

            /*
             * TODO "more info" link, icons etc.
             */
            ret = ZK.vbox(ZK.spacer(28), ZK.label("The computation ended with errors.")).align("center")
                    .sclass(STYLE.TEXT_LARGE_BOLD_RED);

        } else if (storyline.getStatus() == ModelStoryline.DISABLED) {
            ret = ZK.vbox(ZK.spacer(28), ZK.label("Computation of this storyline is not possible in this region."))
                    .align("center").sclass(STYLE.TEXT_LARGE_BOLD_GREY);
        } else {

            /*
             * Make the ribbon for the result dataset corresponding to the various pages.
             * Call the vis first or we won't get our sequence right the first time.
             */
            WebVisualization visualization = (WebZKVisualization) (storyline.getVisualization());

            if (visualization == null)
                return null;

            Pair<Integer, Integer> xy = VisualizationFactory.get().getPlotSize(110, 64, storyline.getContext());

            ArrayList<ZKComponent> components = new ArrayList<ZK.ZKComponent>();

            for (int i = 0; i < getPageSequence().size(); i++) {
                Page p = getPageSequence().get(i);
                final int idx = i;
                String img = visualization.getStateUrl(p.getConcept(), VisualizationFactory.PLOT_GEOSURFACE_2D);
                if (img != null) {
                    components.add(ZK
                            .div(ZK.vbox(
                                    ZK.image(img).width(xy.getFirst()).height(xy.getSecond())
                                            .sclass(currentPage == i ? STYLE.BRIGHT_BORDER : null),
                                    ZK.label(StringUtils.abbreviate(p.getName(), 24)).sclass(STYLE.TEXT_VERYSMALL)
                                            .align("center").fillx()))
                            .align("center").width(120).tooltip(p.getRunningHead()).hand()
                            .listener("onClick", new EventListener() {

                                @Override
                                public void onEvent(Event arg0) throws Exception {
                                    switchPage(idx);
                                }
                            }).tmargin(64 - xy.getSecond()));
                }
            }

            ret = ZK.ribbon(width, height, 120, components.toArray(new ZKComponent[components.size()]))
                    .selected(currentPage);
        }

        return ret;
    }

    @Override
    protected ZKComponent getImageArea(int width, int height) throws ThinklabException {

        String img = getImage();

        if (currentPage >= 0) {

            String units = getPageSequence().get(currentPage).get("units");

            String totals = "";

            String statsReq = getPageSequence().get(currentPage).get("statistics");
            if (statsReq != null && statsReq.contains("totals")) {
                totals = " " + ((WebZKVisualization) (storyline.getVisualization())).getAggregatedDescription(
                        getPageSequence().get(currentPage).getConcept(),
                        getPageSequence().get(currentPage).get("units"));

            } else {
                totals = " click map for values";
            }

            /*
             * list of buttons to switch images among the allowed views.
             */
            ArrayList<ZKComponent> ibuts = new ArrayList<ZK.ZKComponent>();
            ibuts.add(ZK.spacer(4));
            ibuts.add(ZK.imagebutton("/aries/images/" + getPageSequence().get(currentPage).getPlotType() + ".png")
                    .tooltip(VisualizationFactory
                            .getPlotDescription(getPageSequence().get(currentPage).getPlotType() + ".png"))
                    .listener("onClick", new EventListener() {
                        @Override
                        public void onEvent(Event arg0) throws Exception {
                            // TODO Auto-generated method stub
                            currentPlotType[currentPage] = getPageSequence().get(currentPage).getWith("plot-type",
                                    "default", "true") + ".png";
                            render();
                        }
                    }));

            for (String s : getPageSequence().get(currentPage).getAllWithout("plot-type", "default")) {
                final String zing = s;
                ibuts.add(ZK.imagebutton("/aries/images/" + s + ".png")
                        .tooltip(VisualizationFactory.getPlotDescription(s + ".png"))
                        .listener("onClick", new EventListener() {

                            @Override
                            public void onEvent(Event arg0) throws Exception {
                                // TODO Auto-generated method stub
                                currentPlotType[currentPage] = zing + ".png";
                                render();
                            }
                        }));
            }

            return ZK.div(ZK.vbox(ZK.div(

                    ZK.hbox(ZK
                            .div(ZK.vbox(ZK.spacer(8),
                                    ZK.hbox(ibuts.toArray(new ZKComponent[ibuts.size()])).spacing(4)))
                            .align("left"), ZK.spacer(6),
                            ZK.vbox(ZK.spacer(8),
                                    ZK.label(VisualizationFactory.getPlotDescription(currentPlotType[currentPage])
                                            + " :: " + totals)),
                            ZK.div(ZK.vbox(ZK.spacer(8), ZK.hbox(ZK.imagebutton("/aries/images/icons/camera_go.png")
                                    .listener("onClick", new EventListener() {

                                        @Override
                                        public void onEvent(Event arg0) throws Exception {
                                            //exportImages();
                                        }
                                    }).tooltip("Export the selected layer as a PNG image"),
                                    ZK.imagebutton("/aries/images/icons/folder_go.png")
                                            .listener("onClick", new EventListener() {

                                                @Override
                                                public void onEvent(Event arg0) throws Exception {
                                                    // exportGIS();
                                                }
                                            }).tooltip(
                                                    "Export the selected layer as a GeoTIFF file, suitable for GIS applications."),
                                    ZK.imagebutton("/aries/images/icons/google-earth.png")
                                            .listener("onClick", new EventListener() {
                                                @Override
                                                public void onEvent(Event arg0) throws Exception {
                                                    // exportKML();
                                                }
                                            }).tooltip("View the selected layer in Google Earth"),
                                    ZK.spacer(4)).spacing(4))).align("right"))
                            .fillx()

            ).sclass(STYLE.GLASSTOP_SMALL).width(vx).height(TOPBAR_H), ZK.div(
                    ZK.vbox(ZK.separator().height(patch), ZK.image(img).listener("onClick", new EventListener() {

                        @Override
                        public void onEvent(Event arg0) throws Exception {

                            int x = ((MouseEvent) arg0).getX();
                            int y = ((MouseEvent) arg0).getY();
                            showDataAt(getPageSequence().get(currentPage).getConcept(), x, y);
                        }
                    }))).align(
                            "center")
                    .sclass(STYLE.TEXTURED).width(width).height(height - BOTBAR_H - TOPBAR_H),
                    ZK.div(ZK.hbox(
                            ZK.div(ZK.vbox(ZK.spacer(20),
                                    ZK.hbox(ZK.spacer(16),
                                            ((WebZKVisualization) (storyline.getVisualization())).getLegend(
                                                    getPageSequence().get(currentPage).getConcept(), units,
                                                    currentPlotType[currentPage]))))
                                    .align("left"),
                            ZK.div().align("right").id("datawin")).fillx()

                    ).sclass(STYLE.GLASSBOTTOM_LARGE).width(vx).height(BOTBAR_H)).spacing(0)).width(width)
                    .height(height).sclass(STYLE.BORDERED_SUNK);
        }

        /*
         * TODO
         * no map to show
         */
        return ZK.div(ZK.vbox(ZK.separator().height(patch), ZK.image(getImage()))).align("center")
                .sclass(STYLE.TEXTURED_SUNK).width(width).height(height);
    }

    private void showDataAt(IConcept concept, int imgX, int imgY) throws ThinklabException {

        Div div = (Div) ZK.getComponentById(this, "datawin");

        ZKComponent content = ZK.vbox(ZK.hbox(((WebZKVisualization) (storyline.getVisualization()))
                .getStateDescriptionAt(concept, imgX, imgY, getPageSequence().get(currentPage).get("units")),
                ZK.bar(),
                ZK.vbox(ZK.spacer(12),
                        ((WebZKVisualization) (storyline.getVisualization())).getLatLonDescriptionAt(imgX, imgY)),
                ZK.spacer(12)));

        ZK.resetComponent(div);
        div.appendChild(content.get());
    }

    public void initialize(Storyline sl, AriesBrowser browser, StorylineControlPanel badge) {

        initialize(sl, browser);
        this.cpanel = badge;
        try {
            render();
        } catch (ThinklabException e) {
            throw new ThinklabRuntimeException(e);
        }
    }
}