// PieChart.java  for Drawing Bar Chart.
// Author : Saket Kumar
// Email Id : saket_kumar@hotmail.com

import java.awt.*;
import java.io.*;
import java.lang.*;

public class PieChart extends java.applet.Applet {

    String	title;
    Font        font;
    FontMetrics fontMetrics;
    int		titleHeight = 15;
    int		columns;
    int		values[];
    Color       colors[];
    String      labels[];
    float       percent[];
    float       angle[];
    int		maxLabelWidth = 0;
    int         maxValueWidth = 0;
    int		max = 0;
    int         strWidth=0;
    boolean     showLabel=true;   // Whether to display label or not
    boolean     showPercent=true; // Whether to display percent or not

    int lx=0,ly=0;          //For Writing Label
    int cx=0,cy=0;          //Center of Circle

  public synchronized void init() {

    String temp;

    font = new java.awt.Font("Sanserif", Font.BOLD, 12);
    fontMetrics = getFontMetrics(font);
    String bgColor=getParameter("bgcolor"); // Background color of Chart

    if (bgColor==null)
       setBackground(Color.white);
    else{
        if (bgColor.equals("red")) {
            setBackground(Color.red);
        } else if (bgColor.equals("green")) {
            setBackground(Color.green);
        } else if (bgColor.equals("blue")) {
            setBackground(Color.blue);
        } else if (bgColor.equals("pink")) {
            setBackground(Color.pink);
        } else if (bgColor.equals("orange")) {
            setBackground(Color.orange);
        } else if (bgColor.equals("magenta")) {
            setBackground(Color.magenta);
        } else if (bgColor.equals("cyan")) {
            setBackground(Color.cyan);
        } else if (bgColor.equals("white")) {
            setBackground(Color.white);
        } else if (bgColor.equals("yellow")) {
            setBackground(Color.yellow);
        } else if (bgColor.equals("gray")) {
            setBackground(Color.gray);
        } else if (bgColor.equals("darkGray")) {
            setBackground(Color.darkGray);
	    } else {
        setBackground(Color.white);
	    }
    }

	title = getParameter("title"); // Title of the Pie Chart

	if (title == null) {
        title = "Pie Chart";
	}

    temp = getParameter("columns");
    if (temp == null) {
	    columns = 5;
	} else {
        columns = Integer.parseInt(temp);
	}

    temp = getParameter("showlabel");
    if (temp == null) {
        showLabel = true;
	} else {
        if (temp.equalsIgnoreCase("YES"))
            showLabel = true;
        if (temp.equalsIgnoreCase("NO"))
            showLabel = false;
        else
            showLabel = true;
    }

    temp = getParameter("showpercent");
    if (temp == null) {
        showPercent = true;
	} else {
        if (temp.equalsIgnoreCase("YES"))
            showPercent = true;
        if (temp.equalsIgnoreCase("NO"))
            showPercent = false;
        else
            showPercent = true;
    }

    values = new int[columns];
    colors = new Color[columns];
    labels = new String[columns];
    percent= new float[columns];
    angle  = new float[columns];

    float totalValue=0;

	for (int i=0; i < columns; i++) {

        temp = getParameter("Pvalue" + (i+1));
        if (temp != null) {
		try {
            values[i] = Integer.parseInt(temp);
		} catch (NumberFormatException e) {
		    values[i] = 0;
		}
	    }
        totalValue +=  values[i];
        if (values[i] > max) {
		max = values[i];
	    }

	    // parse the label for this column
        temp = getParameter("P" + "label"+ (i+1) );
        labels[i] = (temp == null) ? "" : temp;
        maxLabelWidth = Math.max(fontMetrics.stringWidth((String)(labels[i])),
				     maxLabelWidth);

	    // parse the color attribute for this column
        temp = getParameter("P" + "color"+ (i+1) );
        if (temp != null) {
        if (temp.equals("red")) {
		    colors[i] = Color.red;
        } else if (temp.equals("green")) {
		    colors[i] = Color.green;
        } else if (temp.equals("blue")) {
		    colors[i] = Color.blue;
        } else if (temp.equals("pink")) {
		    colors[i] = Color.pink;
        } else if (temp.equals("orange")) {
		    colors[i] = Color.orange;
        } else if (temp.equals("magenta")) {
		    colors[i] = Color.magenta;
        } else if (temp.equals("cyan")) {
		    colors[i] = Color.cyan;
        } else if (temp.equals("white")) {
		    colors[i] = Color.white;
        } else if (temp.equals("yellow")) {
		    colors[i] = Color.yellow;
        } else if (temp.equals("gray")) {
		    colors[i] = Color.gray;
        } else if (temp.equals("darkGray")) {
		    colors[i] = Color.darkGray;
		} else {
		    colors[i] = Color.gray;
		}
	    } else {
				
			  if((i % 3) == 0)
					colors[i] = new Color(0xBB,0x00,0x00);
			  else
			  if((i%3) == 1)
					colors[i] = new Color(0x88,0xBB,0x88);
			  else
			  if((i%3) == 2)            
					colors[i] = new Color(0x00,0x88,0xBB);
	    }
    }
    float multiFactor = 100 / totalValue;

	for (int i=0; i < columns; i++) {
        percent[i]= values[i] * multiFactor;
        angle[i]  = (float) (percent[i] * 3.6) ;  // Calculation of Angle (360/100)
    }

  }

// paint method

