package ibase.client;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONString;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Window;

public class ChartCreator
{
	public static JSONObject buildChartData(ArrayList<ArrayList<String>> graphDtlList, JSONObject jsonObjGraph, String dataSource)
	{
		String key = "";
		String currentvalue = "";
		String monthKey = null;

		JSONObject graphJson = new JSONObject();
		JSONObject categryJson = new JSONObject();
		List<String> metaDataList = null;
		List<String> xAxisColunList = null;
		List<String> yAxisColunList = null;
		List<String> xAxisColumnName = null;
		List<String> yAxisColumnName = null;
		List<String> renderInfoList = null;
		List<String> colorInfoList = null;
		List<String> valueList = null;
		List<String> lineVisibleList = null;
		List<String> dotThicknessList = null;
		List<String> showValList = null;
		List<String> chartTypeList =  new ArrayList<String>();
		List<String> mapValuList = null;
		JSONValue barDataVal = null;
		JSONValue jsonChartVal = null;
		JSONValue categryDataVal = null;
		JSONString jsnStringKey = null;
		JSONString jsnStringValue = null;
		JSONString dataStringKey = null;
		JSONString dataStringValue = null;
		Set<String> valueMapSet = null;
		Object[] array = null;
		HashMap<String, List<String>> allDataMap = null;
		LinkedHashMap<JSONValue, JSONValue> categoryMap = null;
		LinkedHashMap<JSONValue, JSONValue> barChartMap = null;
		LinkedHashMap<JSONValue, JSONValue> barMap = null;
		ArrayList<LinkedHashMap<JSONValue, JSONValue>> labelList = null;
		ArrayList<LinkedHashMap<JSONValue, JSONValue>> barValueList = null;
		ArrayList<LinkedHashMap<JSONValue, JSONValue>> allDataList = null;

		for (int i = 0; i < graphDtlList.size(); i++)
		{
			if (i == 3)
			{
				xAxisColunList = (ArrayList<String>) graphDtlList.get(i);
			}
			if (i == 4)
			{
				yAxisColunList = (ArrayList<String>) graphDtlList.get(i);
			}
			if (i == 5)
			{
				metaDataList = (ArrayList<String>) graphDtlList.get(i);
			}
			if (i == 6)
			{
				xAxisColumnName = (ArrayList<String>) graphDtlList.get(i);
			}
			if (i == 7)
			{
				yAxisColumnName = (ArrayList<String>) graphDtlList.get(i);
			}
			if (i == 8)
			{
				renderInfoList = (ArrayList<String>) graphDtlList.get(i);
			}
			if (i == 9)
			{
				colorInfoList = (ArrayList<String>) graphDtlList.get(i);
			}
			if (i == 10)
			{
				lineVisibleList = (ArrayList<String>) graphDtlList.get(i);
			}
			if (i == 11)
			{
				dotThicknessList = (ArrayList<String>) graphDtlList.get(i);
			}
			if (i == 12)
			{
				showValList = (ArrayList<String>) graphDtlList.get(i);
			}
			if (i == 13)
			{
				chartTypeList = (ArrayList<String>) graphDtlList.get(i);
			}
			
		}
        int cnt=0;
		if (jsonObjGraph != null)
		{
			cnt++;
			allDataMap = new HashMap<String, List<String>>();
			barMap = new LinkedHashMap<JSONValue, JSONValue>();
          
			labelList = new ArrayList<LinkedHashMap<JSONValue, JSONValue>>();
			barValueList = new ArrayList<LinkedHashMap<JSONValue, JSONValue>>();
			allDataList = new ArrayList<LinkedHashMap<JSONValue, JSONValue>>();
			try
			{
				JSONObject jsonObjFrGraph =(JSONObject) jsonObjGraph.get(dataSource);	
				for (int jsnCnt = 0; jsnCnt < jsonObjFrGraph.size(); jsnCnt++)
				{
					JSONObject fetchRowWiseVal = (JSONObject) jsonObjFrGraph.get(String.valueOf(jsnCnt));
					for (int xCnt = 0; xCnt < xAxisColunList.size(); xCnt++)
					{
						key = "" + fetchRowWiseVal.get(xAxisColunList.get(xCnt));
					}
					valueList = new ArrayList<String>();
					for (int yCnt = 0; yCnt < yAxisColunList.size(); yCnt++)
					{
						currentvalue = (fetchRowWiseVal.get(yAxisColunList.get(yCnt)).toString().replace('"', ' ').trim());
						valueList.add(currentvalue);
					}					
					allDataMap.put(key, valueList);					
					key = "";
				}
				valueMapSet = allDataMap.keySet();
				if(chartTypeList.get(0).trim().equals("bar"))
				{
					for (String keyString : valueMapSet)
					{
						mapValuList = allDataMap.get(keyString);
						categoryMap = new LinkedHashMap<JSONValue, JSONValue>();
						keyString = keyString.replace('"', ' ').trim();
						jsnStringValue = new JSONString(keyString);
						jsnStringKey = new JSONString("label");
						categoryMap.put(jsnStringKey, jsnStringValue);
						labelList.add(categoryMap);
						dataStringKey = new JSONString("value");
					}
					for (int seriesCnt = 0; seriesCnt < mapValuList.size(); seriesCnt++)
					{
						barMap = new LinkedHashMap<JSONValue, JSONValue>();
						barValueList = new ArrayList<LinkedHashMap<JSONValue, JSONValue>>();
						array = valueMapSet.toArray();
						for (int columnCnt = 0; columnCnt < array.length; columnCnt++)
						{
							monthKey = (String) array[columnCnt];
							mapValuList = allDataMap.get(monthKey);
							barChartMap = new LinkedHashMap<JSONValue, JSONValue>();
							dataStringValue = new JSONString("" + mapValuList.get(seriesCnt));
							barChartMap.put(dataStringKey, dataStringValue);
							barChartMap.put(new JSONString("showValue"), new JSONString(showValList.get(seriesCnt)));
							barValueList.add(barChartMap);
						}
						barDataVal = JSONParser.parseStrict(barValueList.toString().replace('=', ':'));
						if ("column".equals(renderInfoList.get(seriesCnt)))
						{
							barMap.put(new JSONString("renderas"), new JSONString("Column"));
							barMap.put(new JSONString("parentYAxis"), new JSONString("s"));
						}
						if ("line".equals(renderInfoList.get(seriesCnt)))
						{
							barMap.put(new JSONString("renderas"), new JSONString("Line"));
							barMap.put(new JSONString("parentYAxis"), new JSONString("s"));
							barMap.put(new JSONString("valuePosition"), new JSONString("ABOVE"));
						}
						else
						{							
							barMap.put(new JSONString("valuePosition"), new JSONString("BELOW"));
						}
						barMap.put(new JSONString("color"), new JSONString(colorInfoList.get(seriesCnt)));
						barMap.put(new JSONString("data"), barDataVal);
						barMap.put(new JSONString("seriesname"), new JSONString(yAxisColumnName.get(seriesCnt)));
						allDataList.add(barMap);						
					}
					categryDataVal = JSONParser.parseStrict(labelList.toString().replace('=', ':'));
					categryJson.put("category", categryDataVal);
					graphJson.put("dataset", JSONParser.parseStrict(allDataList.toString().replace('=', ':')));
					graphJson.put("categories", categryJson);					
				}
				else if(chartTypeList.get(0).trim().equals("pie"))
				{		
					for (String keyString : valueMapSet)
					{				
						mapValuList = allDataMap.get(keyString);
						categoryMap = new LinkedHashMap<JSONValue, JSONValue>();
						keyString = keyString.replace('"', ' ').trim();
						jsnStringValue = new JSONString(keyString);
						jsnStringKey   = new JSONString("label");
						categoryMap.put(jsnStringKey, jsnStringValue);						
						dataStringKey = new JSONString("value");
						
						for (int seriesCnt = 0; seriesCnt < mapValuList.size(); seriesCnt++)
						{
							dataStringValue = new JSONString("" + mapValuList.get(seriesCnt));
							categoryMap.put(dataStringKey, dataStringValue);
							barValueList.add(categoryMap);							
							barDataVal = JSONParser.parseStrict(barValueList.toString().replace('=', ':'));
						}
						graphJson.put("data", barDataVal);
						
					}
				}
				
				if(chartTypeList.get(0).trim().equals("stack"))
				{
					HashMap<String, String> dMap = new HashMap<String, String>();
					for (String keyString : valueMapSet)
					{
						mapValuList = allDataMap.get(keyString);
						jsnStringKey = new JSONString("label");
						dataStringKey = new JSONString("value");
						String value = mapValuList.get(1).replace("{", "");
						value = value.replace("}", "");
						String[] tempArray = value.split(",");
						barMap = new LinkedHashMap<JSONValue, JSONValue>();
						barValueList = new ArrayList<LinkedHashMap<JSONValue, JSONValue>>();
						for(int i=0;i<tempArray.length;i++)
						{
							if(! tempArray[i].equals(""))
							{
								String[] tempArr = tempArray[i].split(":");
								categoryMap = new LinkedHashMap<JSONValue, JSONValue>();
								barChartMap = new LinkedHashMap<JSONValue, JSONValue>();	
								for(int j=0;j<tempArr.length;j++)
								{
									jsnStringValue = new JSONString(tempArr[0]);									
									categoryMap.put(jsnStringKey, jsnStringValue);
									if(!barChartMap.containsKey(jsnStringKey))
									{
										barChartMap.put(dataStringKey, new JSONString(tempArr[1]));
									}
								}
								if(! labelList.contains(categoryMap))
								{
									labelList.add(categoryMap);
								}
								if(! barValueList.contains(categoryMap))
								{
									barValueList.add(barChartMap);
								}
							}
						}						
						barMap.put(new JSONString("seriesname"), new JSONString(mapValuList.get(0)));
						barDataVal = JSONParser.parseStrict(barValueList.toString().replace('=', ':'));
						barMap.put(new JSONString("data"), barDataVal);
						allDataList.add(barMap);
						graphJson.put("dataset", JSONParser.parseStrict(allDataList.toString().replace('=', ':')));
					 
					}
					categryDataVal = JSONParser.parseStrict(labelList.toString().replace('=', ':'));
					categryJson.put("category", categryDataVal);
					graphJson.put("categories", categryJson);					
				}	
				jsonChartVal = JSONParser.parseStrict(metaDataList.toString());
				graphJson.put("chart", jsonChartVal);
				//Window.alert("graphJson:"+graphJson);
				
			} catch (Exception e)
			{
				Window.alert(" Exception :: Build Final Graph component [" + e.getMessage() + "]");

			}
		}
		return graphJson;
	}
}
