/*
 * waveapplet.java
 *
 * Created on 21. März 2008, 12:55
 */
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import java.awt.Graphics2D;
import java.awt.geom.*;
import java.text.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import java.awt.image.BufferedImage;



/**
 *
 * @author  poj
 */
public class waveapplet extends javax.swing.JApplet
     implements ActionListener {
     DecimalFormat df, df1;
    Timer timer;
    Thread calculatorThread;
    Graphics2D gb;
    BufferedImage image;
    int count, iloop, iter, i, j, k, n, color;
    double x, y, z, x1, x2, y3, y2, dumax, ddu, csmax, facx, fact, kdeltax, sum, sum2;
    double[] amp;
    double[] velo;
    double[] oldsd;
    double[] cp;
    double[] cm;
    double[] omegak;
    double[] u;
    int NMAX = 200;
    int NITER = 10000;
    double deltax = 0.1;  /* m */

    double DELTAXSQ = 0.01;
    double vel = 1.0;
    double deltat = 0.1;  /* s */

    double TP = 0.1;
    double TP0 = 0.1;
    double cutoff = 0.4;
    double phase = 0.0;
    double refr = 1.0;
    double refr0 = 1.0;
    boolean nonlinear = false;
    int pulsetype = 0;
    int disptype = 0;
    int anispeed = 1;
    
    public void actionPerformed(ActionEvent e) {
        int iw;
        //for(iw=0;iw<anispeed;iw++)waves();
        k += (anispeed - 1);
        waves();
        //draw();
        timer.setInitialDelay(1);
        timer.setDelay(1);
        timer.restart();

    }

    /** Initializes the applet waveapplet */
    public void init() {
        try {
            java.awt.EventQueue.invokeAndWait(new Runnable() {
                public void run() {
                    initComponents();
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        
        df = new DecimalFormat("00.000E0");
        df1 = new DecimalFormat("0.000");

        amp = new double[NMAX];
        velo = new double[NMAX];
        cp = new double[NMAX];
        cm = new double[NMAX];
        omegak = new double[NMAX];
        u = new double[NMAX];

        image =
        new BufferedImage(550, 650, BufferedImage.TYPE_INT_RGB);
        gb = (Graphics2D) image.createGraphics();
        gb.setBackground(Color.white);
        gb.clearRect(0, 0, 550, 650);




        velSlider.setValue((int) (vel * 100));
        velLabel.setText("velocity=" + df1.format((vel)));

        speedSlider.setValue(1);
        reset_all();
        timer = new Timer(10, this);
        timer.setInitialDelay(10);
        timer.start();
    }
    
    /** This method is called from within the init() method to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jPanel1 = new myPanel();
        jPanel2 = new javax.swing.JPanel();
        jLabel1 = new javax.swing.JLabel();
        velLabel = new javax.swing.JLabel();
        velSlider = new javax.swing.JSlider();
        jComboBox1 = new javax.swing.JComboBox();
        jComboBox2 = new javax.swing.JComboBox();
        speedSlider = new javax.swing.JSlider();
        jButton1 = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();

        jPanel1.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jPanel1.setMaximumSize(new java.awt.Dimension(400, 400));
        jPanel1.setMinimumSize(new java.awt.Dimension(400, 400));
        jPanel1.setPreferredSize(new java.awt.Dimension(400, 400));

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 398, Short.MAX_VALUE)
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );

        jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        jLabel1.setText("jLabel1");

        velLabel.setText("jLabel2");

        velSlider.setMaximum(200);
        velSlider.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                velSliderMouseDragged(evt);
            }
        });

        jComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "triangular pulse", "Gaussian pulse", "standing wave", "wave packet", "plucked string" }));
        jComboBox1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jComboBox1ActionPerformed(evt);
            }
        });

        jComboBox2.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "dispersion on", "dispersion off" }));
        jComboBox2.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jComboBox2ActionPerformed(evt);
            }
        });

        speedSlider.setMajorTickSpacing(1);
        speedSlider.setMaximum(10);
        speedSlider.setPaintTicks(true);
        speedSlider.setSnapToTicks(true);
        speedSlider.addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
            public void mouseDragged(java.awt.event.MouseEvent evt) {
                speedSliderMouseDragged(evt);
            }
        });

        jButton1.setText("Restart");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jLabel2.setText("animation speed");

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGap(66, 66, 66)
                        .addComponent(jLabel1))
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGap(50, 50, 50)
                        .addComponent(jButton1))
                    .addGroup(jPanel2Layout.createSequentialGroup()
                        .addGap(24, 24, 24)
                        .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(speedSlider, javax.swing.GroupLayout.PREFERRED_SIZE, 144, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                .addComponent(velSlider, javax.swing.GroupLayout.PREFERRED_SIZE, 138, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addComponent(velLabel)
                                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                    .addComponent(jComboBox2, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                    .addComponent(jComboBox1, javax.swing.GroupLayout.Alignment.LEADING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))))
                .addContainerGap(18, Short.MAX_VALUE))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup()
                .addGap(0, 0, Short.MAX_VALUE)
                .addComponent(jLabel2)
                .addGap(39, 39, 39))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(velLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(velSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(38, 38, 38)
                .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(44, 44, 44)
                .addComponent(jComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(36, 36, 36)
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(speedSlider, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jButton1)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel1)
                .addGap(22, 22, 22))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(207, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                    .addComponent(jPanel2, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 402, Short.MAX_VALUE))
                .addContainerGap(133, Short.MAX_VALUE))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void velSliderMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_velSliderMouseDragged

         vel = velSlider.getValue() * 0.01;

        velLabel.setText("velocity=" + df1.format((vel)));// TODO add your handling code here:
    }//GEN-LAST:event_velSliderMouseDragged

    private void speedSliderMouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_speedSliderMouseDragged

         anispeed = speedSlider.getValue();// TODO add your handling code here:
    }//GEN-LAST:event_speedSliderMouseDragged

    private void jComboBox1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBox1ActionPerformed

        pulsetype = jComboBox1.getSelectedIndex();
        reset_all();// TODO add your handling code here:
    }//GEN-LAST:event_jComboBox1ActionPerformed

    private void jComboBox2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jComboBox2ActionPerformed
       
        disptype= jComboBox2.getSelectedIndex();// TODO add your handling code here:
    }//GEN-LAST:event_jComboBox2ActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        
        reset_all();// TODO add your handling code here:
    }//GEN-LAST:event_jButton1ActionPerformed
    
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton jButton1;
    private javax.swing.JComboBox jComboBox1;
    private javax.swing.JComboBox jComboBox2;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JSlider speedSlider;
    private javax.swing.JLabel velLabel;
    private javax.swing.JSlider velSlider;
    // End of variables declaration//GEN-END:variables
    

void reset_all() {
        int i;

        for (i = 0; i < NMAX; i++) {
            amp[i] = 0.0;
            velo[i] = 0.0;

        }
        k = 0;
        if (pulsetype == 0) {
            pulse();
        }
        if (pulsetype == 2) {
            standing_wave();
        }
        if (pulsetype == 3) {
            wave_packet();
        }
        if (pulsetype == 4) {
            plucked();
        }

        if (pulsetype == 1) {
            pulse2();
        }

        fourier();


    }

    void pulse() {
        int i;

        for (i = 0; i < NMAX; i++) {
            amp[i] = 0.0;
            velo[i] = 0.0;
        }
        for (i = NMAX / 2 - 15; i < NMAX / 2; i++) {
            velo[i] = -vel;
        }
        for (i = NMAX / 2; i < NMAX / 2 + 15; i++) {
            velo[i] = vel;
        }

        for (i = NMAX / 2 - 15; i < NMAX / 2; i++) {
            amp[i] = (i - NMAX / 2 + 15) * deltat;
        }
        for (i = NMAX / 2; i < NMAX / 2 + 15; i++) {
            amp[i] = -(i - NMAX / 2 - 15) * deltat;
        }



    }

    void pulse2() {
        int i;
        double x;
        for (i = 0; i < NMAX; i++) {
            x = (i - NMAX / 2) / 10.0;
            amp[i] = Math.exp(-x * x);

            velo[i] = -vel * amp[i] * 4 * x / (deltat * 20.0);

        }
    }

    void standing_wave() {
        int i;
        for (i = 0; i < NMAX; i++) {
            amp[i] = 0.0;
            velo[i] = 0.0;
        }
        /* standing wave*/

        for (i = 0; i < NMAX; i++) {
            velo[i] = Math.sin(20 * (i + 1) * Math.PI / (NMAX + 1));
        }

    }

    void wave_packet() {
        int i;
        for (i = 0; i < NMAX; i++) {
            amp[i] = 0.0;
            velo[i] = 0.0;
        }
        /* wave packet */
        for (i = 0; i < NMAX; i++) {
            amp[i] = Math.exp(-(i - NMAX / 2) * (i - NMAX / 2) * 0.01) * Math.sin(i * Math.PI * 0.3);
        }

    }

    void plucked() {

        int i;
        for (i = 0; i < NMAX; i++) {
            amp[i] = 0.0;
            velo[i] = 0.0;
        }
        velo[NMAX / 2] = 10.0;

    }

    void fourier() {
        int i;

        /* Fourier-transformation */
        for (i = 0; i < NMAX; i++) {
            kdeltax = (i + 1) * Math.PI / (NMAX + 1);



            /* with dispersion */
            if (disptype == 0) {
                omegak[i] = 2.0 * vel * Math.sin(kdeltax / 2.0) / deltax;
            } /* without */ else {
                omegak[i] = vel * kdeltax / deltax;
            }

            sum = 0.0;
            sum2 = 0.0;
            for (j = 0; j < NMAX; j++) {
                sum = sum + amp[j] * Math.sin((j + 1) * kdeltax);
                sum2 = sum2 + velo[j] * Math.sin((j + 1) * kdeltax);
            }
            cp[i] = 2 * sum / NMAX;
            cm[i] = 2 * sum2 / (NMAX * omegak[i]);

        }



    }

    void waves() {
        Graphics g = jPanel1.getGraphics();

        Graphics2D g2 = (Graphics2D) g;
        int y2, y3, i, j;



        {

            for (i = 0; i < NMAX; i++) {
                sum = 0.0;
                for (j = 0; j < NMAX; j++) {
                    sum2 = cp[j] * Math.cos(k * deltat * omegak[j]) + cm[j] * Math.sin(k * deltat * omegak[j]);
                    sum = sum + sum2 * Math.sin((i + 1) * (j + 1) * Math.PI / (NMAX + 1));
                }

                u[i] = sum;
            /* printf(" %i  %f  \n",i,u[0][i]); */
            }

            gb.setColor(Color.white);
            gb.clearRect(0, 0, 550, 600);

            gb.setColor(Color.red);

            for (i = 0; i < NMAX - 1; i++) {
                y3 = (int) (200 - u[i] * 100);
                y2 = (int) (200 - u[i + 1] * 100);
                gb.drawLine(2 * i, y3, 2 * i + 2, y2);
            }


        }

        g2.drawImage(image, 0, 0, null);
        k++;
        jLabel1.setText("" + k);
    }

    void draw() {
        Graphics g = jPanel1.getGraphics();

        Graphics2D g2 = (Graphics2D) g;

        //jLabel1.setText("time=" + df1.format(time_now));







        g2.drawImage(image, 0, 0, null);

    }

    public class myPanel extends javax.swing.JPanel {

        int iy0, iy1, ix0, ix1;
        double tscale;

        public void paint(Graphics g) {
            int ix, iy, ir, ix5, ix10, ix15, ix20, ix25, k, i, j;
            double xp, yp;
            Graphics2D g2 = (Graphics2D) g;
            int size = 200;

            //if(count==0) {super.paintComponent(g);

            //}

            super.paintComponent(g);


            g2.drawImage(image, 0, 0, null);



        }
    }
}