  public synchronized void paint(Graphics g) {
    int  x=0;
    int  y=0;
    int width=0,height=0;
    int ax=0,ay=0;          //For Drawing Black line from center to Peripherial
    int px=0,py=0;          //For Writing Percentage
    int radius=0;
    width=height=Math.min((getSize().width - 100),(getSize().height - 100));
    x=y=50;

    if ( getSize().width > width ){
        x = (getSize().width - width ) /2 ; 
    }

    cx = x + width/2;
    cy = y + height/2;
    radius = width/2;

    // Draw the Title of the Chart on Top of the Applet

    strWidth=fontMetrics.stringWidth(title);
    Font fnt = new java.awt.Font("Sanserif", Font.BOLD, 16);
    g.setFont(fnt);
    g.setColor(Color.red);
    g.drawString(title,((getSize().width - strWidth )/2),15);
    g.setFont(font);
    int initAngle=90;
    int sweepAngle=0;
    int incSweepAngle=0;
    int incLabelAngle= (int) (angle[0]/2);

    for (int i=0; i < columns; i++) {
        sweepAngle = (int) Math.round(angle[i]);
        g.setColor((Color)colors[i]);

        if (i==(columns-1)){
            sweepAngle = 360 - incSweepAngle;
            g.fillArc(x,y,width,height,initAngle,(-sweepAngle));
            g.setColor(Color.black);
            g.drawArc(x,y,width,height,initAngle,(-sweepAngle));

            if (showLabel){
                lx = (int) (cx + ( radius * Math.cos((incLabelAngle * 3.14f/180) - 3.14f/2)));
                ly = (int) (cy + ( radius * Math.sin((incLabelAngle * 3.14f/180) - 3.14f/2)));
                adjustLabel(i);
                g.drawString((String)labels[i],lx,ly);
            }
            if (showPercent){
                px = (int) (cx + ((radius*2/3) * Math.cos((incLabelAngle * 3.14f/180) - 3.14f/2)));
                py = (int) (cy + ((radius*2/3) * Math.sin((incLabelAngle * 3.14f/180) - 3.14f/2)));
                g.drawString(String.valueOf(Math.round(percent[i]))+"%",px,py); 
            }
            break;
        }

        g.fillArc(x,y,width,height,initAngle,(-sweepAngle));
        g.setColor(Color.black);
        g.drawArc(x,y,width,height,initAngle,(-sweepAngle));
        incSweepAngle +=sweepAngle;

        ax = (int) (cx + ( radius * Math.cos((incSweepAngle * 3.14f/180) - 3.14f/2)));
        ay = (int) (cy + ( radius * Math.sin((incSweepAngle * 3.14f/180) - 3.14f/2)));
        g.drawLine(cx,cy,ax,ay);

        if (showLabel){
            lx = (int) (cx + ( radius * Math.cos((incLabelAngle * 3.14f/180) - 3.14f/2)));
            ly = (int) (cy + ( radius * Math.sin((incLabelAngle * 3.14f/180) - 3.14f/2)));
            adjustLabel(i);
            g.drawString((String)labels[i],lx,ly);
        }
        if (showPercent){
            px = (int) (cx + ((radius*2/3) * Math.cos((incLabelAngle * 3.14f/180) - 3.14f/2)));
            py = (int) (cy + ((radius*2/3) * Math.sin((incLabelAngle * 3.14f/180) - 3.14f/2)));
            strWidth = fontMetrics.stringWidth(Math.round(percent[i])+"%");
            g.drawString(String.valueOf(Math.round(percent[i]))+"%",(px - strWidth/2),py);
        }

        incLabelAngle = incLabelAngle + (int) (angle[i]/2 + angle[i+1]/2);
        initAngle += (-sweepAngle);
    }
    g.setColor(Color.black);
    g.drawLine(cx,cy,cx,cy-radius);
  }

  private void adjustLabel(int i){
    if ( (lx > cx) && (ly < cy) ){
        lx +=5;
        ly -=5;
    }

    if ( (lx > cx) && (ly > cy) ){
        lx +=5;
        ly +=10;
    }

    if ( (lx < cx) && (ly > cy) ){
        strWidth=fontMetrics.stringWidth(labels[i]);
        lx -= strWidth+5;
        if (lx < 0)
            lx=0;
    }

    if ( (lx < cx) && (ly < cy) ){
        strWidth=fontMetrics.stringWidth(labels[i]);
        lx -= strWidth+5;
        if (lx < 0)
            lx=0;
    }
  }

}
