package com.smartgwt.sample.client.cube.advanced;

import java.util.Date;

import com.google.gwt.core.client.EntryPoint;
import com.smartgwt.client.data.AdvancedCriteria;
import com.smartgwt.client.data.DSRequest;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.RecordList;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.AutoSelectionModel;
import com.smartgwt.client.types.ExportDisplay;
import com.smartgwt.client.types.ExportFormat;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.types.VerticalAlignment;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.Label;
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.cube.events.FacetAddedEvent;
import com.smartgwt.client.widgets.cube.events.FacetAddedHandler;
import com.smartgwt.client.widgets.cube.events.FacetMovedEvent;
import com.smartgwt.client.widgets.cube.events.FacetMovedHandler;
import com.smartgwt.client.widgets.cube.events.FixedFacetValueChangedEvent;
import com.smartgwt.client.widgets.cube.events.FixedFacetValueChangedHandler;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.grid.HoverCustomizer;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.menu.MenuButton;

public class AdvancedCubeSample implements EntryPoint {
    private CubeGrid advancedCube;
    private Label reportLabel;
    private FacetList rowFacetList;
    private FacetList colFacetList;
    private Button exportButton;

    public void onModuleLoad() {
        createAdvancedCube();

        Canvas controlCanvas = getFacetControls();

        // Label to show current state of CubeGrid facets
        reportLabel = new Label();
        reportLabel.setWidth(500);
        reportLabel.setHeight(30);
        reportLabel.setWrap(false);
        reportLabel.setOverflow(Overflow.VISIBLE);
        reportLabel.setPadding(5);
        reportLabel.setBorder("1px solid black");
        reportLabel.setStyleName("blackOnWhite");
        reportLabel.setAlign(Alignment.CENTER);
        reportLabel.setValign(VerticalAlignment.CENTER);
        reportLabel.setLayoutAlign(Alignment.CENTER);

        VLayout mainLayout = new VLayout();
        mainLayout.setWidth100();
        mainLayout.setHeight100();
        mainLayout.setMembersMargin(8);
        mainLayout.setLayoutMargin(10);
        mainLayout.setMembers(controlCanvas, reportLabel, advancedCube);

        updateLists();
        updateLabels();

        mainLayout.draw();
    }

    private void createAdvancedCube() {

        advancedCube = new CubeGrid();
        advancedCube.setAutoFetchData(true);

        //in order to enable charting, the Drawing module must be present
        if(SC.hasDrawing()) {
            advancedCube.setEnableCharting(true);
        }

        // Facet definitions
        Facet[] dims = FourDimensionFacets.getFourDimensionFacets();

        //We need to add a dummy dimension because
        //CubeGrid requires both a row and column dimension (Facet)
        Facet dummyFacet = new Facet("CODE");
    	dummyFacet.setTitle("Dummy Facet");
    	dummyFacet.setValues(new FacetValue("TEST1","Values"));
    	dummyFacet.setCanMinimize(false);
    	dummyFacet.setCanCollapse(Boolean.FALSE);
    	dummyFacet.setSynchColumnLayout(true);
    	
    	Facet[] allFacets = new Facet[dims.length+1];
    	for(int x=0;x<dims.length;x++){
    		allFacets[x]=dims[x];
    	}
    	allFacets[dims.length]=dummyFacet;
    	
        advancedCube.setFacets(allFacets);
        
        //Setup initial Criteria so we have something to retrieve
        AdvancedCriteria crit = new AdvancedCriteria();
		crit.addCriteria("CODE","TEST1");
		crit.addCriteria("EFFECTIVE_DT",new Date());
		advancedCube.setInitialCriteria(crit);
		
        advancedCube.setDataSource(DataSource.get("fourDimensions"));

        advancedCube.setValueProperty("AMT_VALUE");
        advancedCube.setCellIdProperty("ROWNUMBER");

        advancedCube.setColumnFacets("DIM1_OCCUR_NO", dummyFacet.getIdAsString());
        advancedCube.setRowFacets("DIM2_OCCUR_NO");
        FacetValueMap fixedFacetValues = new FacetValueMap();

        fixedFacetValues.addMapping("DIM3_OCCUR_NO", "1");
        fixedFacetValues.addMapping("DIM4_OCCUR_NO", "1");
        advancedCube.setFixedFacetValues(fixedFacetValues);

        advancedCube.setCanHover(true);
        advancedCube.setShowCellContextMenus(true);

        advancedCube.setHoverCustomizer(new HoverCustomizer() {
            @Override
            public String hoverHTML(Object value, ListGridRecord record, int rowNum,
                                    int colNum) {
                if (record != null) {
                    return "cell value: " + record.getAttribute("value")
                            + "<br>cell ID: " + record.getAttribute("cellID");
                }
                return null;
            }
        });

        advancedCube.setHoverHeight(20);
        advancedCube.setHoverWidth(150);
        advancedCube.setValueTitle("Amount");
        advancedCube.setCanCollapseFacets(true);
        advancedCube.setCanMinimizeFacets(true);
        advancedCube.setAutoSelectValues(AutoSelectionModel.BOTH);

        advancedCube.setRowHeaderGridMode(true);
        advancedCube.setCanMoveFacets(true);

        advancedCube.addFacetAddedHandler(new FacetAddedHandler() {
            @Override
            public void onFacetAdded(FacetAddedEvent event) {
                updateLists();
                updateLabels();
            }
        });

        advancedCube.addFacetMovedHandler(new FacetMovedHandler() {
            @Override
            public void onFacetMoved(FacetMovedEvent event) {
                updateLabels();
                updateLists();
            }
        });

        advancedCube.addFixedFacetValueChangedHandler(new FixedFacetValueChangedHandler() {
            @Override
            public void onFixedFacetValueChanged(FixedFacetValueChangedEvent event) {
                updateLabels();
                updateLists();
            }
        });
    }

