/*
newton
z4 + z3 + z - 1 = 0
	-i,i,0.618034,-1.618034
z4 + 3 z3 + 2 z2 + 0.2 z + 1 = 0
	= -1.675245 -0.11495 x i = -1.675245 + 0.11495 x i = 0.175245 -0.569159 x i = 0.175245 + 0.569159 x i
z4 + z3 - 1 = 0 
	X1 = -0.219447 -0.914474 x i  X2 = -0.219447 + 0.914474 x i  X3 = 0.819173  X4 = -1.380278
z3 + 2 z2 + z + 3 = 0
X1 = -2.174559  X2 = 0.08728 -1.171312 x i  X3 = 0.08728 + 1.171312 x i
-2 z4 + z3 + z2 - 2 z - 1 = 0
X1 = 0.877439 -0.744862 x i X2 = 0.877439 + 0.744862 x i  X3 = -0.5  X4 = -0.754878
*/

import java.awt.Graphics;
import java.awt.Image; 
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO; 
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.event.*;
import java.awt.*; 
import java.awt.image.BufferedImage;
import java.util.Timer;
import java.util.TimerTask; 
import java.awt.Dimension;
import java.awt.*;
 
public class Panneaunewton extends JPanel implements MouseListener
{
	static int longueur;
	static int haut; 
  static double minX = -3.0;
	static double maxX = 3.0;
	static double minY = -1.5;
	static double maxY =  1.5;
	static int nb=200;
	static boolean flag=true;
	static boolean listen=false;
	static boolean dyna=false; 
	static int nbi; 
	static boolean racines=false;
	static boolean traveling=false;
	static boolean montre=true;
	static double pastravel=0.0001;
	static int ractravel=1;
	static Timer t=new Timer();
 	static int nbcycle=10;
 	static int ncycle=0;
 	static boolean cycle=false;
	static boolean cycled=false; 
	static double cyclex;
	static double cycley;
	static int numfon=0;
	static String tabfon[]={"(z-1)(z-1/2-a)(z-1/2+a)","z3-1","z4-1","z5-1","z4 + z3 + z - 1","z4 + 3 z3 + 2 z2 + 0.2 z + 1","z4 + z3 - 1","-2 z4 + z3 + z2 - 2 z - 1","z3 + 2 z2 + z + 3 ","Z2-1"};
	
	double RZ;
	double IZ;
	double RC;
	double IC; 
	double R;
	double I;

 
	static int degre=3;
//  static double racx[]={1.0,Math.cos(2*Math.PI/3),Math.cos(4*Math.PI/3),0.0,0.0,0.0};
//  static double racy[]={0.0,Math.sin(2*Math.PI/3),Math.sin(4*Math.PI/3),0.0,0.0,0.0}; 
		static double racx[]={1.0,-0.5-0.00508,-0.5+0.00508,0.0,0.0,0.0};
  	static double racy[]={0.0,0.33136,-0.33136,0.0,0.0,0.0}; 

  static double resux;
  static double resuy;
  static Color tabcolor[]={Color.red,Color.yellow,Color.blue,Color.green,Color.cyan,Color.magenta,Color.orange};

