/*
 * @(#)Chart.java	1.6f 95/03/27 Sami Shaio
 *
 * Copyright (c) 1994-1996 Sun Microsystems, Inc. All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this software
 * and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
 * without fee is hereby granted. 
 * Please refer to the file http://java.sun.com/copy_trademarks.html
 * for further important copyright and trademark information and to
 * http://java.sun.com/licensing.html for further important licensing
 * information for the Java (tm) Technology.
 * 
 * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
 * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
 * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
 * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
 * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
 * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
 * 
 * THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
 * CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
 * PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
 * NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
 * SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
 * SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
 * PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES").  SUN
 * SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
 * HIGH RISK ACTIVITIES.
 */
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.io.*;
import java.lang.*;
import java.net.URL;

public class Chart extends java.applet.Applet {
    static final int	VERTICAL = 0;
    static final int 	HORIZONTAL = 1;

    static final int	SOLID = 0;
    static final int	STRIPED = 1;

    int			orientation;
    String		title;
    Font		titleFont;
    FontMetrics		titleFontMetrics;
    int			titleHeight = 15;
    int			columns;
    int			values[];
    Object		colors[];
    Object		labels[];
    int			styles[];
    int			scale = 10;
    int			maxLabelWidth = 0;
    int			barWidth;
    int			barSpacing = 10;
    int			max = 0;

    public synchronized void init() {
        String rs;

        titleFont = new java.awt.Font("Courier", Font.BOLD, 12);
        titleFontMetrics = getFontMetrics(titleFont);
        title = getParameter("title");

        if (title == null) {
            title = "Chart";
        }
        rs = getParameter("columns");
        if (rs == null) {
            columns = 5;
        } 
        else {
            columns = Integer.parseInt(rs);
        }
        rs = getParameter("scale");
        if (rs == null) {
            scale = 10;
        } 
        else {
            scale = Integer.parseInt(rs);
        }

        rs = getParameter("orientation");
        if (rs == null) {
            orientation = VERTICAL;
        } 
        else if (rs.toLowerCase().equals("vertical")) {
            orientation = VERTICAL;
        } 
        else if (rs.toLowerCase().equals("horizontal")) {
            orientation = HORIZONTAL;
        } 
        else {
            orientation = VERTICAL;
        }
        values = new int[columns];
        colors = new Color[columns];
        labels = new String[columns];
        styles = new int[columns];
        for (int i=0; i < columns; i++) {
            // parse the value for this column
            rs = getParameter("C" + (i+1));
            if (rs != null) {
                try {
                    values[i] = Integer.parseInt(rs);
                } 
                catch (NumberFormatException e) {
                    values[i] = 0;
                }
            }
            if (values[i] > max) {
                max = values[i];
            }

            // parse the label for this column
            rs = getParameter("C" + (i+1) + "_label");
            labels[i] = (rs == null) ? "" : rs;
            maxLabelWidth = Math.max(titleFontMetrics.stringWidth((String)(labels[i])),
            maxLabelWidth);

            // parse the bar style
            rs = getParameter("C" + (i+1) + "_style");
            if (rs == null || rs.toLowerCase().equals("solid")) {
                styles[i] = SOLID;
            } 
            else if (rs.toLowerCase().equals("striped")) {
                styles[i] = STRIPED;
            } 
            else {
                styles[i] = SOLID;
            }
            // parse the color attribute for this column
            rs = getParameter("C" + (i+1) + "_color");
            if (rs != null) {
                if (rs.equals("red")) {
                    colors[i] = Color.red;
                } 
                else if (rs.equals("green")) {
                    colors[i] = Color.green;
                } 
                else if (rs.equals("blue")) {
                    colors[i] = Color.blue;
                } 
                else if (rs.equals("pink")) {
                    colors[i] = Color.pink;
                } 
                else if (rs.equals("orange")) {
                    colors[i] = Color.orange;
                } 
                else if (rs.equals("magenta")) {
                    colors[i] = Color.magenta;
                } 
                else if (rs.equals("cyan")) {
                    colors[i] = Color.cyan;
                } 
                else if (rs.equals("white")) {
                    colors[i] = Color.white;
                } 
                else if (rs.equals("yellow")) {
                    colors[i] = Color.yellow;
                } 
                else if (rs.equals("gray")) {
                    colors[i] = Color.gray;
                } 
                else if (rs.equals("darkGray")) {
                    colors[i] = Color.darkGray;
                } 
                else {
                    colors[i] = Color.gray;
                }
            } 
            else {
                colors[i] = Color.gray;
            }
        }
        switch (orientation) {
        case VERTICAL:
        default:
            barWidth = maxLabelWidth;
            resize(Math.max(columns * (barWidth + barSpacing),
            titleFontMetrics.stringWidth(title)) +
                titleFont.getSize() + 5,
            (max * scale) + (2 * titleFont.getSize()) + 5 + titleFont.getSize());
            break;
        case HORIZONTAL:
            barWidth = titleFont.getSize();
            resize(Math.max((max * scale) + titleFontMetrics.stringWidth("" + max),
            titleFontMetrics.stringWidth(title)) + maxLabelWidth + 5,
            (columns * (barWidth + barSpacing)) + titleFont.getSize() + 10);
            break;
        }
    }