    private Canvas getFacetControls() {

        String[] facetIds = new String[]{"DIM1_OCCUR_NO", "DIM2_OCCUR_NO", "DIM3_OCCUR_NO", "DIM4_OCCUR_NO"};

        VLayout menuButtonStack = new VLayout();
        menuButtonStack.setWidth(175);
        menuButtonStack.setMembersMargin(20);

        // Create the FacetMenuButtons, and FacetMenus for each facet
        for (int i = 0; i < facetIds.length; i++) {
            String facetId = facetIds[i];
            FacetMenuButton button = new FacetMenuButton(facetId);
            FacetMenu menu = new FacetMenu(advancedCube, facetId);

            button.setMenu(menu);
            menuButtonStack.addMember(button);
        }

        // Create 2 ListGrids as an alternative UI for drag-rearranging facets
        rowFacetList = new FacetList(advancedCube, true);
        rowFacetList.setFields(new ListGridField("title", "Row Facets"));
        rowFacetList.setWidth(150);
        rowFacetList.setHeight(150);
        rowFacetList.setLeft(250);

        colFacetList = new FacetList(advancedCube, false);
        colFacetList.setFields(new ListGridField("title", "Column Facets"));
        colFacetList.setLeft(450);
        colFacetList.setHeight(150);
        colFacetList.setWidth(150);

        exportButton = new Button("Export");
        exportButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                DSRequest dsRequestProperties = new DSRequest();
                dsRequestProperties.setExportAs(ExportFormat.XLS);
                dsRequestProperties.setExportDisplay(ExportDisplay.DOWNLOAD);
                advancedCube.exportClientData(dsRequestProperties);            
            }
        });
        exportButton.setTop(125);
        exportButton.setLeft(675);

        // Combine the controls into a single canvas for easy UI management
        Canvas controlCanvas = new Canvas();
        controlCanvas.setWidth(775);
        controlCanvas.setHeight(150);
        controlCanvas.setOverflow(Overflow.HIDDEN);
        controlCanvas.setLayoutAlign(Alignment.CENTER);
        controlCanvas.addChild(menuButtonStack);
        controlCanvas.addChild(rowFacetList);
        controlCanvas.addChild(colFacetList);
        controlCanvas.addChild(exportButton);

        return controlCanvas;
    }

    public void updateLists() {
        // Update the data for each ListGrid based on the rowFacets / columnFacets arrays
        // for the CubeGrid
        RecordList rowFacetData = new RecordList();
        String[] rowFacets = advancedCube.getRowFacets();
        for (int i = 0; i < rowFacets.length; i++) {
            Facet facet = advancedCube.getFacet(rowFacets[i]);
            ListGridRecord facetRecord = new ListGridRecord();
            facetRecord.setAttribute("id", facet.getId());
            facetRecord.setAttribute("title", facet.getTitle());

            rowFacetData.add(facetRecord);
        }
        rowFacetList.setData(rowFacetData);

        RecordList colFacetData = new RecordList();
        String[] colFacets = advancedCube.getColumnFacets();
        for (int i = 0; i < colFacets.length; i++) {
            Facet facet = advancedCube.getFacet(colFacets[i]);
            ListGridRecord facetRecord = new ListGridRecord();
            facetRecord.setAttribute("id", facet.getId());
            facetRecord.setAttribute("title", facet.getTitle());

            colFacetData.add(facetRecord);
        }
        colFacetList.setData(colFacetData);

    }

    public void updateLabels() {
        // Fixed facet values
        // Update menus and assemble descriptive string
        FacetValueMap fixedValues = advancedCube.getFixedFacetValues();
        String[] fixedFacets = fixedValues.getAttributes();
        String fixedValuesString = "<B>Report - fixed values: ";
        if (fixedFacets.length == 0) {
            fixedValuesString += "none.</B>";
        } else {
            for (int i = 0; i < fixedFacets.length; i++) {
                String facetId = fixedFacets[i];
                FacetValue fv = advancedCube.getFacetValue(facetId, fixedValues.getAttribute(facetId));

                MenuButton button = (MenuButton) Canvas.getById(facetId + "Button");
                button.setTitle("<b>" + facetId + "</b>: [" + fv.getTitle() + "]");
                fixedValuesString += (i == 0 ? " " : ", ") + facetId + ": <i>'" + fv.getTitle() + "'</i>";
            }
            fixedValuesString += "</B>";
        }
        reportLabel.setContents(fixedValuesString);

        String[] rowFacets = advancedCube.getRowFacets();
        for (int i = 0; i < rowFacets.length; i++) {
            String facetId = rowFacets[i];
            MenuButton button = (MenuButton) Canvas.getById(facetId + "Button");
            if (button != null) button.setTitle("<b>" + facetId + "</b>: [ in Rows ]");
        }

        String[] colFacets = advancedCube.getColumnFacets();
        for (int i = 0; i < colFacets.length; i++) {
            String facetId = colFacets[i];
            MenuButton button = (MenuButton) Canvas.getById(facetId + "Button");
            if (button != null) button.setTitle("<b>" + facetId + "</b>: [ in Columns ]");
        }
    }

	
	
	
}