

                   /*
                    * @(#)Chart.java       1.6f 95/03/27 Sami Shaio
                    *
                    * Copyright (c) 1994-1995 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;
                               }
                           }
                       }
                   }

