package com.smartgwt.sample.client;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Date;  
import java.util.Set;

import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.RichTextItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.events.ChangedEvent;
import com.smartgwt.client.widgets.form.fields.events.ChangedHandler;
import com.smartgwt.client.widgets.grid.ListGridRecord;  

import java.util.Date;  

import com.smartgwt.client.data.Criteria;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.RecordList;
import com.smartgwt.client.types.Alignment;  
import com.smartgwt.client.types.AutoFitWidthApproach;
import com.smartgwt.client.types.AutoSelectionModel;
import com.smartgwt.client.types.Autofit;
import com.smartgwt.client.types.ListGridFieldType;  
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.util.JSOHelper;
import com.smartgwt.client.util.JSON;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;  
import com.smartgwt.client.widgets.IButton;  
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.events.DrawEvent;
import com.smartgwt.client.widgets.events.DrawHandler;
import com.smartgwt.client.widgets.grid.ListGrid;  
import com.smartgwt.client.widgets.grid.ListGridEditorContext;
import com.smartgwt.client.widgets.grid.ListGridEditorCustomizer;
import com.smartgwt.client.widgets.grid.ListGridField;  
  
import com.google.gwt.core.client.EntryPoint;  
  

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

        String json = getJson();
        RecordList reclist = new RecordList();
        String[] decoded = JSOHelper.convertToJavaStringArray(JSON.decode(json));
        for (String mapToDecode : decoded) {
        	Map<String, Object> map = JSOHelper.convertToMap((JSON.decode(mapToDecode)));
        	Record rec = new Record(map);
        	reclist.add(rec);
        	logToSC(rec.toMap()+"");
        }
        
      Canvas canvas = new Canvas(); 
      canvas.setHeight100();
      canvas.setWidth100();
      canvas.setOverflow(Overflow.AUTO);
      
      final CubeGrid cubeGrid = new CubeGrid();
        cubeGrid.setFacets(getCustomFacets(reclist.toArray()));
		cubeGrid.setRowFacets("PNR_StageName","metric");
		cubeGrid.setColumnFacets("ProjName_Revision","Block_Name", "Layout_Rundir_Name","Synth_Install_Name");
		cubeGrid.setValueProperty("Value");
		cubeGrid.setEmptyCellValue("EMPTY");
		cubeGrid.setWidth100();
		cubeGrid.setHeight100();
		cubeGrid.setAutoFitFieldsFillViewport(false);
		cubeGrid.setData(reclist);
		cubeGrid.setHideEmptyFacetValues(true);
		cubeGrid.setAutoFitWidthApproach(AutoFitWidthApproach.BOTH);
