
public class DaisyWorldImpl {

	private final static double TIME_MAX = 100;
	// sterberate
	private final static double CHI = 0.10000000000000001;
	
	// Strfan-Bolzmann-Konstante
	private final static double sigma = 5.6699999999999998E-008D;

	// Albedo white, black, ground in [0, 1]
	private final static double alphaw = 0.69999999999999996;
	private final static double alphab = 0.20000000000000001;
	private final static double alphag = 0.40000000000000002;
	private final static double Lmin = 0.40000000000000002;
	private final static double Lmax = 2.6000000000000001;

	private final static boolean autoflag = true;

	// Sonnenkonstante (W/m^2)
	private final static int S0 = 3668;
	
	// temperature
	private final static int T0 = 273;
	private final static int TMIN = -30;
	private final static int TMAX = 130;

	// area white, black planet initial
	private final static int AWPI = 10;
	private final static int ABPI = 10;

	// Transportparameter in [0, 1]; 
	// 0 .. vollstaendige Isolation
	// 1 .. vollstaendiger Wärmetransport
	private final static double R = 0.29999999999999999;
	
	double t;
	// area white, black, ground in [0, 1]
	double Aw, Ab, Ag;
	double betaw, betab;
	// planetare Albedo in [0, 1]
	double alphap;
	// mittlere Temperatur^4, lokale Temperatur weiß und schwarz
	double Tp4, Tw, Tb;
	double Rc;
	// Trimmfaktor fuer Lichtintensitaet
	double L = 1;
	int CTp, CTw, CTb, CTpl;


	private void ejsReset() {
		t = 0;
		Aw = AWPI / 100D;
		Ab = ABPI / 100D;
		constPage();
	}

	private void constPage() {
		Ag = 1.0D - Aw - Ab;
		alphap = Aw * alphaw + Ab * alphab + Ag * alphag;
		Tp4 = ((1 - alphap) * L * S0) / 4D / sigma;
		Tw = Math.pow(((R * L * S0) / 4D / sigma) * (alphap - alphaw) + Tp4, 0.25);
		Tb = Math.pow(((R * L * S0) / 4D / sigma) * (alphap - alphab) + Tp4, 0.25);
		betaw = Math.max(0, 1 - 0.0032650000000000001D * Math.pow(295.5 - Tw, 2));
		betab = Math.max(0, 1 - 0.0032650000000000001D * Math.pow(295.5 - Tb, 2));
		if (autoflag) {
			L = Lmin + ((Lmax - Lmin) * t) / TIME_MAX;
		}
		CTp = (int) Math.round(Math.pow(Tp4, 0.25) - T0);
		CTw = (int) Math.round(Tw - T0);
		CTb = (int) Math.round(Tb - T0);
		CTpl = (int) Math.round(Math.pow(((1 - alphag) * L * S0) / 4D / sigma, 0.25) - T0);
	}

	private void evolPage() {
		double ad[] = new double[3];
		double ad1[] = new double[4];
		double ad2[] = new double[3];
		double ad3[] = new double[4];
		ad1[0] = evolPage0(Aw);
		ad[0] = Aw + (0.5 * ad1[0]) / 2D;
		ad3[0] = evolPage1(Ab);
		ad2[0] = Ab + (0.5 * ad3[0]) / 2D;
		ad1[1] = evolPage0(ad[0]);
		ad[1] = Aw + (0.5 * ad1[1]) / 2D;
		ad3[1] = evolPage1(ad2[0]);
		ad2[1] = Ab + (0.5 * ad3[1]) / 2D;
		ad1[2] = evolPage0(ad[1]);
		ad[2] = Aw + 0.5 * ad1[2];
		ad3[2] = evolPage1(ad2[1]);
		ad2[2] = Ab + 0.5 * ad3[2];
		ad1[3] = evolPage0(ad[2]);
		ad3[3] = evolPage1(ad2[2]);
		Aw += (0.5 * (ad1[0] + 2 * ad1[1] + 2 * ad1[2] + ad1[3])) / 6D;
		Ab += (0.5 * (ad3[0] + 2 * ad3[1] + 2 * ad3[2] + ad3[3])) / 6D;
		t += 0.5;
	}
	
	private double evolPage0(double d1) {
		return d1 * (betaw * Ag - CHI);
	}

	private double evolPage1(double d2) {
		return d2 * (betab * Ag - CHI);
	}
	
	public void reset() {
		ejsReset();
		constPage();
	}

	public void ejsStep() {
		evolPage();
		constPage();
	}

}