/*
 *	EasyScout Boy Scouts of America tracking software.
 *	http://www.easyscout.org/
 *
 *	Copyright (C) 2000 Conan C. Albrecht
 *	conan@warp.cx
 *
 *	This program is released under the GNU license so tech-savvy
 *	Boy Scouts and others can enhance the program for the use
 *	of all.  Please e-mail changes to my address above so I can
 *	reintegrate into the main program at http://www.easyscout.org/.
 *	This way, all users mutually benefit one another in the spirit of
 *	scouting.
 *
 *	This program is free software; you can redistribute it and/or
 *	modify it under the terms of the GNU General Public License
 *	as published by the Free Software Foundation; either version 2
 *	of the License, or (at your option) any later version.
 *
 * 	Any and all changes to the program code must be documented with
 *  date, author name and e-mail, and a short description.
 *
 *	This program is distributed in the hope that it will be useful,
 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *	GNU General Public License for more details.
 *
 *	You should have received a copy of the GNU General Public License
 *	along with this program; if not, write to the Free Software
 *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */

package cx.warp.scout.graphics;

import cx.warp.scout.*;
import cx.warp.graphics.*;
import javax.servlet.http.*;
import java.awt.*;
import java.awt.image.*;
import java.util.*;
import java.io.*;

/** Returns a PNG-type pie chart given the input parameters*/
public class PieChart {

	static Color colors[] = { Color.pink, Color.darkGray, Color.red, Color.blue, Color.magenta, Color.lightGray, Color.orange  };
	static Color transparency = Color.green;

	FontMetrics fm;
	int padding = 4;
	String title;
	Vector items;
	int totalValue;
	Dimension size = new Dimension(300, 200);
	Font font = new Font("Dialog", Font.PLAIN, 10);

	/** Constructor */
	public PieChart() {
		this("");
	}//PieChart constructor

	/** Constructor */
	public PieChart(String title) {
		this.title = title;
		items = new Vector();
	} // end constructor
	
	/** Adds an item to the pie graph. */
	public void addItem(String name, int value, Color col) {
		items.addElement(new GraphItem(name, value, col));
		totalValue += value;
	}//addItem

	/** Sets the size of the graphic (default is 200x200) */
	public void setSize(Dimension d) {
		size = d;
	}//setSize
	
	/** Sets the font of the pie labels */
	public void setFont(Font f) {
		font = f;
	}//setFont

	/** Paint the pie to a graphics object */
	public void paint(Graphics g) {
	 	// draw the title
		fm = Toolkit.getDefaultToolkit().getFontMetrics(font);
			
		// blank the drawing space with white color
		g.setColor(transparency);
		g.fillRect(0, 0, size.width, size.height);
			
	  int titleHeight = fm.getHeight();
		int top = padding * 4 + titleHeight;
		int bottom = size.height - padding;
		int left = padding;
		int right = size.width - padding;
		Point center = new Point((right - left)/2, (bottom - top)/2);
		g.setColor(Color.black);
		g.drawString(title, (size.width - fm.stringWidth(title))/2, titleHeight + padding);

		int size2 = Math.min(bottom - top, right - left) - padding - 30;
		int arcX = left + (right - left - size2)/2;
		int arcY = top + (bottom - top - size2)/2;

		int sumTot = 0;
		for (int i = 0; i < items.size(); i++) {
			GraphItem item = (GraphItem)items.elementAt(i);
			if (item.value > 0) {
				String t = item.title + " (" + String.valueOf(item.value) + ")";
	      int degrees = sumTot * 360 / totalValue;
	      int adjustedValue = (sumTot + item.value)*360 / totalValue - degrees;
	      g.setColor(item.color);
	      g.fillArc(arcX, arcY, size2, size2, degrees, adjustedValue);
	      Point titlePosition = new Point(0, 0);
	      titlePosition.x = (int)(Math.cos(degrees*Math.PI/180 + adjustedValue*Math.PI/360) * size2/2) + center.x + left;
	      titlePosition.y = center.y - (int)(-Math.sin(degrees*Math.PI/180 + adjustedValue*Math.PI/360) * size2/2) + top;
				if (titlePosition.x <= center.x)
	        titlePosition.x = titlePosition.x - fm.stringWidth(t) - 1;
	      else if (titlePosition.x > center.x)
	        titlePosition.x += 1;
				titlePosition.x = Math.max(titlePosition.x, 0);
	      if (titlePosition.y > center.y)
	        titlePosition.y = titlePosition.y + fm.getHeight() + 1;
	      else if (titlePosition.y <= center.y)
	        titlePosition.y -= 1;
	      g.setColor(Color.black);
	      g.drawString(t, titlePosition.x, titlePosition.y);
	      sumTot += item.value;
			}//if
		}//for 
	} // end paint

	/** Inner class to represent one graph item */
	class GraphItem {
		String title;
		String titleValue;
		int value;
		Color color;
		public GraphItem(String title, int value, Color color) {
			this.title = title;
			this.value = value;
			this.color = color;
			setTitleValue();
		 } // end constructor

		 public void setTitleValue() {
			 titleValue = title + " [" + String.valueOf(value) + "]";
		 }//setTitlevalue

	} // end GraphItem
	
	/** Creates the graph and prints to the output stream */
	public static void doChart(HttpServletRequest request, HttpServletResponse response, Session session) throws IOException {
		response.setContentType("image/gif");
		OutputStream out = response.getOutputStream();

		// construct the pie
		PieChart pie = new PieChart("Advancement");
		Dimension size = new Dimension(300, 200);
		pie.setSize(size);
		int index = 1;
		while (true) {
			String name = request.getParameter(String.valueOf(index) + "n");
			String val = request.getParameter(String.valueOf(index) + "v");
			System.out.println(name + " " + val);
			if (name == null || name.equals("") || val == null || val.equals("")) {
				break;
			}//if
			pie.addItem(name, Integer.parseInt(val), colors[index % colors.length]);
			index++;
		}//while
		
		// paint the pie on an image
		BufferedImage img = new BufferedImage(size.width, size.height, BufferedImage.TYPE_BYTE_INDEXED);
		pie.paint(img.getGraphics());

		// encode to gif format and return to the client
		GifEncoder encoder = new GifEncoder(img, out);
		encoder.setTransparentColor(transparency);
		encoder.encode();

/*
		PngEncoderB png = new PngEncoderB(img, PngEncoder.ENCODE_ALPHA, 0, 1);
	  byte[] pngbytes = png.pngEncode();
		if (pngbytes != null) {
			out.write(pngbytes);
		}//if
*/
		out.flush();
		out.close();
	}//doGraph

}//PieChart
