/*----------------------------------------------------------------------+
|	Title:	RangeDisplay.java                                       |
|                                                                       |
|	Author:	David E. Joyce                                          |
|		Department of Mathematics and Computer Science          |
|       	Clark University                                        |
|       	Worcester, MA 01610-1477                                |
|       	U.S.A.                                                  |									|                                                                       |
|		http://aleph0.clarku.edu/~djoyce/home.html              |
|		djoyce@clarku.edu                                       |
|                                                                       |
|	Date:	February, 2001.                                         |
+----------------------------------------------------------------------*/


import java.awt.*;
import java.awt.event.*;

public class RangeDisplay extends Canvas {

  Color background;      // background color for the window
  Range R;               // the range being displayed

  //display data
  double x[], y[];       // the (x,y) coordinates for the center of the herd
  double s_rad, t_rad;   // relative radii of circles

  RangeDisplay (Color background) {
    this.background = background;
    addMouseListener(new MouseClickListener());
  }  // RangeDisplay

  public void setRange(Range R) {
    this.R = R;
    resetRangeDisplay();
  } // setRange

  void resetRangeDisplay() {
    // compute some display constants
    x = new double[R.numberOfHerds];
    y = new double[R.numberOfHerds];
    if (R.numberOfHerds == 1) {          // special computations when one herd
      x[0] = 0.0;
      y[0] = 0.0;
      s_rad = 0.0;
      t_rad = 1.0;
    } else {                            // more than one herd
      double theta = 2*Math.PI/R.numberOfHerds;
      for (int i=0; i<R.numberOfHerds; ++i) {
        x[i] = Math.cos(i*theta);
        y[i] = Math.sin(i*theta);
      }
      double sin = Math.sin(theta/2.0);
      s_rad = 1.0/(1.0 + sin);          // relative radius of circle centers
      t_rad = s_rad*sin;                // relative radius of circles
    }
  }

  Image offscreen;
  Dimension offscreensize;
  Graphics offgraphics;
  Color black = new Color(0);

  public void update(Graphics g) {
    if (R == null) return; // not yet initialized
    g.setColor(background);
    Dimension d = getSize();
    if ((offscreen == null) || (d.width != offscreensize.width)
		|| (d.height != offscreensize.height)) {
      offscreen = createImage(d.width, d.height);
      offscreensize = d;
      offgraphics = offscreen.getGraphics();
      offgraphics.setFont(g.getFont());
    }
    drawHerds(offgraphics);
    offgraphics.setColor(black);
    offgraphics.drawString(R.day+"", getSize().width/2-10, getSize().height/2+5);
    g.drawImage(offscreen, 0, 0, null);
  }

  public void drawHerds(Graphics g) {
    if (R.stats==null || R.stats[0]== null) return; // not yet initialized
    g.setColor(background);
    Dimension d = getSize();
    g.fillRect(0,0,d.width,d.height);
    int center_x = d.width/2;
    int center_y = d.height/2;
    double min = (center_x < center_y) ? center_x : center_y;
    double radius = s_rad*min;
    int herd_radius = (int)Math.round(t_rad*min);
    g.fillRect(0, 0, d.width, d.height);
    for (int h=0; h<R.numberOfHerds; ++h) {   // color each herd
      g.setColor(Genome.chooseColor(R.stats[h][Genome.getRedGene()].mean,
                                    R.stats[h][Genome.getGreenGene()].mean,
                                    R.stats[h][Genome.getBlueGene()].mean));
      // draw the herd in that color
      int h_x = center_x + (int)Math.round(radius*x[h]) - herd_radius;
      int h_y = center_y + (int)Math.round(radius*y[h]) - herd_radius;
      if (R.herd[h].getPopulation() > 0) {
        g.fillOval (h_x, h_y, 2*herd_radius, 2*herd_radius);
        // print the population of the herd
        String digits =Integer.toString(R.herd[h].getPopulation());
        g.setColor(Color.black);
        g.drawString(digits, h_x+herd_radius-10, h_y+herd_radius+5);
      } else // nobody there
        g.drawOval (h_x+(herd_radius/2), h_y+(herd_radius/2),
                    herd_radius, herd_radius);
      if (h == R.selectedHerd) {
        g.setColor(Color.black);
        g.drawOval (h_x, h_y, 2*herd_radius, 2*herd_radius);
      }
    }
  }

  public void paint(Graphics g) {
    update(g);
  }

  private class MouseClickListener extends MouseAdapter {

    public void mouseClicked(MouseEvent e) {
      int ex = e.getX();
      int ey = e.getY();
      Dimension d = getSize();
      int center_x = d.width/2;
      int center_y = d.height/2;
      double min = (center_x < center_y) ? center_x : center_y;
      double radius = s_rad*min;
      int herd_radius = (int)Math.round(t_rad*min);
      int herd_radius_squared = herd_radius*herd_radius;
      // see if (x,y) is in one of the herds
      int i;
      for (i=0; i<R.numberOfHerds; ++i) {
        int h_x = center_x + (int)Math.round(radius*x[i]);
        int h_y = center_y + (int)Math.round(radius*y[i]);
        int dx2 = (h_x - ex)*(h_x - ex);
        int dy2 = (h_y - ey)*(h_y - ey);
        if (dx2 + dy2 < herd_radius_squared)
          break;
      }
      if (i < R.numberOfHerds && R.selectedHerd != i)
        R.selectedHerd = i;
    } // mouseClicked
  } // MouseClickListener
} // RangeDisplay

