package mapper;

import javax.swing.*;
import java.awt.*;
import java.awt.image.*;

/** Bill's first Lightweight Component! */
public class Scale extends JPanel
{
   public Scale(int ppd, float centerLat)
   {
      setDoubleBuffered(false);
      this.ppd = ppd;
      this.centerLat = centerLat;
      
      //Font theFont = getFont();
      //FontMetrics metrics = getFontMetrics(theFont);
      mPerLon = mPerLat * Math.cos(centerLat * RADPERDEG);
      ppm = ppd / mPerLon;
      if(ppd > 15000) { increment = (float)100;  unitName = "METERS";  labelDivisor = 1; }
      else if(ppd > 5000) { increment = (float)500;  unitName = "METERS";  labelDivisor = 1; }
      else if(ppd > 650) { increment = 1000;  unitName = "KILOMETERS";  labelDivisor = 1000; }
      else if(ppd > 180) { increment = 5000;  unitName = "KILOMETERS";  labelDivisor = 1000;}
      else if(ppd > 80) { increment = 10000;  unitName = "KILOMETERS";  labelDivisor = 1000; }
      else if(ppd > 60) { increment = 50000;  unitName = "KILOMETERS";  labelDivisor = 1000; }
      else if(ppd > 10) { increment = 100000;  unitName = "KILOMETERS";  labelDivisor = 1000; }
      else if(ppd > 2) { increment = 500000;  unitName = "KILOMETERS";  labelDivisor = 1000; }
      else if(ppd > 1) { increment = 1000000;  unitName = "KILOMETERS";  labelDivisor = 1000; }
      else { increment = 5000000;  unitName = "KILOMETERS";  labelDivisor = 1000; }
      //System.err.println("ppd = " + ppd + ";  increment = " + increment);
      segLength = (int)(ppm*increment);
   }
/*
   public void paint(Graphics g)
   {
      try
      {
         g.drawImage(bgImage, 0, 0, null);
      }
      catch(NullPointerException npe1)
      {
         System.out.println("Drawing scale.");
         drawScale();
         g.drawImage(bgImage, 0, 0, null);
      }
   }
*/
   public void paint(Graphics g)
   {
      // NOTE:  We'd love to transparentize first and then be able to draw
      //        in any arbitrary color.  But we can't.  Image's returned by
      //        createImage(ImageProducer) are not drawable.  Just don't draw in
      //        Color.white and you'll be okay.  Or, if you must, pick a different
      //        color to transparentize on.
      int xInset = 1, yInset = 1, scaleHeight = 4;
      Font font = new Font("Monospaced", Font.PLAIN, 9);
      FontMetrics fm = getFontMetrics(font);
      int ascent = fm.getAscent();
      int swidth = fm.stringWidth(unitName);
      
      // '12' in width is a magic number.  '2' in height leaves space between text's and scale.
      setSize(xInset*2 + segLength*5 + 12, yInset*2 + scaleHeight + ascent*2 + 2);
      
      // Create drawing image and get graphics context:
      //Dimension d = getSize();
      //bgImage = createImage(d.width, d.height);
      //Graphics bgg = bgImage.getGraphics();
      
      // Prepare for Transparentization:
      //g.setColor(Color.white);
      //g.fillRect(0, 0, d.width, d.height);
      
      // Draw what we want:
      g.setColor(Color.darkGray);
      g.setFont(font);
      int offset = xInset;
      int labelYInset = yInset + ascent;
      int boxYInset = labelYInset + 1/*space text off top of scale*/;
      int lineYInset = boxYInset + (scaleHeight/2);
      int unitsYInset = boxYInset + scaleHeight + 1 + ascent;
      int label = (int)increment / labelDivisor;
      for(int i = 1; i <= 5; i++)
      {
         g.drawRect(offset, boxYInset, segLength, scaleHeight); 
         if((i%2)!= 0)
         {
            g.drawLine(offset, lineYInset, offset + segLength, lineYInset);
         }
         offset += segLength;
         String lS = String.valueOf(label*i);
         g.drawString(lS, offset - fm.stringWidth(lS)/2, labelYInset);
      }
      
      g.drawString(unitName, ((offset)/2) - (swidth/2), unitsYInset);
      
      // Transparentize:
      //ImageProducer src = bgImage.getSource();
      //ImageFilter tfilter = new TransparentOffGFilter(Color.white.getRGB());
      //bgImage = createImage(new FilteredImageSource(src, tfilter));
   }
   /*
   public void update(Graphics g)
   {
      paint(g);
   }
   */
   private void drawScale()
   {
      // NOTE:  We'd love to transparentize first and then be able to draw
      //        in any arbitrary color.  But we can't.  Image's returned by
      //        createImage(ImageProducer) are not drawable.  Just don't draw in
      //        Color.white and you'll be okay.  Or, if you must, pick a different
      //        color to transparentize on.
      int xInset = 1, yInset = 1, scaleHeight = 4;
      Font font = new Font("Monospaced", Font.PLAIN, 9);
      FontMetrics fm = getFontMetrics(font);
      int ascent = fm.getAscent();
      int swidth = fm.stringWidth(unitName);
      
      // '12' in width is a magic number.  '2' in height leaves space between text's and scale.
      setSize(xInset*2 + segLength*5 + 12, yInset*2 + scaleHeight + ascent*2 + 2);
      
      // Create drawing image and get graphics context:
      Dimension d = getSize();
      bgImage = createImage(d.width, d.height);
      Graphics bgg = bgImage.getGraphics();
      
      // Prepare for Transparentization:
      bgg.setColor(Color.white);
      bgg.fillRect(0, 0, d.width, d.height);
      
      // Draw what we want:
      bgg.setColor(Color.darkGray);
      bgg.setFont(font);
      int offset = xInset;
      int labelYInset = yInset + ascent;
      int boxYInset = labelYInset + 1/*space text off top of scale*/;
      int lineYInset = boxYInset + (scaleHeight/2);
      int unitsYInset = boxYInset + scaleHeight + 1 + ascent;
      int label = (int)increment / labelDivisor;
      for(int i = 1; i <= 5; i++)
      {
         bgg.drawRect(offset, boxYInset, segLength, scaleHeight); 
         if((i%2)!= 0)
         {
            bgg.drawLine(offset, lineYInset, offset + segLength, lineYInset);
         }
         offset += segLength;
         String lS = String.valueOf(label*i);
         bgg.drawString(lS, offset - fm.stringWidth(lS)/2, labelYInset);
      }
      
      bgg.drawString(unitName, ((offset)/2) - (swidth/2), unitsYInset);
      
      // Transparentize:
      ImageProducer src = bgImage.getSource();
      ImageFilter tfilter = new TransparentOffGFilter(Color.white.getRGB());
      bgImage = createImage(new FilteredImageSource(src, tfilter));
      
      // Clean-up:
      bgg.dispose();
   }
   
   private Image bgImage;
   private int ppd;
   private float centerLat;
   private double mPerLon;                       // meters per degree <latitude|longitude>
   private static final double mPerLat;
   private static final double EARTHRADIUS = 6378020.0;     // in meters
   private static final double DEGPERRAD   = 180.0 / Math.PI;
   private static final double RADPERDEG   = Math.PI / 180.0;
   static
   {
        mPerLat = 2.0 * Math.PI * EARTHRADIUS / 360.0;
   }
   private double ppm;
   private double increment;
   private int segLength;
   private String unitName;
   private int labelDivisor;
}