    public synchronized void paint(Graphics g) {
        int i, j;
        int cx, cy;
        char l[] = new char[1];


        // draw the title centered at the bottom of the bar graph
        g.setColor(Color.black);
        i = titleFontMetrics.stringWidth(title);
        g.setFont(titleFont);
        g.drawString(title, Math.max((size().width - i)/2, 0),
        size().height - titleFontMetrics.getDescent()); 
        for (i=0; i < columns; i++) {
            switch (orientation) {
            case VERTICAL:
            default:
                // set the next X coordinate to account for the label
                // being wider than the bar size().width.
                cx = (Math.max((barWidth + barSpacing),maxLabelWidth) * i) +
                    barSpacing;

                // center the bar chart
                cx += Math.max((size().width - (columns *
                    (barWidth + (2 * barSpacing))))/2,0);

                // set the next Y coordinate to account for the size().height
                // of the bar as well as the title and labels painted
                // at the bottom of the chart.
                cy = size().height - (values[i] * scale) - 1 - (2 * titleFont.getSize());

                // draw the label
                g.setColor(Color.black);		
                g.drawString((String)labels[i], cx,
                size().height - titleFont.getSize() - titleFontMetrics.getDescent());

                // draw the shadow bar
                if (colors[i] == Color.black) {
                    g.setColor(Color.gray);
                }
                g.fillRect(cx + 5, cy - 3, barWidth,  (values[i] * scale));
                // draw the bar with the specified color
                g.setColor((Color)(colors[i]));
                switch (styles[i]) {
                case SOLID:
                default:
                    g.fillRect(cx, cy, barWidth, (values[i] * scale));
                    break;
                case STRIPED:
                    {
                        int steps = (values[i] * scale) / 2;
                        int ys;

                        for (j=0; j < steps; j++) {
                            ys = cy + (2 * j);
                            g.drawLine(cx, ys, cx + barWidth, ys);
                        }
                    }
                    break;
                }
                g.drawString("" + values[i],
                cx,
                cy - titleFontMetrics.getDescent());
                break;
            case HORIZONTAL:
                // set the Y coordinate
                cy = ((barWidth + barSpacing) * i) + barSpacing;

                // set the X coordinate to be the size().width of the widest
                // label 
                cx = maxLabelWidth + 1;

                cx += Math.max((size().width - (maxLabelWidth + 1 +
                    titleFontMetrics.stringWidth("" +
                    max) +
                    (max * scale))) / 2, 0);
                // draw the labels and the shadow
                g.setColor(Color.black);		
                g.drawString((String)labels[i], cx - maxLabelWidth - 1,
                cy + titleFontMetrics.getAscent());
                if (colors[i] == Color.black) {
                    g.setColor(Color.gray);
                }
                g.fillRect(cx + 3,
                cy + 5,
                (values[i] * scale),
                barWidth);

                // draw the bar in the current color
                g.setColor((Color)(colors[i]));
                switch (styles[i]) {
                case SOLID:
                default:
                    g.fillRect(cx,
                    cy,
                    (values[i] * scale),
                    barWidth);
                    break;
                case STRIPED:
                    {
                        int steps = (values[i] * scale) / 2;
                        int ys;

                        for (j=0; j < steps; j++) {
                            ys = cx + (2 * j);
                            g.drawLine(ys, cy, ys, cy + barWidth);
                        }
                    }
                    break;
                }
                g.drawString("" + values[i],
                cx + (values[i] * scale) + 3,
                cy + titleFontMetrics.getAscent());

                break;
            }
        }
    }
}
