/*
 * BBrad.java
 *
 * Created on 2004/03/18, 2:48
 */
import java.awt.*;
import java.awt.Graphics;
import java.awt.event.*;
import java.applet.*;
import java.lang.Math.*;
import javax.swing.*;
import javax.swing.event.*;

/**
 *
 * @author  iromono
 */
public class BBrad extends JApplet {
    double Planckh=6.6260755e-34;
    double Boltzmannk=1.380658e-23;
    double LightSpeed=2.99792458e8;


    int temperature=12000;

    double[][] xyztable={
        {0.0014,0.0042,0.0143,
         0.0435,0.1344,0.2839,0.3483,0.3362,
         0.2908,0.1954,0.0956,0.0320,0.0049,
         0.0093,0.0633,0.1655,0.2904,0.4334,
         0.5945,0.7621,0.9163,1.0263,1.0622,
         1.0026,0.8544,0.6424,0.4479,0.2835,
         0.1649,0.0874,0.0468,0.0227,0.0114,
         0.0058,0.0029,0.0014,0.0007,0.0003,
         0.0002,0.0001,0
        },
        {0,0.0001,0.0004,
         0.0012,0.004,0.0116,0.023,0.038,
         0.06,0.091,0.139,0.208,0.323,
         0.503,0.71,0.862,0.954,0.995,
         0.995,0.952,0.87,0.757,0.631,
         0.503,0.381,0.265,0.175,0.107,
         0.061,0.032,0.017,0.0082,0.0041,
         0.0021,0.0010,0.0005,0.0003,0.0001,
         0.0001,0,0
        },
        {0.0065,0.0201,0.0679,
         0.2074,0.6456,1.3856,1.7471,1.7721,
         1.6692,1.2876,0.813,0.4652,0.272,
         0.1582,0.0782,0.0422,0.0203,0.0087,
         0.0003,0.0002,0,0,0,
         0.0002,0.0002,0.0001,0.0001,0,
         0,0,0,0,0,
         0,0,0,0,0,
         0,0,0,0,0,
         0,0,0
        }
    };
    
    public void init() {
        initComponents();
    }
    
    private void initComponents() {
      Container cont=getContentPane();
      panel1 = new JPanel();
      panel2 = new JPanel();
      RJColor = new JPanel();
      PlanckColor = new JPanel();
      Graph = new JPanel();
      temptext = new JTextField();
      sb = new JSlider();
      
      cont.setLayout(new BorderLayout());
      
      panel1.setLayout(new GridLayout(1, 0));
      
      panel2.setLayout(new GridLayout(2, 1));
      
      panel2.add(RJColor);
      
      panel2.add(PlanckColor);
      
      panel1.add(panel2);
      
      panel1.add(Graph);
      
      cont.add(panel1, BorderLayout.CENTER);
      
      temptext.setText("12000");
      temptext.setEditable(false);
      
      sb.setMaximum(20000);
      sb.setMinimum(500);
      sb.setValue(12000);
      sb.setMajorTickSpacing(2500);
      sb.setMinorTickSpacing(500);
      sb.setPaintTicks(true);
      sb.setPaintLabels(true);
      sb.addChangeListener(new ChangeListener() {
	  public void stateChanged(ChangeEvent evt) {
	    sbAdjustmentValueChanged(evt);
	  }
        });
      
      JPanel panel3= new JPanel();
      panel3.setLayout(new BorderLayout());
      
      panel3.add(temptext, BorderLayout.WEST);
      panel3.add(sb, BorderLayout.CENTER);
      
      cont.add(panel3, BorderLayout.SOUTH);
      
    }

    public void XYZtoRGB(double XYZ[],double RGB[])
    {
	int i;
	
	RGB[0]=0.4184343854*XYZ[0]-0.1586448132*XYZ[1]-0.08284547018*XYZ[2];
	RGB[1]=-0.09116033134*XYZ[0]+0.2524229575*XYZ[1]+ 0.01570763673*XYZ[2];
	RGB[2]=0.0009209266773*XYZ[0] -0.002550045969*XYZ[1]+0.1786426331*XYZ[2];
	for( i=0 ; i<3 ; i++ ) {
	    if( RGB[i]<0 ) RGB[i]=0;
	}
    }

    public double Planck(int t,double n)
    {
	return 8*Math.PI*Planckh*n*n*n/LightSpeed/LightSpeed/LightSpeed/(Math.exp(Planckh*n/(Boltzmannk*t))-1);
    }

    public double RJeans(int t,double n)
    {
	return 8*Math.PI*Boltzmannk*n*n*t/LightSpeed/LightSpeed/LightSpeed;
    }

