import java.awt.*;
import java.awt.event.*;
import javax.swing.event.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.geom.Arc2D;



public class Fletko extends JApplet implements ChangeListener  {
	
	Ploca papir;	
	double gornjaLetvica = 2;
    double donjaLetvica = -2;	
    
       		VTocka sjec1 = new VTocka(0,0);
      		VTocka sjec2 = new VTocka(0,0);
         	JSlider ParametarA;
			JSlider ParametarB;
			JSlider ParametarC;
   		double beta;
   		int dodatak = 0;
   		
   		

	public void init() // Ono sto browser izvodi prije pokretanja Apleta
      	{        	
         	JTextField naslov = new JTextField();
         	             	
        	naslov.setBackground(new Color(204, 255, 102));
        	naslov.setEditable(false);
        	naslov.setFont(new Font("Dialog", 1, 24));
        	naslov.setForeground(new Color(204, 0, 51));
        	naslov.setHorizontalAlignment(JTextField.CENTER);
        	naslov.setText("Panparalelna ploča");
        	naslov.setPreferredSize(new Dimension(450, 50));
			
	
        	ParametarA = new JSlider(1,5,1);	
        	ParametarB = new JSlider(1,5,2);	
        	ParametarC = new JSlider(0,90,45);	
        	
        	ParametarA.setMinorTickSpacing(1);
        	ParametarA.setMajorTickSpacing(5);
        	//ParametarA.setLabelTable(ParametarA.createStandardLabels(5));
        	ParametarA.setPaintTicks(true);
        	ParametarA.setPaintLabels(true);
        	
        	ParametarB.setMinorTickSpacing(1);
        	ParametarB.setMajorTickSpacing(5);
        	//ParametarB.setLabelTable(ParametarB.createStandardLabels(5));
        	ParametarB.setPaintTicks(true);
        	ParametarB.setPaintLabels(true);
        	
        	ParametarC.setMinorTickSpacing(5);
        	ParametarC.setMajorTickSpacing(15);
        	ParametarC.setLabelTable(ParametarC.createStandardLabels(15));
        	ParametarC.setPaintTicks(true);
        	ParametarC.setPaintLabels(true);
        	
        	ParametarA.addChangeListener(this);
        	ParametarB.addChangeListener(this);
        	ParametarC.addChangeListener(this);
        	
        	JPanel kucicaA, kucicaB, kucicaC;
        	
        	kucicaA = new JPanel();
        	kucicaA.setBorder(new TitledBorder("Koeficjent n1"));
        	kucicaA.add(ParametarA);
        	
        	kucicaB = new JPanel();
        	kucicaB.setBorder(new TitledBorder("koeficjent n2"));
        	kucicaB.add(ParametarB);
        	
        	kucicaC = new JPanel();
        	kucicaC.setBorder(new TitledBorder("Upadni kut alfa"));
        	kucicaC.add(ParametarC);
        	
        	JLabel oznaka = new JLabel("A sin(Bx+C)");
        	JPanel kucicaFje = new JPanel();
        	kucicaFje.setBorder(new TitledBorder("Funkcija"));
        	kucicaFje.add(oznaka);
        	
        	JPanel gumbici = new JPanel();
        	gumbici.setLayout(new GridLayout(4,1));
        	//gumbici.add(kucicaFje);
        	gumbici.add(kucicaA);
        	gumbici.add(kucicaB);
        	gumbici.add(kucicaC); 
        	
        	
        	
			Sinus funkcija;     	
        	funkcija = new Sinus(ParametarA, ParametarB, ParametarC);
        	
        	papir = new Ploca(funkcija,-6,6,-5,5);

			getContentPane().setLayout(new BorderLayout());
			getContentPane().add(naslov, BorderLayout.NORTH);
			getContentPane().add(papir, BorderLayout.CENTER);
			getContentPane().add(gumbici, BorderLayout.EAST);
			
  int delay = 50; //milliseconds
  ActionListener taskPerformer = new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
          //...Perform a task...
          papir.repaint();
      }
  };
  new Timer(delay, taskPerformer).start();
      	}
      	
	private class Ploca extends JPanel 
      	{
      		double xm;
      		double xM;
      		double ym;
      		double yM;
      		Sinus f;
      		
      		int n = 1000; 

      		Ploca()
      			{
      				xm = -5;
      				xM = 5;
      				ym = -5;
      				yM = 5;
      				f = new Sinus(1,1,0);
      			}
      		
      		Ploca(Sinus fja, double a, double b, double c, double d)
      			{
      				xm = a;
      				xM = b;
      				ym = c;
      				yM = d;
      				f = fja;
      			}

      		public void paintComponent(Graphics g) 
        		{
        			setBackground(Color.white);
            		super.paintComponent(g); 	
            		
            		UTocka M = new UTocka(getWidth(),getHeight());
            	
            		g.drawRect(0,0,getWidth()-1,getHeight()-1);
            	
            		UTocka P = uvoz(new VTocka(0,0),M);
            	
            		//g.drawLine(P.x,0,P.x,M.y-1);
            		//g.drawLine(0,P.y,M.x-1,P.y);
            		
            		dodatak = dodatak + 10;
            		if (dodatak==n-500) {dodatak=0;}
            		
            		g.setFont(new Font("Dialog", 2, 24));
            		UTocka temp = uvoz(new VTocka(0,gornjaLetvica), M);
            		g.drawLine(0,temp.y,M.x-1,temp.y);
            		g.drawString("n1", M.x-30, (int) temp.y/2);
            		g.drawString("n1", M.x-30, (int) (M.y-temp.y/2));
            		double dubravka = temp.y;
            		
            		temp = uvoz(new VTocka(0,donjaLetvica), M);
            		g.drawLine(0,temp.y,M.x-1,temp.y);
            		g.drawString("n2", M.x-30, (int) (dubravka+(temp.y-dubravka)/2));
            		
            		crtaj(f, Color.blue, g, M);
            		
            		// funkcija je f
            		P = uvoz(new VTocka(sjec2.x,sjec2.y), M);
            		temp = uvoz(new VTocka((gornjaLetvica-f.l3)/(f.k1), gornjaLetvica), M);
            		g.drawLine(P.x, P.y, temp.x, temp.y);
            		
            		P = uvoz(new VTocka(sjec1.x,sjec1.y), M);
            		temp = uvoz(new VTocka((((1/f.k1)*sjec1.x+sjec1.y-f.l3)/(f.k1+(1/f.k1))),(f.k1*(((1/f.k1)*sjec1.x+sjec1.y-f.l3)/(f.k1+(1/f.k1)))+f.l3)), M);
            		g.drawLine(P.x,P.y, temp.x, temp.y);
            		g.drawString("d",(int) (temp.x+(P.x-temp.x)/2-15), (int) P.y+(temp.y-P.y)/2);
            		
            		// crtanje lukova
            			//tocka sredista luka
            			temp = uvoz(new VTocka(sjec1.x,sjec1.y), M);
            			g.setFont(new Font("Dialog", 2, 24));
            			
            			g.drawLine(temp.x,temp.y,temp.x,temp.y-120);            				
            			g.drawArc(temp.x-(50),temp.y-(50),100,100,90, ParametarC.getValue()+2);
            			g.drawString("a",temp.x-20,temp.y-25);
            			
            			g.drawLine(temp.x,temp.y,temp.x,temp.y+120);            				
            			g.drawArc(temp.x-(50),temp.y-(50),100,100,270, (int) beta+2);
            			g.drawString("b",temp.x+1,temp.y+40);
            			
            			temp = uvoz(new VTocka(sjec2.x,sjec2.y), M);
            			
            			g.drawLine(temp.x,temp.y,temp.x,temp.y-120);            				
            			g.drawArc(temp.x-(50),temp.y-(50),100,100,270, ParametarC.getValue()+2);
            			g.drawString("b",temp.x-15,temp.y-25);
            			
            			g.drawLine(temp.x,temp.y,temp.x,temp.y+120);            				
            			g.drawArc(temp.x-(50),temp.y-(50),100,100,90, (int) beta+2);
            			g.drawString("a",temp.x+1,temp.y+30);
         		}
         		
         	public void crtaj(Sinus fja, Color boja, Graphics obris, UTocka M)
         		{
         			
         			obris.setColor(boja);
         		
         			UTocka u = new UTocka();       			
         			VTocka v = new VTocka();
         			UTocka su = u; // staro u
         			
         			double h = ( xM - xm ) / n; 
         			
         			for (int i=0; i<n; i=i+1)
         				{
         					v.x = xm + i * h;
         					// Ako je i djeljivo s 100 promjeni boju
         						if ((i==dodatak+100)||(i==dodatak+150)||(i==dodatak+200)||(i==dodatak+250)||(i==dodatak+300)||(i==dodatak+350)||(i==dodatak+400)||(i==dodatak+450))
         							{
         								if (obris.getColor()==Color.blue)
         									{obris.setColor(Color.yellow);}
         									else {obris.setColor(Color.blue);}
         							}
         					v.y = fja.vrijednost(v.x);
         					u = uvoz(v, M);
         			//		obris.drawLine(su.x,su.y,u.x,u.y);
         					obris.drawOval(su.x,su.y,4*(u.x-su.x),4*(u.y-su.y));
         					su = u;
         				}
         				
         			//obris.dispose(); 
         		}
         		
         	public UTocka uvoz(VTocka T, UTocka U)
         		{
         			int sirina = U.x;
         			int dubina = U.y;
         			
         			UTocka I = new UTocka();
         		
         			I.x = (int) Math.round( ( T.x - xm )/( ( xM - xm ) / ( sirina ) ) );
         			I.y = (int) Math.round( ( yM - T.y )/( ( yM - ym ) / ( dubina ) ) );
         			
         			return I;
         		}
         	
         	public VTocka izvoz(UTocka T, UTocka U)
         		{
         			int sirina = U.x;
         			int dubina = U.y;
         			
         			VTocka I = new VTocka();
         			
         			I.x = xm + ( T.x * ( ( xM - xm )/sirina ) );
         			I.y = xM - ( T.y * ( ( yM - ym )/dubina ) );
         			
         			return I;
         		}
      	}
      	
      private class UTocka
      	{
      		int x;
      		int y;
      		
      		UTocka()
      			{
      			}
      		
      		UTocka(int a, int b)
      			{
      				x = a;
      				y = b;
      			}
      	}

      private class VTocka
      	{
      		double x;
      		double y;
      		
      		VTocka()
      			{      				
      			}
      			
      		VTocka(double a, double b)
      			{
      				x = a;
      				y = b;
      			}
      	}

      private class Sinus
      	{
      		JSlider n1, n2, alpha;
      		double l1 = 1.5;
      		Boolean crtas = new Boolean(true);
      		double k1;
   			double k2;
      		double l2;
      		double k3;
      		double l3;

      		
      		Sinus(int a, int b, int c)
      			{
      				n1 = new JSlider(-10,10,a);
      				n2 = new JSlider(-10,10,b);
      				alpha = new JSlider(-10,10,c);
      			}
      		
      		Sinus(JSlider a, JSlider b, JSlider c)
      			{
      				n1 = a;
      				n2 = b;
      				alpha = c;
      			}
      		
      		public double vrijednost(double x)
      			{
      				// racunanje prve jednadžbe
      					
      					k1 = Math.tan(Math.toRadians(alpha.getValue()+90));
      				// prvu tocku
      					sjec1.x = (gornjaLetvica - l1) / (Math.tan(Math.toRadians(90+alpha.getValue())));
      					sjec1.y = gornjaLetvica;
      				// druga jednadzba
      					
      					
      					beta = Math.asin(((n1.getValue())*Math.sin(Math.toRadians(alpha.getValue())))/(n2.getValue()));
      					beta = Math.toDegrees(beta);
      					k2 = Math.tan(Math.toRadians(90+beta));
      					l2 = -1 * Math.tan(Math.toRadians(90+beta))* sjec1.x +gornjaLetvica;
      				
      				// druga tocka
      					sjec2.x = (donjaLetvica-l2)/(k2);
      					sjec2.y = donjaLetvica;
      					
      				//treca jednadzba
      					
      					
      					k3 = k1;
      					l3 = -1 * k1 * sjec2.x + sjec2.y;
      					
      				// racun
      					double rjesenje=0;
      					
      					if (x<=sjec1.x)
      						{
      							rjesenje = k1 * x + l1;
      						}
      					if ((x>sjec1.x)&&(x<=sjec2.x))
      						{
      							rjesenje = k2 * x + l2;
      						}
      					if (x>sjec2.x)
      						{
      							rjesenje = k3 * x + l3;
      						}
      					
      				return rjesenje;
      			}
      			
      		public String izraz()
      			{
      				return "Nemoj mene koristiti!";
      			}
      	}
      	
	public void stateChanged(ChangeEvent evt) 
		{
       		papir.repaint();       		
   		} 
   }  