 Dimension dime = Toolkit.getDefaultToolkit().getScreenSize();
  int theight = (int)dime.getHeight();
	int twidth  = (int)dime.getWidth();
 BufferedImage buffimag = new BufferedImage(twidth, theight, BufferedImage.TYPE_INT_RGB); 
//public void init() { 
//	 addMouseListener(this);
//	 System.out.println("init mouselistener");
//} 
	
public void mousePressed(MouseEvent e) 
{ 
int buttonDown = e.getButton();
double vx=e.getX();
double vy=e.getY();
double RC=minX + (maxX - minX)/(double)longueur * (double)vx;
double IC=minY + (maxY - minY)/(double)haut * (double)vy;

if (buttonDown == MouseEvent.BUTTON3) 
	{ 
/*	nb=200;
	nbi=0; 
	dyna=true;*/
	//System.out.println("bouton droit");}	// Bouton DROIT enfoncé 
	dyna=false;
	cycle=true;
	cyclex=RC;
	cycley=IC;
	if (cycled==false) {t.schedule(new timetask(),50,1511);}
 	cycled=true;
 	repaint();
	}
else {
if (buttonDown == MouseEvent.BUTTON2) 
	{
	dyna=false;
	cycle=false;
	racx[ractravel]=RC;
	racy[ractravel]=IC;
	
	repaint();}// Bouton du MILIEU enfoncé
else 
	{
	if (buttonDown == MouseEvent.BUTTON1) {dyna=false;//Bouton GAUCHE enfoncé
 		{
	
		//Invoked when the mouse has been clicked on a component.
		if (flag==true) 
			{flag=false;
		//System.out.println("Pressed"+vx+"-"+vy+"- "+minX+"-"+maxX+"- "+minY+"-"+maxY  );

			double deltaX=maxX-minX;
			double deltaY=maxY-minY;

			minX=RC-deltaX/5.0;
			maxX=RC+deltaX/5.0;
			minY=IC-deltaY/5.0;
			maxY=IC+deltaY/5.0;
			nb=nb+40;
			//text.visible=false; 
			//System.out.println(""+deltaX+"-"+deltaY+"- "+minX+"-"+maxX+"- "+minY+"-"+maxY);
			repaint();
			}
		}
	}
} } }

public void mouseClicked(MouseEvent e) {
	//System.out.println("Clicked");
	}
	//Invoked when a mouse button has been pressed on a component.

public void mouseReleased(MouseEvent e) {
	//System.out.println("Released");
	}
	//Invoked when a mouse button has been released on a component.

public void mouseEntered(MouseEvent e) {
	//System.out.println("Entered");
	}
	//Invoked when the mouse enters a component.

public void mouseExited(MouseEvent e) {
	//System.out.println("Exited");
	}
	//Invoked when the mouse exits a component.


private void mul(double a, double b, double m, double n)
	{
	resux=a*m-b*n;
	resuy=a*n+b*m;
	}
	
private void calcule()

{
int j;
int k;
double derivx;
double derivy;
double fx;
double fy;
double elemx;
double elemy;

			fx=RZ-racx[0];
			fy=IZ-racy[0];
			for (j=1;j<degre;j++)
				{
				mul(fx,fy,RZ-racx[j],IZ-racy[j]);
				fx=resux;
				fy=resuy;
				} // j
			derivx=0;
			derivy=0;
			for (j=0;j<degre;j++)
				{
				elemx=1;
				elemy=0; 
				for (k=0;k<degre;k++)
					{
					if (k==j) {} else 
						{mul(elemx,elemy,RZ-racx[k],IZ-racy[k]);
						elemx=resux;
						elemy=resuy;}
					} //k 
				derivx=derivx+resux;
				derivy=derivy+resuy;
				} // j 
			mul(fx,fy,derivx,-derivy);
			RZ=R-resux/(derivx*derivx+derivy*derivy);
			IZ=I-resuy/(derivx*derivx+derivy*derivy);
} 

public void paintComponent(Graphics g){

int color;
//Color col;
boolean  stop;
int a;

int X;
int Y;
int j;
flag=false;

 
if (listen==false) {addMouseListener(this);}
listen=true;
color=0;
//col=Color.black; 
for(X= 0;X<longueur-1;X++)
	{ 
	for (Y= 0;Y<haut-1;Y++)
		{ 
 		RZ = minX + (maxX - minX)/longueur * X;	// RZ est la partie réelle de Zn
		IZ = minY + (maxY - minY)/haut * Y;			// IZ la partie imaginaire
	
		stop=false;
		a=0; 
		while (stop==false)
			{ R = RZ;	// RZ est la partie réelle de Zn; R est la valeur en cours de calcul Zn+1. 
			I = IZ;
			calcule();
				
/*			RZ = R*R - I*I + RC;
			IZ = 2* R*I + IC; */
			
			if ( (RZ-R)*(RZ-R) + (IZ-I)*(IZ-I) <0.00001) 
				{stop=true;
				color=0;
				if (racines==false)
					{color=(nb-1-a)*0xFFFFFF*(nb-a)/nb;
					//col=new Color(color);
					}
				else
					{
					for (j=0;j<degre;j++)
						{
						if ((Math.abs(racx[j]-RZ)<0.0001) && (Math.abs(racy[j]-IZ)<0.0001))
							{color=tabcolor[j].getRGB();}
						}
					}
				}
 			if (a==nb-1) {stop=true;color=(nb-1-a)*0xFFFFFF/nb;
 				//col=new Color(color);
 				}
 			if (stop==false)	{a++;}
 			} // while
 			
		buffimag.setRGB(X, Y, color);
/* 		g.setColor(col);          
 		g.drawLine(X,Y,X,Y+1);*/
 		} // for Y
 	}	// for X
g.drawImage(buffimag, 0, 0, null);  

if (cycle==true) 
	{
	X= (int) Math.floor((cyclex -minX)/(maxX - minX)*longueur);
	Y=(int) Math.floor( (cycley -minY)/(maxY - minY)*haut);
//	System.out.println("croix "+cyclex+" "+cycley+" "+X+" "+Y);
	g.setColor(Color.white);
	g.drawLine(X-3,Y,X+3,Y);
	g.drawLine(X,Y-3,X,Y+3);
	}

if (montre==true)
{ 
for (j=0;j<degre;j++)
	{
	if (j==ractravel)
		{g.setColor(Color.red);}
	else
		{g.setColor(Color.white);}
	resux=0;
	resuy=0;
	resux=(racx[j]-minX)/(maxX - minX)* longueur;
	resuy=(racy[j]-minY)/(maxY - minY)* haut;
	X= (int) resux;
	Y= (int) resuy;
	g.drawLine(X-5,Y,X+5,Y);
	g.drawLine(X,Y-5,X,Y+5); 
	/*
	resux=(-1-minX)/(maxX-minX)*longueur;
	resuy=(-minY)/(maxY - minY)*haut;
	X=(int) resux;
	Y=(int) resuy;
	g.drawLine(X-5,Y,X+5,Y);
	g.drawLine(X,Y-5,X,Y+5);*/
	}
}
 
flag=true;
}
 
 class timetask extends TimerTask
        	{
        	public void run()  
        		{
    				if ((cycle==true) && (flag==true))
    						{
        				R=cyclex;
        				I=cycley;
        				RZ=R;
        				IZ=I;
        				calcule();
        			//	if ((RZ-cyclex)*(RZ-cyclex)+(IZ-cycley)*(IZ-cycley) < 0.0001) {cycle=false;}
        				cyclex=RZ;
        				cycley=IZ;
        		//		System.out.println("timer "+RZ+" "+IZ);
        				repaint();
        				}
        		}
        	}
}

