/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ht.ui.chart;

import java.text.DecimalFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Tooltip;
import javafx.scene.input.MouseEvent;

import com.ht.tags.model.index.IndexTreeNode;

/**
 * 
 * @author Administrator
 */
public class CustomBarChart extends BarChart<String, Number> implements
		ICmpChartWrapper {
	// private BarChart<String,Number> chart;

	private BarChart.Series<String, Number> sumSeries;
	private XYChart.Data<String, Number> maxItem;
	private XYChart.Data<String, Number> minItem;
	private XYChart.Data<String, Number> avgItem;

	private DecimalFormat valueDF = new DecimalFormat("#0.00");
	private Tooltip tooltip = new Tooltip();

	private String dateTitle;
	private String preTitle = "";
	private String sufTitle = "";

//	private List<IndexTreeNode> categoryList = new ArrayList<IndexTreeNode>();
	private Map<IndexTreeNode, Data<String, Number>> categoryMap = new HashMap<IndexTreeNode, Data<String, Number>>();
	private double sum = 0;
	private int displayType = 0;// 用于表示当前显示数据的方式， 0表示显示总能耗，1表示显示单位建筑面积数据，2表示显示单位空调面积数据，3表示显示单位采暖面积数据

	public CustomBarChart() {

		super(new CategoryAxis(), new NumberAxis());
		CategoryAxis xAxis = (CategoryAxis) getXAxis();
		xAxis.setTickLabelRotation(30);
		xAxis.setTickLabelsVisible(true);
		// NumberAxis yAxis = (NumberAxis) getYAxis();
		// yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis,
		// "", null));

		// chart = new BarChart<String,Number>(xAxis, yAxis);
		setCache(false);
		setAnimated(false);
		setLegendVisible(false);

		sumSeries = new BarChart.Series<String, Number>();
		sumSeries.setName("累计值");
		this.getData().add(sumSeries);

		// maxSeries = new BarChart.Series<String, Number>();
		// maxSeries.setName("最大值");
		// chart.getData().add(maxSeries);
		//
		// minSeries = new BarChart.Series<String, Number>();
		// minSeries.setName("最小值");
		// chart.getData().add(minSeries);
		//
		// avgSeries = new BarChart.Series<String, Number>();
		// avgSeries.setName("平均值");
		// chart.getData().add(avgSeries);

	}
	
	@Override
	public void showShortTitle() {
		setTitle("柱状图");
	}

	public void showLongTitle() {
		setTitle(dateTitle + this.preTitle + this.sufTitle + "柱状图");
	}

	@Override
	public void setDateTitle(String dateTitle) {
		this.dateTitle = dateTitle;
	}

	@Override
	public void setPreTitle(String preTitle) {
		this.preTitle = preTitle;
	}

	@Override
	public void setSufTitle(String sufTitle) {
		this.sufTitle = sufTitle;
	}

	@Override
	public BarChart<String, Number> getChart() {
		return this;
	}

	public void addOrUpdateValue(IndexTreeNode indexNode, double value) {
		
		if (sumSeries.getData().isEmpty()) {

			maxItem = new Data<String, Number>("最大值", 0);
			minItem = new Data<String, Number>("最小值", 0);
			avgItem = new Data<String, Number>("平均值", 0);

			sumSeries.getData().add(maxItem);
			sumSeries.getData().add(minItem);
			sumSeries.getData().add(avgItem);

			maxItem.getNode().getStyleClass().add("default-color1");
			minItem.getNode().getStyleClass().add("default-color2");
			avgItem.getNode().getStyleClass().add("default-color7");

			configTooltip(maxItem);
			configTooltip(minItem);
			configTooltip(avgItem);
		}

		Data<String, Number> data;
		if (categoryMap.containsKey(indexNode)) {

			data = categoryMap.get(indexNode);
			sum += value - data.getYValue().doubleValue();

			data.setYValue(value);
		} else {
			sum += value;

			data = new XYChart.Data<String, Number>(
					indexNode.getName(), value, value);
			data.setExtraValue(indexNode.getName());
			sumSeries.getData().add(data);
			data.getNode().getStyleClass().add("default-color" + (sumSeries.getData().size() - 4));
			categoryMap.put(indexNode, data);

			// config tooltips
			configTooltip(data);
		}

		if (value > maxItem.getYValue().doubleValue()) {
			maxItem.setYValue(value);
			maxItem.setExtraValue(indexNode.getName());
			maxItem.getNode().getStyleClass().set(maxItem.getNode().getStyleClass().size() - 1, "default-color" + (sumSeries.getData().indexOf(data) - 3));
		}
		if (minItem.getYValue().doubleValue() <= 0
				|| value < minItem.getYValue().doubleValue()) {
			minItem.setYValue(value);
			minItem.setExtraValue(indexNode.getName());
			minItem.getNode().getStyleClass().set(minItem.getNode().getStyleClass().size() - 1, "default-color" + (sumSeries.getData().indexOf(data) - 3));
		}
		avgItem.setYValue(sum / categoryMap.size());

	}

	private void configTooltip(final Data<String, Number> data) {
		final Node node = data.getNode();
		Tooltip.install(data.getNode(), tooltip);
		node.setOnMouseEntered(new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent event) {
				String text = " (" + valueDF.format(data.getYValue()) + ")";
				if (data.getExtraValue() != null) {
					text = data.getExtraValue().toString() + text;
				} else {
					
					text = data.getXValue() + text;
				}
				
				tooltip.setText(text);
				tooltip.show(node, event.getScreenX(), event.getScreenY());
			}
		});
		node.setOnMouseMoved(new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent event) {
				tooltip.show(node, event.getScreenX(), event.getScreenY());
			}
		});
		node.setOnMouseExited(new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent event) {
				tooltip.hide();
			}
		});
	}
	
	@Override
	public void showAsHeatingAreaData() {
		if(displayType == 3) {
			return;
		}
		displayType = 3;
		
		sum = 0;
		double min = -1;
		double max = 0;

		for (Entry<IndexTreeNode, Data<String, Number>> entry : categoryMap.entrySet()) {
			IndexTreeNode node = entry.getKey();

			if (node.getHeatingArea() == null) {
				continue;
			}
			Data<String, Number> data = entry.getValue();

			double value = (Double) data.getExtraValue();
			
			value = value / node.getHeatingArea();
			data.setYValue(value);
			sum += value;

			if (min <= 0 || value < min) {
				min = value;
			}
			if (value > max) {
				max = value;
			}
			//
			// Data<String, Number> minData = minSeries.getData().get(i);
			// minData.setYValue(minData.getYValue().doubleValue()
			// / node.getArea());
			//
			// Data<String, Number> avgData = avgSeries.getData().get(i);
			// avgData.setYValue(avgData.getYValue().doubleValue()
			// / node.getArea());
		}
		maxItem.setYValue(max);
		minItem.setYValue(min);
		avgItem.setYValue(sum / categoryMap.size());
		
	}
	
	@Override
	public void showAsAirConditionAreaData() {
		if(displayType == 2) {
			return;
		}
		displayType = 2;
		
		sum = 0;
		double min = -1;
		double max = 0;

		for (Entry<IndexTreeNode, Data<String, Number>> entry : categoryMap.entrySet()) {
			IndexTreeNode node = entry.getKey();

			if (node.getAirConditionArea() == null) {
				continue;
			}
			Data<String, Number> data = entry.getValue();

			double value = (Double) data.getExtraValue();
			
			value = value / node.getAirConditionArea();
			data.setYValue(value);
			sum += value;

			if (min <= 0 || value < min) {
				min = value;
			}
			if (value > max) {
				max = value;
			}
			//
			// Data<String, Number> minData = minSeries.getData().get(i);
			// minData.setYValue(minData.getYValue().doubleValue()
			// / node.getArea());
			//
			// Data<String, Number> avgData = avgSeries.getData().get(i);
			// avgData.setYValue(avgData.getYValue().doubleValue()
			// / node.getArea());
		}
		maxItem.setYValue(max);
		minItem.setYValue(min);
		avgItem.setYValue(sum / categoryMap.size());
	}

	@Override
	public void showAsAreaData() {
		if(displayType == 1) {
			return;
		}
		displayType = 1;

		sum = 0;
		double min = -1;
		double max = 0;

		for (Entry<IndexTreeNode, Data<String, Number>> entry : categoryMap.entrySet()) {
			IndexTreeNode node = entry.getKey();

			if (node.getArea() == null) {
				continue;
			}
			Data<String, Number> data = entry.getValue();

			double value = (Double) data.getExtraValue();
			
			value = value / node.getArea();
			data.setYValue(value);
			sum += value;

			if (min <= 0 || value < min) {
				min = value;
			}
			if (value > max) {
				max = value;
			}
			//
			// Data<String, Number> minData = minSeries.getData().get(i);
			// minData.setYValue(minData.getYValue().doubleValue()
			// / node.getArea());
			//
			// Data<String, Number> avgData = avgSeries.getData().get(i);
			// avgData.setYValue(avgData.getYValue().doubleValue()
			// / node.getArea());
		}
		maxItem.setYValue(max);
		minItem.setYValue(min);
		avgItem.setYValue(sum / categoryMap.size());
	}

	@Override
	public void showAsNormalData() {
		if(displayType == 0) {
			return;
		}
		displayType = 0;
		
		sum = 0;
		double min = -1;
		double max = 0;

		for (Entry<IndexTreeNode, Data<String, Number>> entry : categoryMap.entrySet()) {
			IndexTreeNode node = entry.getKey();

			if (node.getArea() == null) {
				continue;
			}

			Data<String, Number> data = entry.getValue();
			double value = (Double) data.getExtraValue();

			data.setYValue(value);
			sum += value;

			if (min <= 0 || value < min) {
				min = value;
			}
			if (value > max) {
				max = value;
			}

			// Data<String, Number> maxData = maxSeries.getData().get(i);
			// maxData.setYValue(maxData.getYValue().doubleValue()
			// * node.getArea());
			//
			// Data<String, Number> minData = minSeries.getData().get(i);
			// minData.setYValue(minData.getYValue().doubleValue()
			// * node.getArea());
			//
			// Data<String, Number> avgData = avgSeries.getData().get(i);
			// avgData.setYValue(avgData.getYValue().doubleValue()
			// * node.getArea());
		}

		maxItem.setYValue(max);
		minItem.setYValue(min);
		avgItem.setYValue(sum / categoryMap.size());
	}

	@Override
	public void clearData() {
		this.categoryMap.clear();
		sumSeries.getData().clear();
		sum = 0;
	}

	@Override
	public Collection<IndexTreeNode> getCategoryList() {
		return categoryMap.keySet();
	}
}
