import apprentissage.CourbeFonction;
import apprentissage.IFonction;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.io.Writer;
import java.util.Observable;
import java.util.Observer;
import javax.swing.*;
import utils.Temoin;
 
public class Relaxation extends JApplet implements ActionListener, IFonction, Observer
{
 
    public Relaxation()
    {
        pane = new JPanel(new BorderLayout());
        dessins = new JPanel(new GridLayout(3, 1));
        dessin1 = new CourbeFonction(0, this);
        dessin2 = new CourbeFonction(1, this);
        dessin3 = new CourbeFonction(2, this);
        boutons = new JPanel();
        bNouvelleFonction = new JButton("Nouvelle Fonction");
        bNouveauCycle = new JButton("Nouveau Cycle");
        coeffs = new double[15];
        v1 = 0.33D;
        v2 = 0.33D;
        v3 = 0.34D;
        old1 = 0.0D;
        old2 = 0.0D;
        delta1 = 0.0D;
        delta2 = 0.0D;
    } // Relaxation()
 
    /***************************
    * The function to discover *
    ***************************/
     
    protected double fonction(double d, double d1, double d2)
    {
        double d3 = coeffs[0];
        for(int i = 1; i < 5; i++)
            d3 += coeffs[i] * Math.sin((d + d1) * (double)(1 + i) * 3.14159D + coeffs[15 - i]);
 
        d3 += 5D * coeffs[5] * Math.pow(d, 2D);
        d3 += 5D * coeffs[6] * Math.pow(d1, 3D);
        d3 += 5D * coeffs[7] * Math.pow(d2, 4D);
        d3 += 5D * coeffs[8] * Math.pow(d + d2, 5D);
        d3 += 5D * coeffs[9] * Math.pow(d1 + d2, 6D);
        return d3;
    } // fonction()
 
    /*****************
    * Event Managing *
    *****************/
    
    protected void nouvelleFonction()
    {
        for(int i = 0; i < coeffs.length; i++)
            coeffs[i] = Math.random() - Math.random();
 
        v1 = Math.random();
        v2 = Math.random() * (1.0D - v1);
        v3 = 1.0D - (v1 + v2);
        old1 = v1;
        old2 = v2;
        delta1 = 0.0D;
        delta2 = 0.0D;
        dessin1.setAuto(1.0D);
        dessin2.setAuto(1.0D);
        dessin3.setAuto(1.0D);
    } // nouvelleFonction()
 
    protected void nouveauCycle()
    {
        old1 = v1;
        old2 = v2;
        delta1 = 0.0D;
        delta2 = 0.0D;
        dessin3.setAuto(1.0D);
    } // nouveauCycle()
 
    public void actionPerformed(ActionEvent actionevent)
    {
        if(actionevent.getSource().equals(bNouvelleFonction))
            nouvelleFonction();
        else
        if(actionevent.getSource().equals(bNouveauCycle))
            nouveauCycle();
    } // actionPerformed(ActionEvent)
 
    /******************
    * The Applet part *
    ******************/
    
    public void init()
    {
        dessins.add(dessin1);
        dessin1.temoin.addObserver(this);
        dessin1.setBornesX(0.0D, 1.0D);
        dessins.add(dessin2);
        dessin2.temoin.addObserver(this);
        dessin2.setBornesX(0.0D, 1.0D);
        dessins.add(dessin3);
        dessin3.temoin.addObserver(this);
        nouvelleFonction();
        pane.add(dessins, "Center");
        bNouvelleFonction.addActionListener(this);
        boutons.add(bNouvelleFonction);
        bNouveauCycle.addActionListener(this);
        boutons.add(bNouveauCycle);
        pane.add(boutons, "South");
        setContentPane(pane);
    } // init()
 
    public void start()   {}
 
    public void stop()    {}
 
    public void destroy() {}
 
    /*********************
    * The IFonction part *
    *********************/
 
    public double valeur()
    {
        return fonction(v1, v2, v3);
    }
 
    public int nbParametres()
    {
        return 2;
    }
 
    public double[] domaine(int i) throws IllegalArgumentException
    {
        double ad[] = new double[2];
        if(i != 2)
        {
            ad[0] = 0.0D;
            if(i == 0)
                ad[1] = 1.0D - v2;
            else
                ad[1] = 1.0D - v1;
        } else
        {
            double d = delta1 + delta2;
            double d1 = old1 + old2;
            double d2 = -1000000000000D;
            double d3 = 1000000000000D;
            double d4 = (1.0D - d1) / d;
            if(d > 0.0D)
                d3 = d4;
            else
            if(d < 0.0D)
                d2 = d4;
            d4 = -old1 / delta1;
            if(delta1 > 0.0D)
            {
                if(d2 < d4)
                    d2 = d4;
            } else
            if(delta1 < 0.0D && d3 > d4)
                d3 = d4;
            d4 = -old2 / delta2;
            if(delta2 > 0.0D)
            {
                if(d2 < d4)
                    d2 = d4;
            } else
            if(delta2 < 0.0D && d3 > d4)
                d3 = d4;
            ad[0] = d2;
            ad[1] = d3;
        }
        return ad;
    } // domaine(int)
 
    public void regleParametre(int i, double d) throws IllegalArgumentException
    {
        switch(i)
        {
        case 0: // '\0'
            v1 = d;
            break;
 
        case 1: // '\001'
            v2 = d;
            break;
 
        case 2: // '\002'
            v1 = old1 + d * delta1;
            v2 = old2 + d * delta2;
            break;
        }
        v3 = 1.0D - (v1 + v2);
    } // regleParametre(int,double)
 
    public double parametre(int i) throws IllegalArgumentException
    {
        switch(i)
        {
        case 0: // '\0'
            return v1;
 
        case 1: // '\001'
            return v2;
 
        case 2: // '\002'
            if(delta1 == 0.0D)
            {
                if(delta2 == 0.0D)
                    return 1.0D;
                else
                    return (v2 - old2) / delta2;
            } else
            {
                return (v1 - old1) / delta1;
            }
        }
        return 0.0D;
    } // parametre(int)
 
    public void printDescriptif(Writer writer, int i) throws IllegalArgumentException, IOException  {}
 
    public void setReglage()   {}
 
    public void unsetReglage() {}
 
    public void update(Observable observable, Object obj)
    {
        if(observable.equals(dessin1.temoin))
        {
            delta1 = v1 - old1;
            dessin2.setAuto(1.0D);
            dessin3.setAuto(1.0D);
        } else
        if(observable.equals(dessin2.temoin))
        {
            delta2 = v2 - old2;
            dessin1.setAuto(1.0D);
            dessin3.setAuto(1.0D);
        } else
        {
            dessin1.setAuto(1.0D);
            dessin2.setAuto(1.0D);
        }
    } // update(Observable,Object)
 
    /*********************
    * The variables part *
    *********************/
    
    protected JPanel pane;
    protected JPanel dessins;
    protected CourbeFonction dessin1;
    protected CourbeFonction dessin2;
    protected CourbeFonction dessin3;
    protected JPanel boutons;
    protected JButton bNouvelleFonction;
    protected JButton bNouveauCycle;
    protected double coeffs[];
    protected double v1;
    protected double v2;
    protected double v3;
    protected double old1;
    protected double old2;
    protected double delta1;
    protected double delta2;
} // class Relaxation