//		cubeGrid.setAutoFitData(Autofit.BOTH);
		FacetValue val = cubeGrid.getFacetValue("metric", "MacroCellArea");
		
		cubeGrid.getFacet("PNR_StageName").setWidth(300);
		cubeGrid.getFacet("metric").setWidth(300);
		
		cubeGrid.addDrawHandler(new DrawHandler(){

			@Override
			public void onDraw(DrawEvent event) {
				cubeGrid.autoFitFields();
			}});
		
	  canvas.addChild(cubeGrid);

      canvas.draw();  
	}
	
	
	public static native void logToSC(String msg) /*-{
	$wnd.isc.logWarn(msg);
	}-*/;
	
	private String getJson() {
		return "[\"{\\\"title\\\":\\\"TotalWorst\\\",\\\"Value\\\":0E-9,\\\"Layout_Rundir_Name\\\":\\\"EXP_0805_Base_minus_175_move_place_groups\\\",\\\"PNR_StageName\\\":\\\"place_opt\\\",\\\"metric\\\":\\\"place_opt;Delay Per MM;SS092125;functional;budgeted_inputs_gisbports2reg;TotalWorst\\\",\\\"Block_Name\\\":\\\"hvdp1_top\\\",\\\"Synth_Install_Name\\\":\\\"2016_08_08.00_22_final_syn\\\",\\\"Parent_Id\\\":\\\"place_opt;Delay Per MM;SS092125;functional;budgeted_inputs_gisbports2reg\\\",\\\"Level_Id\\\":\\\"place_opt;Delay Per MM;SS092125;functional;budgeted_inputs_gisbports2reg;TotalWorst\\\",\\\"ProjName_Revision\\\":\\\"BCM7278 A0\\\"}\",\"{\\\"Layout_Rundir_Name\\\":\\\"EXP_0805_Base_minus_175_move_place_groups\\\",\\\"PNR_StageName\\\":\\\"place_opt\\\",\\\"Value\\\":\\\"empty\\\",\\\"title\\\":\\\"Delay Per MM\\\",\\\"metric\\\":\\\"place_opt;Delay Per MM\\\",\\\"Block_Name\\\":\\\"hvdp1_top\\\",\\\"Synth_Install_Name\\\":\\\"2016_08_08.00_22_final_syn\\\",\\\"Parent_Id\\\":\\\"-1\\\",\\\"ProjName_Revision\\\":\\\"BCM7278 A0\\\",\\\"Level_Id\\\":\\\"place_opt;Delay Per MM\\\"}\",\"{\\\"Layout_Rundir_Name\\\":\\\"EXP_0805_Base_minus_175_move_place_groups\\\",\\\"PNR_StageName\\\":\\\"place_opt\\\",\\\"Value\\\":\\\"empty\\\",\\\"title\\\":\\\"SS092125\\\",\\\"metric\\\":\\\"place_opt;Delay Per MM;SS092125\\\",\\\"Block_Name\\\":\\\"hvdp1_top\\\",\\\"Synth_Install_Name\\\":\\\"2016_08_08.00_22_final_syn\\\",\\\"Parent_Id\\\":\\\"place_opt;Delay Per MM\\\",\\\"ProjName_Revision\\\":\\\"BCM7278 A0\\\",\\\"Level_Id\\\":\\\"place_opt;Delay Per MM;SS092125\\\"}\",\"{\\\"Layout_Rundir_Name\\\":\\\"EXP_0805_Base_minus_175_move_place_groups\\\",\\\"PNR_StageName\\\":\\\"place_opt\\\",\\\"Value\\\":\\\"empty\\\",\\\"title\\\":\\\"functional\\\",\\\"metric\\\":\\\"place_opt;Delay Per MM;SS092125;functional\\\",\\\"Block_Name\\\":\\\"hvdp1_top\\\",\\\"Synth_Install_Name\\\":\\\"2016_08_08.00_22_final_syn\\\",\\\"Parent_Id\\\":\\\"place_opt;Delay Per MM;SS092125\\\",\\\"ProjName_Revision\\\":\\\"BCM7278 A0\\\",\\\"Level_Id\\\":\\\"place_opt;Delay Per MM;SS092125;functional\\\"}\",\"{\\\"Layout_Rundir_Name\\\":\\\"EXP_0805_Base_minus_175_move_place_groups\\\",\\\"PNR_StageName\\\":\\\"place_opt\\\",\\\"Value\\\":\\\"empty\\\",\\\"title\\\":\\\"budgeted_inputs_gisbports2reg\\\",\\\"metric\\\":\\\"place_opt;Delay Per MM;SS092125;functional;budgeted_inputs_gisbports2reg\\\",\\\"Block_Name\\\":\\\"hvdp1_top\\\",\\\"Synth_Install_Name\\\":\\\"2016_08_08.00_22_final_syn\\\",\\\"Parent_Id\\\":\\\"place_opt;Delay Per MM;SS092125;functional\\\",\\\"ProjName_Revision\\\":\\\"BCM7278 A0\\\",\\\"Level_Id\\\":\\\"place_opt;Delay Per MM;SS092125;functional;budgeted_inputs_gisbports2reg\\\"}\",\"{\\\"title\\\":\\\"TotalCount\\\",\\\"Value\\\":1,\\\"Layout_Rundir_Name\\\":\\\"EXP_0805_Base_minus_175_move_place_groups\\\",\\\"PNR_StageName\\\":\\\"place_opt\\\",\\\"metric\\\":\\\"place_opt;Delay Per MM;SS092125;functional;budgeted_inputs_gisbports2reg;TotalCount\\\",\\\"Block_Name\\\":\\\"hvdp1_top\\\",\\\"Synth_Install_Name\\\":\\\"2016_08_08.00_22_final_syn\\\",\\\"Parent_Id\\\":\\\"place_opt;Delay Per MM;SS092125;functional;budgeted_inputs_gisbports2reg\\\",\\\"Level_Id\\\":\\\"place_opt;Delay Per MM;SS092125;functional;budgeted_inputs_gisbports2reg;TotalCount\\\",\\\"ProjName_Revision\\\":\\\"BCM7278 A0\\\"}\",\"{\\\"title\\\":\\\"Comment\\\",\\\"Value\\\":\\\"this is a very long comment. this is asdsads adsada sdsaa sadas dsaa very long chis is a very long comment. \\\",\\\"Layout_Rundir_Name\\\":\\\"EXP_0805_Base_minus_175_move_place_groups\\\",\\\"PNR_StageName\\\":\\\"place_opt\\\",\\\"metric\\\":\\\"place_opt;Delay Per MM;SS092125;functional;budgeted_inputs_gisbports2reg;Comment\\\",\\\"Block_Name\\\":\\\"hvdp1_top\\\",\\\"Synth_Install_Name\\\":\\\"2016_08_08.00_22_final_syn\\\",\\\"Parent_Id\\\":\\\"place_opt;Delay Per MM;SS092125;functional;budgeted_inputs_gisbports2reg\\\",\\\"Level_Id\\\":\\\"place_opt;Delay Per MM;SS092125;functional;budgeted_inputs_gisbports2reg;Comment\\\",\\\"ProjName_Revision\\\":\\\"BCM7278 A0\\\"}\",\"{\\\"title\\\":\\\"TotalSum\\\",\\\"Value\\\":0.890000000,\\\"Layout_Rundir_Name\\\":\\\"EXP_0805_Base_minus_175_move_place_groups\\\",\\\"PNR_StageName\\\":\\\"place_opt\\\",\\\"metric\\\":\\\"place_opt;Delay Per MM;SS092125;functional;budgeted_inputs_gisbports2reg;TotalSum\\\",\\\"Block_Name\\\":\\\"hvdp1_top\\\",\\\"Synth_Install_Name\\\":\\\"2016_08_08.00_22_final_syn\\\",\\\"Parent_Id\\\":\\\"place_opt;Delay Per MM;SS092125;functional;budgeted_inputs_gisbports2reg\\\",\\\"Level_Id\\\":\\\"place_opt;Delay Per MM;SS092125;functional;budgeted_inputs_gisbports2reg;TotalSum\\\",\\\"ProjName_Revision\\\":\\\"BCM7278 A0\\\"}\"]";
	}
	
