package com.mars.helios.heliosweb.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.Timer;
import com.smartgwt.client.core.Function;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.cube.CubeGrid;
import com.smartgwt.client.widgets.cube.Facet;
import com.smartgwt.client.widgets.cube.FacetValue;
import com.smartgwt.client.widgets.cube.FacetValueMap;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
import com.smartgwt.client.widgets.toolbar.ToolStripButton;
import java.util.HashSet;
import java.util.Set;

/**
 * Entry point classes define
 * <code>onModuleLoad()</code>.
 */
public class HeliosWeb implements EntryPoint {

    private final HeliosGinjector injector = GWT.create(HeliosGinjector.class);

    /**
     * This is the entry point method.
     */
    @Override
    public void onModuleLoad() {
        GWT.setUncaughtExceptionHandler(new HeliosUncaughtExceptionHandler());
        // see http://code.google.com/p/google-web-toolkit/issues/detail?id=1617
        Timer timer = new Timer() {
            @Override
            public void run() {
                actualLoading();
            }
        };

        timer.schedule(1);
    }

    public void actualLoading() {
        SC.logInfo("Starting sandbox setup");

        /*
         * Cube setup
         */

        String[] firstNames = {"Alfred", "Bob", "Charles", "David", "Emilien",
            "Fabrice", "Gerard", "Henri", "Ignace", "Julien", "Kevin", "Lucien",
            "Maurice", "Nicolas", "Olivier", "Patrick", "Quentin", "Robert", "Stéphane",
            "Thomas", "Ulysse", "Vincent", "William", "Xavier", "Yves", "Zoe"};
        String[] lastNames = {"Arbogast", "Becht", "Cuvier", "Durand", "Einstein",
            "Frot", "Goncalves", "Herbillaut", "Ibrahimovitch", "Jugnot", "Klein",
            "Lienhardt", "Michu", "Nolam", "Obama", "Pastewski", "Quirin", "Ribero",
            "Stendhal", "Tallerand", "Urban", "Vinci", "Wagner", "Xenakis", "Yserand",
            "Zand"};


        Facet facet1 = new Facet("FirstName");
        createFacetValues(facet1, firstNames);

        Facet facet2 = new Facet("LastName");
        createFacetValues(facet2, lastNames);
        Facet facet3 = new Facet("Period");
        createPeriodValues(facet3, 300);

        final CubeGrid cubeGrid = new CubeGrid();
        cubeGrid.setDataSource(new MyDS());

        cubeGrid.setWidth100();
        cubeGrid.setHeight100();
        cubeGrid.setHideEmptyFacetValues(false);
        cubeGrid.setShowCellContextMenus(true);

        cubeGrid.setFacets(facet1, facet2, facet3);
        cubeGrid.setColumnFacets("Period");
        cubeGrid.setRowFacets("FirstName", "LastName");
        cubeGrid.setValueProperty("Value");

        cubeGrid.setAutoFetchData(true);
        cubeGrid.fetchData();

        cubeGrid.setCanEdit(true);
        cubeGrid.setAutoSaveEdits(false);

        /*
         * Setup toolbar
         */

        ToolStripButton btSetRandomValue = new ToolStripButton("Set value to Alfred/Durand/P300");
        btSetRandomValue.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                String updatedValue = "42";
                FacetValueMap valueMap = new FacetValueMap();
                valueMap.addMapping("FirstName", "Alfred");
                valueMap.addMapping("LastName", "Durand");
                valueMap.addMapping("Period", "P300");
                int calcRow = cubeGrid.getFacetValuesRow(valueMap);
                int calcCol = cubeGrid.getFacetValuesColumn(valueMap);
                cubeGrid.setEditValue(calcRow, calcCol, updatedValue);
                SC.logInfo("Value set to " + updatedValue + " at " + calcRow + "/" + calcCol);
            }
        });

        ToolStripButton btSave = new ToolStripButton("Save");
        btSave.addClickHandler(new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                SC.logInfo("Changes before apply: " + cubeGrid.hasChanges());
                cubeGrid.saveAllEdits(new Function() {
                    @Override
                    public void execute() {
                        SC.logInfo("Call back return : " + cubeGrid.hasChanges());
                    }
                });
                SC.logInfo("Changes after apply: " + cubeGrid.hasChanges());
            }
        });

        ToolStrip toolStrip = new ToolStrip();
        toolStrip.addButton(btSetRandomValue);
        toolStrip.addButton(btSave);

        VLayout layout = new VLayout();
        layout.setWidth100();
        layout.setHeight100();
        layout.addMember(toolStrip);
        layout.addMember(cubeGrid);

        layout.draw();
        SC.logInfo("Setup done !");
    }

    private void createFacetValues(Facet facet, String[] facetValues) {
        Set<FacetValue> values = new HashSet<FacetValue>();

        for (String value : facetValues) {
            values.add(new FacetValue(value, value));
        }

        facet.setValues(values.toArray(new FacetValue[0]));
    }

    private void createPeriodValues(Facet facet, int periods) {
        Set<FacetValue> values = new HashSet<FacetValue>();
        for (int i = 1; i <= periods; i++) {
            String period = "" + i;

            while (period.length() < 3) {
                period = "0" + period;
            }

            period = "P" + period;

            values.add(new FacetValue(period, period));
        }

        facet.setValues(values.toArray(new FacetValue[0]));
    }
}