    public Color BB(int t)
    {
	double n;
	int i;
	int j;
	double xyz[]=new double[3];
	double rgb[]=new double[3];
	
	for(j=0 ; j<3 ; j++ ) {
	    xyz[j]=0.0;
	}
	for( i=0 ; i<41 ; i++ ){
	    n=LightSpeed/((0.38+0.01*i)*1.0e-6);
	    for( j=0 ; j<3 ; j++ ) {
		xyz[j] += xyztable[j][i]*Planck(t,n);
	    }
	}
	XYZtoRGB(xyz,rgb);
	double rgbmax=rgb[0];
	
	if( rgbmax < rgb[1] ) {
	    rgbmax=rgb[1];
	}
	if( rgbmax < rgb[2] ) {
	    rgbmax=rgb[2];
	}

	return new Color(
			 (float)(rgb[0]/rgbmax),
			 (float)(rgb[1]/rgbmax),
			 (float)(rgb[2]/rgbmax)
			 );
    }

     public Color RJ(int t)
     {
         double n;
         int i;
         int j;
         double xyz[]=new double[3];
         double rgb[]=new double[3];

         for(j=0 ; j<3 ; j++ ) {
             xyz[j]=0.0;
         }
         for( i=0 ; i<41 ; i++ ){
             n=LightSpeed/((0.38+0.01*i)*1.0e-6);
             for( j=0 ; j<3 ; j++ ) {
                 xyz[j] += xyztable[j][i]*RJeans(t,n);
             }
         }
         XYZtoRGB(xyz,rgb);
         double rgbmax=rgb[0];

         if( rgbmax < rgb[1] ) {
             rgbmax=rgb[1];
         }
         if( rgbmax < rgb[2] ) {
             rgbmax=rgb[2];
         }

         return new Color(
                          (float)(rgb[0]/rgbmax),
                          (float)(rgb[1]/rgbmax),
                          (float)(rgb[2]/rgbmax)
                          );
     }

    private void sbAdjustmentValueChanged(ChangeEvent evt) {
        // 処理コードをここに追加します:
        temperature=sb.getValue();
        temptext.setText(String.valueOf(temperature));
        repaint();
    }

    public void update(Graphics g) {
	paint(g);
    }

  /**
   * Describe <code>paint</code> method here.
   *
   * @param g a <code>Graphics</code> value
   */
  public void paint(Graphics g) {
        super.paint(g);
        
        Color bb=BB(temperature);
        Color rj=RJ(temperature);
        
        Dimension dim;
        dim=PlanckColor.getSize();
        double w=dim.getWidth();
        double h=dim.getHeight();


	// Planck分布の色を書く。
        Graphics gc=PlanckColor.getGraphics();
        
	gc.setColor(bb);
	gc.fillRect(0,0,(int)w,(int)h);
    

	// レイリージーンズ-分布の色を書く。
	dim=RJColor.getSize();
	w=dim.getWidth();
	h=dim.getHeight();
	gc=RJColor.getGraphics();
	gc.setColor(rj);
	gc.fillRect(0,0,(int)w,(int)h);

	// グラフを書く。
	dim=Graph.getSize();
	w=dim.getWidth();
	h=dim.getHeight();
	gc=Graph.getGraphics();
	gc.setColor(Color.black);
	gc.fillRect(0,0,(int)w,(int)h);

	gc.setColor(Color.red);
	gc.fillRect((int)(0.39*w),0,(int)(0.1*w),(int)h);
	gc.setColor(Color.yellow);
	gc.fillRect((int)(0.49*w),0,(int)(0.05*w),(int)h);
	gc.setColor(Color.green);
	gc.fillRect((int)(0.53*w),0,(int)(0.11*w),(int)h);
	gc.setColor(Color.blue);
	gc.fillRect((int)(0.64*w),0,(int)(0.1*w),(int)h);
	gc.setColor(Color.magenta);
	gc.fillRect((int)(0.74*w),0,(int)(0.05*w),(int)h);

	gc.setColor(bb);

	double nu;
	int i;
	int sp0=(int)h;
	int sp1;

	
	for( i=1 ; i<w ; i++ ) {
	    nu=i*1e15/w;
	    sp1=(int)(h-h*Planck(temperature,nu)/1.5e-14);
	    gc.drawLine(i-1,sp0,i,sp1);
	    sp0=sp1;
	}	

	gc.setColor(rj);
	sp0=(int)h;

	for( i=1 ; i<w ; i++ ) {
	    nu=i*1e15/w;
	    sp1=(int)(h-h*RJeans(temperature,nu)/1.5e-14);
	    gc.drawLine(i-1,sp0,i,sp1);
	    sp0=sp1;
	}	

    }    

    
    
    private JPanel Graph;
    private JPanel PlanckColor;
    private JPanel RJColor;
    private JPanel panel1;
    private JPanel panel2;
    private JSlider sb;
    private JTextField temptext;
}
