/*  Copyright (C) Stephen Lee 2007 .  
 *  Email:stephen@tachyos.org  
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *  
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

package cosmod;


import java.util.*;
import java.text.*;
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.lang.*;

public class cosmod1 extends Applet implements ItemListener {

Thread timer = null;
Choice cevol=new Choice();
Color pacol=new Color(244,255,255);
Color bgcol=new Color(235,244,244);
Color[] dcol ={Color.black,new Color(0,255,0),Color.blue,Color.red,Color.lightGray,
               Color.orange,  Color.lightGray};
MainPanel MP=new MainPanel();
//CG=new CheckboxGroup();
Checkbox CBt[]=new Checkbox[4];
Checkbox CBd[]=new Checkbox[7];
Checkbox CBwide;
Label Dlab=new Label("Distance Measure");
Label Tlab=new Label("Time");
Font bf=new Font("Arial",Font.BOLD,12);
//int dp[]={5,4,4};
int lo=30;
double[] steps={0.0,20.0,5.0};
boolean uflg=true;


double kpw=Math.log(10.0)/100.0;
//int ms=20,pwid=600,phgt=600;

  public cosmod1() {
  }

double sinh(double x){
return (Math.exp(x)-Math.exp(-x))/2;}

double cosh(double x){
return (Math.exp(x)+Math.exp(-x))/2;}

double dfn(double z,int na,int nt, int nd){
double fz,fz2,chi,d,t,T0,tbar,tx,tm,rnow,c2,a,fzx;

int i;
fz=1.0+z;fz2=fz*fz;
d=z;fzx=fz;
if (na==0)  {
  switch (nt){
  case 0:d=z/fz;break;
  case 1:if (z<1.0) d=z/Math.sqrt(1-z*z);else d=1e5;}
  fzx=1/(1-d);
  if (nd==1){
    if (Math.abs(d)<1.0)d= Math.log((1+d)/(1-d))/2.0;
    else return 1e5;}
  else if (nd==5)if (fzx>0) return Math.log(fzx);else return 1e5;}
else {
  chi=Math.log(fz);t=1/fz;tbar=1/cosh(chi);T0=1;  //a=t
  switch (na){ //na a=e^Ht,t,t^½,t^(2/3)
  case 2:T0=0.5;t=T0/fz2;chi=2*z*Math.sqrt(t);tbar=T0-chi*chi/4;break;
  case 3:T0=2.0/3;t=T0/(fz*Math.sqrt(fz));chi=3*(1-1/Math.sqrt(fz))*0.87358046;
    tbar=0.000001;c2=chi*chi/9;
    for (i=1;i<=7;i++){
      tm=Math.pow(tbar,T0);tbar-=(tm*(tbar-T0)+tbar*c2)/(tm+c2/3);}}
  tx=t;fzx=fz;
  switch (nt){case 1:tx=tbar;break;case 2: tx=T0;}
  switch (na){
  case 1:if (nd==5)return z*tx;
    if (nd>0)d=tx*sinh(chi);else  d=tx*chi; break;
  case 2:d=chi*Math.sqrt(tx);fzx=1+0.5*d/tx;
    if (nd==5) return d+chi*chi/4;break; //a=t^1/2
  case 3:tm= Math.pow(tx,1.0/3.0);d=chi*tm*tm;//a=t^2/3
         fzx=1+d/(3*tx);fzx*=fzx;
         if ((nd==1)||(nd==5)) d+=chi*chi*chi/27.0;
         if (nd==5) d+=chi*chi*tm/3;
  }}
if (nd==3) if (fzx>0) return d*fzx*fzx;else return 1e5;
if (nd==4) if (fzx>0) return d*fzx;else return 1e5;

return d;}

public void init() {
int i;
CBt[0]=new Checkbox("Emission Time",true);
CBt[1]=new Checkbox("Radar now",false);
CBt[2]=new Checkbox("Comoving Now",true);
CBt[3]=new Checkbox("Usual for dist.",false);
CBd[0]=new Checkbox("Comoving",true);
CBd[1]=new Checkbox("Radar",true);
CBd[2]=new Checkbox("Angular diameter ",true);
CBd[3]=new Checkbox("Luminosity ",true);
CBd[5]=new Checkbox("Light travel time",true);
CBd[4]=new Checkbox("Transverse comoving",true);
CBd[6]=new Checkbox("Scale Factor",true);
CBwide=new Checkbox("Larger range",false);
setBackground(bgcol);
setLayout(null);
add(MP);
MP.setBounds(lo,0,600,600);
MP.setBackground(pacol);
add(cevol);
cevol.setBounds(lo+610,5,175,20);
cevol.add("Steady State: e^Ht");
cevol.add("Empty: t");
cevol.add("Radiation dominated: t^1/2");
cevol.add("Matter dominated: t^2/3");
cevol.select(0);
cevol.addItemListener(this);
add(Dlab);
Dlab.setFont(bf);
Dlab.setBounds(lo+650,42,120,20);
for (i=0;i<6;i++){
  add(CBd[i]);
  CBd[i].setBounds(lo+610,60+30*i,140,20);
  CBd[i].addItemListener(this);}
add(Tlab);
Tlab.setFont(bf);
Tlab.setBounds(lo+660,262,100,20);
for (i=0;i<4;i++){
  add(CBt[i]);
  CBt[i].setBounds(lo+610,280+30*i,110,20);
  CBt[i].addItemListener(this);}

add(CBwide);
CBwide.setBounds(lo+610,420,110,20);
CBwide.addItemListener(this);
 }




 public void paint(Graphics g){
 int i;
 g.setColor(dcol[0]);
 g.drawString("z",lo+280,620);
 g.drawString("dist",3,300);
 g.drawLine(3,302,23,302);
 g.drawString("c/H",3,314);
 g.drawOval(21,313,4,4);
  for (i=0;i<6;i++){
   g.setColor(dcol[i]);
   g.drawLine(lo+755,70+30*i,lo+800,70+30*i);}
  g.setColor(Color.black); 
  for (i=0;i<3;i++)
   drawLinex(g,lo+725,290+30*i,lo+800,290+30*i,steps[i]);
 }

public void itemStateChanged(ItemEvent e){
for (int i=0;i<3;i++)CBt[i].setEnabled(!CBt[3].getState());
MP.repaint();}


  public String getAppletInfo() {
    return "Cosmological distances";
  }



double spos,gx,gy,ox,oy;
void lineg(Graphics g,double s,double e){
g.drawLine((int)(ox+s*gx),(int)(oy+s*gy),(int)(ox+e*gx),(int)(oy+e*gy));
}
void drawLinex(Graphics g,int x1,int y1,int x2,int y2,double step){
double dx,dy,len,epos,iep;
int i,ie;
if (step==0.0) {g.drawLine(x1,y1,x2,y2);return;}
dx=x2-x1;dy=y2-y1;
len=Math.sqrt(dx*dx+dy*dy);
epos=spos+len;
gx=dx/len;gy=dy/len;
ox=x1-spos*gx;oy=y1-spos*gy;
if (spos>step) spos=2*step;
else if (epos<step)lineg(g,spos,epos);else lineg(g,spos,step);
if (epos>2*step){
  ie=(int)(epos/(2*step)); iep=2*step*ie;
  for (i=1;i<ie;i++)lineg(g,2*i*step,(2*i+1)*step);
  if (epos-iep<step)lineg(g,iep,epos);
  else lineg(g,iep,iep+step);}
else iep=0;
spos=epos-iep;}


boolean w=false;

class MainPanel  extends Canvas{

public void paint(Graphics g){
int i,px,py,px0,py0,sn;
int na,nt,ntx,nd;
double z,fz,d,chi,step,ax;
boolean uflg=CBt[3].getState();
w=CBwide.getState();
sn=w?1:2;
spos=2;
na=cevol.getSelectedIndex();
ax=w?0.01:0.1;
for (i=0;i<(w?5:3);i++){
  px=(int)(sn*Math.log(ax/(w?0.001:0.04))/kpw);
  g.drawLine(px,600,px,590);
  g.drawString(Double.toString(ax),px-10,580);
  py=600-(int)(sn*Math.log(ax/(w?0.001:0.04))/kpw);
  g.drawLine(0,py,10,py);
  g.drawString(Double.toString(ax),15,py+5);
  ax*=10;}
for (nt=0;nt<4;nt++) if ((uflg==(nt==3))&&CBt[nt].getState())
for (nd=0;nd<6;nd++) if (CBd[nd].getState()){
if (nt==3)if (nd==0)ntx=2;else ntx=0;else ntx=nt;
g.setColor(dcol[nd]);
px0=0;py0=600;
for (i=0;i<(w?600:300);i++){
  px=sn*i;
  z=(w?0.001:0.04)*Math.exp(i*kpw);
  d=dfn(z,na,ntx,nd);
  py=600-(int)(sn*Math.log(d/(w?0.001:0.04))/kpw);
  drawLinex(g,px0,py0,px,py,steps[ntx]);
  px0=px;py0=py;}
}}//paint
}//MainPanel
}

