/**********************************************************************
 * Copyright (c) 2005, 2006 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * $Id: MethodInvocationBarChart.java,v 1.1 2006/07/07 23:08:07 nmehrega Exp $
 * 
 * Contributors: 
 * IBM - Initial API and implementation
 **********************************************************************/

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.util.Hashtable;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.ApplicationFrame;

/**
 * EclipseCon 2006
 * This class uses a 3D bar chart to graph method invocations
 * 
 * @author Navid Mehregani
 */
public class MethodInvocationBarChart extends ApplicationFrame {
	
	
	private static DefaultCategoryDataset _dataset = new DefaultCategoryDataset();
	private static String _rowKey = "MethodInvocation";
	
	/* Used to store the method counts.  Uses the method name for its 
	 * key and method invocations for its value */
	private static Hashtable methodCountHash = new Hashtable();

    /**
     * Default constructor
     *
     * @param title  the frame title.
     */
    public MethodInvocationBarChart() {

        super("Method Invocations");
        JFreeChart chart = createChart();
        try
        {
        	  ChartPanel chartPanel = new ChartPanel(chart, false);
              chartPanel.setPreferredSize(new Dimension(700, 470));
              setContentPane(chartPanel);
        } catch (Exception e)
        {
        	System.err.println("CAUGHT EXCEPTION FOR BAR " + e.getMessage());  // TODO
        }
      

    }
    
    /**
     * Used to create the chart 
     * 
     * @param dataset  the dataset for the chart
     * 
     * @return The chart that's created 
     */
    private static JFreeChart createChart() {
        
        /* Create a 3D bar chart */
        JFreeChart chart = ChartFactory.createBarChart3D(
            "Method Invocations",         // chart title
            "Methods",               	  // domain axis label
            "Number of Invocations",      // range axis label
            _dataset,                     // data
            PlotOrientation.VERTICAL,     // orientation
            false,                        // no legend
            true,                         // tooltips
            false                         // URLs
        );

        /* Customize the chart */

        /* Background colour */
        chart.setBackgroundPaint(Color.white);

        /* Set the appropriate colours */
        CategoryPlot plot = chart.getCategoryPlot();
        plot.setBackgroundPaint(Color.lightGray);
        plot.setDomainGridlinePaint(Color.white);
        plot.setDomainGridlinesVisible(true);
        plot.setRangeGridlinePaint(Color.white);

        /* Range axis should display integers only */
        final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());

        /* Disable the outlines */
        BarRenderer renderer = (BarRenderer) plot.getRenderer();
        renderer.setDrawBarOutline(false);
        
        /* Gradient paints for series */
        GradientPaint gp0 = new GradientPaint(
            0.0f, 0.0f, Color.blue, 
            0.0f, 0.0f, new Color(0, 0, 64)
        );
        
        renderer.setSeriesPaint(0, gp0);
        
        CategoryAxis domainAxis = plot.getDomainAxis();
        domainAxis.setCategoryLabelPositions(
            CategoryLabelPositions.createUpRotationLabelPositions(Math.PI / 6.0)
        );
        
        
        return chart;
        
    }
    
    /**
     *  Used to get the chart's dataset 
     */
    public DefaultCategoryDataset getDataset()
    {
    	synchronized(_dataset)
    	{
    		return _dataset;
       	}
    }
    
    /**
     * Include the given method on the bar chart 
     * 
     * @param value  The value of the method on the chart (displayed on the y-axis)
     * @param methodName  The name of the method  (displayed on the x-axis)
     */  
    public void includeMethod(int value, String methodName)
    {    
    	synchronized(_dataset)
    	{
	    	if (_dataset != null)
	    	{	    		
	    		_dataset.addValue(value, _rowKey, methodName);	    		
	    	}	
    	}
    }
    
    /**
     * Used to extract the method count from our hashtable
     * 
     * @param methodName  Name of the method
     * 
     * @return  Method count
     */
    public int getMethodCount(String methodName)
    {
    	int methodCount = 0;
    	synchronized(methodCountHash)
    	{   	
	    	Integer previousValueObject = (Integer)methodCountHash.get(methodName);
	    	if (previousValueObject != null)
	      		methodCount = previousValueObject.intValue();
    	}
    	
    	return methodCount;
    	
    	
    }
    
    /**
     * Used to update the number of invocations for the given method in our hashtable
     * 
     * @param methodName  Name of the method
     * @param newMethodCount  Updated method counts
     */
    public void updateMethodCount(String methodName, int newMethodCount)
    {   	
    	/* Update methodCount. We're not going to do anything to avoid a 
    	 * hash collision because the representation of data is not the main 
    	 * focus of this demo.  The main focus of the demo is the probe that 
    	 * actually populates the data.
    	 */
    	
    	synchronized(methodCountHash)
    	{
    		methodCountHash.put(methodName, new Integer(newMethodCount));
    	}    
    }
 
}