public static Facet[] getCustomFacets(Record[] records) {
		
//		cubeGrid.setRowFacets("PNR_StageName","metric"); //ALEX REENABLE
//		cubeGrid.setColumnFacets("ProjName_Revision","Block_Name", "Layout_Rundir_Name","Synth_Install_Name"); //ALEX REENABLE

		Facet projName = new Facet();  
        projName.setId("ProjName_Revision");  
        projName.setTitle("ProjName_Revision");  

        Facet blockName = new Facet();  
        blockName.setId("Block_Name");  
        blockName.setTitle("Block_Name");  

        Facet layoutRundirName = new Facet();  
        layoutRundirName.setId("Layout_Rundir_Name");  
        layoutRundirName.setTitle("Layout_Rundir_Name");

        Facet synthInstallName = new Facet();  
        synthInstallName.setId("Synth_Install_Name");  
        synthInstallName.setTitle("Synth_Install_Name");
        
        Facet pnrStageName = new Facet();  
        pnrStageName.setId("PNR_StageName");  
        pnrStageName.setTitle("PNR_StageName");
        
        Facet metric = new Facet();  
        metric.setId("metric");  
        metric.setTitle("metric");
        metric.setIsTree(true);

        Set<String> blockNames = new HashSet<String>();
        Set<String> layoutRundirNames = new HashSet<String>();
        Set<String> projNames = new HashSet<String>();
        Set<String> synthInstallNames = new HashSet<String>();
        Set<String> pnrStageNames = new HashSet<String>();
        Set<String> metrics = new HashSet<String>();
        boolean hasTree = false;
        for (Record record : records) {
        	blockNames.add(record.getAttribute("Block_Name"));
        	layoutRundirNames.add(record.getAttribute("Layout_Rundir_Name"));
        	projNames.add(record.getAttribute("ProjName_Revision"));
        	synthInstallNames.add(record.getAttribute("Synth_Install_Name"));
        	pnrStageNames.add(record.getAttribute("PNR_StageName"));
        	metrics.add(record.getAttribute("metric"));
        	if (record.getAttribute("Level_Id") != null) {
        		hasTree = true;
        	}
        }
        
        FacetValue[] tempFacetVals;
        int i;
        
        tempFacetVals = new FacetValue[blockNames.size()];
        i = 0;
        for (String str : blockNames) {
        	tempFacetVals[i] = new FacetValue(str, str);
        	i++;
        }
        blockName.setValues(tempFacetVals);
        
        tempFacetVals = new FacetValue[layoutRundirNames.size()];
        i = 0;
        for (String str : layoutRundirNames) {
        	tempFacetVals[i] = new FacetValue(str, str);
        	i++;
        }
        layoutRundirName.setValues(tempFacetVals);
        
        tempFacetVals = new FacetValue[projNames.size()];
        i = 0;
        for (String str : projNames) {
        	tempFacetVals[i] = new FacetValue(str, str);
        	i++;
        }
        projName.setValues(tempFacetVals);
        
        tempFacetVals = new FacetValue[synthInstallNames.size()];
        i = 0;
        for (String str : synthInstallNames) {
        	tempFacetVals[i] = new FacetValue(str, str);
        	i++;
        }
        synthInstallName.setValues(tempFacetVals);
        
        tempFacetVals = new FacetValue[pnrStageNames.size()];
        i = 0;
        for (String str : pnrStageNames) {
        	tempFacetVals[i] = new FacetValue(str, str);
        	i++;
        }
        pnrStageName.setValues(tempFacetVals);
        
        
        	List<FacetValue> facetValueList= new ArrayList<FacetValue>();
        	Set<String> levelIdSet = new HashSet<String>();
        	i = 0;
        	for (Record record : records) {
        		i++;
        		String levelId = record.getAttribute("Level_Id");
        		String parentId = record.getAttribute("Parent_Id");
        		if (!levelIdSet.contains(levelId)) {
        			levelIdSet.add(levelId);
        			FacetValue facetVal;
        			if (!parentId.equals("-1")) {
        				facetVal = new FacetValue(levelId, record.getAttribute("title"), parentId);
        			} else {
        				facetVal = new FacetValue(levelId, record.getAttribute("title"));
        			}
        			facetVal.setCollapsed(true);
        			facetVal.setAlign(Alignment.LEFT);
        			facetValueList.add(facetVal);
        		}
        	}
        	FacetValue[] facetValArr = new FacetValue[facetValueList.size()];
        	facetValArr = facetValueList.toArray(facetValArr);
        	metric.setValues(facetValArr);
        
        return new Facet[]{projName, blockName, layoutRundirName, synthInstallName, pnrStageName, metric};  
	}


}
