// P0901.java:$B@5(B8$BLLBN$K$h$k(B3$B<!85:F5"?^7A(B

package applet;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import Glib.*;

public class P0901 extends xApplet
	implements ActionListener
{	JComboBox cb;
	JButton[]bt=new JButton[3];
	String[]str={"Start","Clear","Exit"};
	xTurtle3 T3;
	xRPh8 ph=new xRPh8(1.0);
	int N=3,NL=4000;
	double r0=112.0,kr=0.5,rtx=15.0,rty=20.0,vpz=2000.0;
	int[]fcolor={2,1,5,4};
	int No=0;
	class xFc
	{	Point[]pvt=new Point[ph.Nvt];
		double depth;
		int color;
	}
	xFc[]fc=new xFc[NL];

	public void init()
	{	app_init(7);
		Container cp=getContentPane();
		cp.setBackground(getBackground());
		cp.setLayout(new FlowLayout(FlowLayout.LEFT));
		JLabel lb=new JLabel("$B:F5"<!?t!'(BN=");
		lb.setForeground(Color.black);
		cp.add(lb);
		cb=new JComboBox();
		cb.setEditable(false);
		for(int i=0;i<5;i++)
			cb.addItem(Integer.toString(i));
		cb.addActionListener(this);
		cp.add(cb);
		for(int i=0;i<str.length;i++)
		{	bt[i]=new JButton(str[i]);
			bt[i].addActionListener(this);
			cp.add(bt[i]);
		}
		T3=new xTurtle3(getGraphics());
		T3.set0(CA,1);
		T3.setpers(rtx,rty,vpz);
	}

	public void actionPerformed(ActionEvent evt)
	{	if(evt.getSource()==cb)
		{	No=0;
			N=cb.getSelectedIndex();
		}
		if(evt.getSource()==bt[0])
			paint2();
		if(evt.getSource()==bt[1])
			repaint();
		if(evt.getSource()==bt[2])
			System.exit(0);
	}

	private void paint2()
	{	rec(r0,0);
		int Face=No;
		xFc dumy;
		for(int i=0;i<Face-1;i++)
		{	for(int j=i+1;j<Face;j++)
			{	if(fc[j].depth<fc[i].depth)
				{	dumy=fc[i];
					fc[i]=fc[j];
					fc[j]=dumy;
				}
			}
		}
		for(No=0;No<Face;No++)
		{	T3.fpolygon(fc[No].pvt,ph.Nvt,fc[No].color);
			T3.polygon(fc[No].pvt,ph.Nvt,0);
		}
		T3.textout(10,60,"No="+No,0,16);
	}

	private void rec(double r,int n)
	{	if(No<NL)
		{	if(n<N)
			{	octa(r);
				T3.warpXpers((1+kr)*r);
				rec(kr*r,n+1);
				T3.warpXpers(-(1+kr)*r);
				for(int i=0;i<4;i++)
				{	T3.turnZ(90.0);
					T3.warpXpers((1+kr)*r);
					rec(kr*r,n+1);
					T3.warpXpers(-(1+kr)*r);
					T3.turnZ(-90.0);
					T3.turnX(90.0);
				}
				if(n==0)
				{	T3.turnZ(180.0);
					T3.warpXpers((1+kr)*r);
					rec(kr*r,n+1);
					T3.warpXpers(-(1+kr)*r);
					T3.turnZ(-180.0);
				}
			}
			else
				octa(r);
		}
	}

	private void octa(double r)
	{	int[]n=new int[ph.Nvt];
		xPoint3D[]vt=new xPoint3D[ph.NVt];
		xPoint3D[]ps=new xPoint3D[ph.NVt];
		xPoint3D nv,np;
		for(int i=0;i<ph.NVt;i++)
		{	double x=T3.getlp3().x+r*(T3.getex().x*ph.Vt[i].x
				+T3.getey().x*ph.Vt[i].y+T3.getez().x*ph.Vt[i].z);
			double y=T3.getlp3().y+r*(T3.getex().y*ph.Vt[i].x
				+T3.getey().y*ph.Vt[i].y+T3.getez().y*ph.Vt[i].z);
			double z=T3.getlp3().z+r*(T3.getex().z*ph.Vt[i].x
				+T3.getey().z*ph.Vt[i].y+T3.getez().z*ph.Vt[i].z);
			vt[i]=new xPoint3D(x,y,z);
			ps[i]=T3.getpers(vt[i]);
		}
		for(int i=0;i<ph.NFc;i++)
		{	for(int j=0;j<ph.Nvt;j++)
				n[j]=ph.Ord[i][j];
			nv=xMath.nop(vt[n[0]],vt[n[1]],vt[n[2]]);
			np=xMath.nop(ps[n[0]],ps[n[1]],ps[n[2]]);
			if(np.z>0)
			{	fc[No]=new xFc();
				for(int j=0;j<ph.Nvt;j++)
					fc[No].pvt[j]=new Point(xMath.fint(ps[n[j]].x),
						xMath.fint(ps[n[j]].y));
				fc[No].color=15;
				for(int j=0;j<ph.NFc/2;j++)
				{	if(Math.abs(nv.x-ph.NV[j].x)<0.1
					&& Math.abs(nv.y-ph.NV[j].y)<0.1
					&& Math.abs(nv.z-ph.NV[j].z)<0.1)
						fc[No].color=fcolor[j];
					if(Math.abs(nv.x+ph.NV[j].x)<0.1
					&& Math.abs(nv.y+ph.NV[j].y)<0.1
					&& Math.abs(nv.z+ph.NV[j].z)<0.1)
						fc[No].color=fcolor[j];
				}
				fc[No].depth=(ps[n[0]].z+ps[n[1]].z+ps[n[2]].z)/3;
				No++;
				if(No>=NL)
				{	T3.textout(10,80,"error:Too small number of NL",0,16);
					return;
				}
			}
		}
	}
}
