import java.awt.*;
import java.applet.*;
import java.lang.Math.*;
import java.util.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;



public class divrot extends JApplet{

    GraphPanel canvas;


    class NumSelect extends JPanel {
	JSpinner sp;
	SpinnerNumberModel model;
	NumSelect(String s) {
	    model = new SpinnerNumberModel(0,-3,3,1);
	    sp=new JSpinner(model);
	    add(sp);
	    add(new JLabel(s));	

	    sp.addChangeListener(new ChangeListener() {
		public void stateChanged(ChangeEvent evt) {
		    writeCanvas(canvas.getGraphics());
		}
	    });

	}
	public int get() {
	    return (Integer)model.getValue();
	}
    }

    NumSelect Ex0,Ey0,Exx,Exy,Eyx,Eyy;
    JCheckBox cbC;


    JSlider sbN,sbM;

    JLabel l1,l2;

    int w,h;
    int pw=-1,ph=-1;

    public void init(){
	canvas=new GraphPanel();

	Container cont=getContentPane();
	cont.setLayout(new BorderLayout());
	
	Exx=new NumSelect("x + ");
	Exy=new NumSelect("y + ");
	Ex0=new NumSelect("");
	Eyx=new NumSelect("x + ");
	Eyy=new NumSelect("y + ");
	Ey0=new NumSelect("");

	sbN=new JSlider();
	sbN.setMaximum(32);
	sbN.setMinimum(8);
	sbN.setValue(15);

	sbM=new JSlider();
	sbM.setMaximum(100);
	sbM.setMinimum(5);
	sbM.setValue(30);


	cbC=new JCheckBox("1/r→e_rを加える");

	cbC.addItemListener(new java.awt.event.ItemListener() {
		public void itemStateChanged(java.awt.event.ItemEvent evt) {
		    repaint();
		}
	    });  

	sbN.addChangeListener(new ChangeListener() {
		public void stateChanged(ChangeEvent evt) {
		    repaint();
		}
	    });

	sbM.addChangeListener(new ChangeListener() {
		public void stateChanged(ChangeEvent evt) {
		    repaint();
		}
	    });

	JPanel p=new JPanel();
	p.setLayout( new GridLayout(2,4));
	p.add(new JLabel("V_x="));
	p.add(Exx);
	p.add(Exy);
	p.add(Ex0);
	p.add(new JLabel("V_y="));
	p.add(Eyx);
	p.add(Eyy);
	p.add(Ey0);


	JPanel p11=new JPanel();
	p11.setLayout(new GridLayout(2,2));
	
	l1=new JLabel("div V=0");
	l2=new JLabel("rot V=0");
 
	p11.add(cbC);
	JPanel p11a=new JPanel();
	p11a.setLayout(new GridLayout(1,2));
	p11a.add(l1);
	p11a.add(l2);
	p11.add(p11a);
	JPanel p11N=new JPanel();
	JPanel p11M=new JPanel();
	p11N.setLayout(new GridLayout(1,2));
	p11M.setLayout(new GridLayout(1,2));

	p11N.add(new JLabel("メッシュ"));
	p11N.add(sbN);
	p11M.add(new JLabel("矢印の大きさ"));
	p11M.add(sbM);

	p11.add(p11N);
	p11.add(p11M);


	JPanel p2=new JPanel();
	p2.setLayout(new GridLayout(1,2));

	p2.add(p);
	p2.add(p11);
    	
	cont.add("South",p2);
	cont.add("Center",canvas);

	start();
    }

    class GraphPanel extends JPanel {
	public void paintComponent(Graphics g){
            if ( g != null ) {
                writeCanvas(g);
            }
	}
    }

    public void drawYajirusi(Graphics g,int x,int y,double vx,double vy)
    {
	int xx=(int)(vx);			
	int yy=(int)(vy);

	Polygon p=new Polygon();

	int vyy=(int)(0.08*vy);
	int vxx=(int)(0.08*vx);
	p.addPoint(x+vyy,y-vxx);
	p.addPoint(x-vyy,y+vxx);
	p.addPoint(x+(int)(0.75*vx-vyy),y+(int)(0.75*vy+vxx));
	p.addPoint(x+(int)(0.75*vx-0.25*vy),y+(int)(0.75*vy+0.25*vx));
	p.addPoint(x+xx,y+yy);
	p.addPoint(x+(int)(0.75*vx+0.25*vy),y+(int)(0.75*vy-0.25*vx));
	p.addPoint(x+(int)(0.75*vx+vyy),y+(int)(0.75*vy-vxx));

        g.fillPolygon(p);
    }

    
    public void writeCanvas(Graphics gc){
        if( gc == null ) {
            return;
        }

	w=canvas.getWidth();
	h=canvas.getHeight();

        int x,y;

	if( w !=pw ) { pw=w;}
	if( h !=ph ) { ph=h;}

	gc.setColor(Color.WHITE);
	gc.fillRect(0,0,w,h);

	int N=sbN.getValue();

	int ww=w/N;


       	int i,j;

	gc.setColor(Color.BLACK);
	gc.drawLine(w/2,0,w/2,h);
	gc.drawLine(0,h/2,w,h/2);

	gc.setColor(Color.GRAY);
	for(i=1 ; i*ww < w/2 ; i++ ) {
	    gc.drawLine(w/2+i*ww,0,w/2+i*ww,h);
	    gc.drawLine(w/2-i*ww,0,w/2-i*ww,h);
	}
	for(j=1; j*ww < h/2 ; j++ ) {
	    gc.drawLine(0,h/2+j*ww,w,h/2+j*ww);
	    gc.drawLine(0,h/2-j*ww,w,h/2-j*ww);
	}

	gc.setColor(Color.RED);

	double bairitsu=((double)sbM.getValue())*0.005;
	double er;

	if( cbC.isSelected() ) {
	    er=10000.0;
	}else{
	    er=0.0;
	}


	double EX0=bairitsu*100.0*Ex0.get();
	double EY0=-bairitsu*100.0*Ey0.get();
	drawYajirusi(gc,w/2,h/2,EX0,EY0);
	for(i=0 ; i*ww < w/2 ; i++ ) {
	    for(j=0; j*ww < h/2 ; j++ ) {
		if( i != 0 || j != 0 ) {
		    double EX1=bairitsu*(Exx.get()*i*ww+er*i/((i*i+j*j)*ww));
		    double EX2=bairitsu*Exy.get()*j*ww;
		    double EY1=bairitsu*Eyx.get()*i*ww;
		    double EY2=bairitsu*(Eyy.get()*j*ww+er*j/((i*i+j*j)*ww));

		    drawYajirusi(gc,w/2+i*ww,h/2-j*ww,
				 EX0+EX1+EX2,EY0-EY1-EY2);
		    drawYajirusi(gc,w/2-i*ww,h/2-j*ww,
				 EX0-EX1+EX2,EY0+EY1-EY2);
		    drawYajirusi(gc,w/2+i*ww,h/2+j*ww,
				 EX0+EX1-EX2,EY0-EY1+EY2);
		    drawYajirusi(gc,w/2-i*ww,h/2+j*ww,
				 EX0-EX1-EX2,EY0+EY1+EY2);
		}
	    }
	}
	int divE=Exx.get()+Eyy.get();
	int rotE=-Exy.get()+Eyx.get();

	l1.setText("div V="+Integer.toString(divE));
	l2.setText("rot V="+Integer.toString(rotE));
    }
}

