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

import java.lang.reflect.Field;
import java.text.DecimalFormat;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import javafx.collections.FXCollections;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.chart.Chart;
import javafx.scene.chart.PieChart;
import javafx.scene.control.Tooltip;
import javafx.scene.input.MouseEvent;
import javafx.scene.text.Text;

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

/**
 * 
 * @author Administrator
 */
public class CustomPieChart extends PieChart implements ICmpChartWrapper {
	// private PieChart chart;
	// private List<IndexTreeNode> categoryList = new
	// ArrayList<IndexTreeNode>();
	private Map<IndexTreeNode, Data> categoryMap = new HashMap<IndexTreeNode, Data>();
	private double sum;

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

	private DecimalFormat rateDF = new DecimalFormat("#0.0%");
	private DecimalFormat valueDF = new DecimalFormat("#0.00");
	private Tooltip tooltip = new Tooltip();
	
	private int displayType = 0;// 用于表示当前显示数据的方式， 0表示显示总能耗，1表示显示单位建筑面积数据，2表示显示单位空调面积数据，3表示显示单位采暖面积数据

	public CustomPieChart() {
		super();
		setAnimated(false);
		setLabelsVisible(false);
		setCache(false);
		// chart = PieChartBuilder.create().animated(false).cache(false)
		// .labelsVisible(true).title("").build();
		// chart = new PieChart();
		// chart.setTitle(this.preTitle + dateTitle + this.sufTitle);
		// chart.setLabelsVisible(true);
	}

	@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 Chart getChart() {
		return this;
	}

	public void addOrUpdateValue(IndexTreeNode category, Number value) {
		if (categoryMap.containsKey(category)) {// update

			final Data data = categoryMap.get(category);
			sum += value.doubleValue() - data.getPieValue();

			data.setPieValue(value.doubleValue());

			updateLabels();
		} else {// insert
			if (getData() == null) {
				setData(FXCollections.<PieChart.Data> observableArrayList());
			}

			sum += value.doubleValue();

			String name = category.getName();

			final PieChart.Data data = new PieChart.Data(name,
					value.doubleValue());
			categoryMap.put(category, data);
			getData().add(data);
			
			data.getNode().setUserData(value.doubleValue());

			configTooltip(data);

			createAndUpdateLabels(name, data);

		}

	}

	private void createAndUpdateLabels(String name, final PieChart.Data data) {
		for (final Node label : lookupAll(".text.chart-pie-label")) {
			if (label instanceof Text) {
				if (((Text) label).getText().equals(name)) {
					((Text) label).setText(rateDF.format(data.getPieValue()
							/ sum));
					label.setUserData(data);
				} else {
					PieChart.Data d = (Data) label.getUserData();
					((Text) label)
							.setText(rateDF.format(d.getPieValue() / sum));
				}
			}
		}
	}

	private void updateLabels() {
		// 修改标签内容，改为显示百分比
		for (final Node label : lookupAll(".text.chart-pie-label")) {
			if (label instanceof Text) {
				PieChart.Data d = (Data) label.getUserData();
				((Text) label).setText(rateDF.format(d.getPieValue() / sum));
			}
		}
	}

	private void configTooltip(final PieChart.Data data) {
		final Node node = data.getNode();
		// Tooltip.install(data.getNode(), tooltip);
		node.setOnMouseEntered(new EventHandler<MouseEvent>() {
			@Override
			public void handle(MouseEvent event) {
				tooltip.setText(valueDF.format(data.getPieValue()) + " ("
						+ rateDF.format(data.getPieValue() / sum) + ")");
				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;
		for (Entry<IndexTreeNode, Data> entry : categoryMap.entrySet()) {
			IndexTreeNode node = entry.getKey();

			if (node.getHeatingArea() != null) {
				PieChart.Data data = entry.getValue();
				// double value = data.getPieValue() / node.getArea();
				double value = (Double) data.getNode().getUserData()
						/ node.getHeatingArea();
				data.setPieValue(value);
				sum += value;
			}
		}
		updateLabels();
	}

	@Override
	public void showAsAirConditionAreaData() {
		if(displayType == 2) {
			return;
		}
		displayType = 2;

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

			if (node.getAirConditionArea() != null) {
				PieChart.Data data = entry.getValue();
				// double value = data.getPieValue() / node.getArea();
				double value = (Double) data.getNode().getUserData()
						/ node.getAirConditionArea();
				data.setPieValue(value);
				sum += value;
			}
		}
		updateLabels();

	}

	@Override
	public void showAsAreaData() {
		if(displayType == 1) {
			return;
		}
		displayType = 1;
		
		sum = 0;
		for (Entry<IndexTreeNode, Data> entry : categoryMap.entrySet()) {
			IndexTreeNode node = entry.getKey();

			if (node.getArea() != null) {
				PieChart.Data data = entry.getValue();
				// double value = data.getPieValue() / node.getArea();
				double value = (Double) data.getNode().getUserData()
						/ node.getArea();
				data.setPieValue(value);
				sum += value;
			}
		}
		updateLabels();
	}

	@Override
	public void showAsNormalData() {
		if(displayType == 0) {
			return;
		}
		displayType = 0;

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

			if (node.getArea() != null) {

				PieChart.Data data = entry.getValue();
				// double value = data.getPieValue() * node.getArea();
				double value = (Double) data.getNode().getUserData();
				data.setPieValue(value);
				sum += value;
			}
		}

		updateLabels();
	}

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

		try {
			Field field = PieChart.class.getDeclaredField("defaultColorIndex");// javafx
																				// 2.1
			field.setAccessible(true);
			// field.set(PieChartWrapper.super, 0);
			field.set(this, 0);
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}

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

	// public void setChartPrefSize(double width, double height) {
	// System.out.println(width);
	// chart.setPrefSize(width, height);
	// // chart.setMaxSize(width, height);
	// }

}
