/*
 * NewJApplet.java
 *
 * Created on February 13, 2008, 6:36 PM
 */

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  root
 */
public class NewJApplet extends JApplet
        implements Runnable,ActionListener {
    DecimalFormat df,df1;
    Timer timer;
    Thread calculatorThread;
     Graphics2D gb;
     BufferedImage image;
     
  int N=       200;
  int MAXITER= 200;
  double J=1.0;
  int NSQ=40000;
  
int [][] Lattice;  
double kT,magav;
int Npoints,magsum,done,number_samples;
char [] message;
char cc;


int i; 
int j; 
int iter; 
int Spin;
double DE;
double r;

double [] Analytical;


int count=0;
int loops=20000;

int ixo=0;
int iyo=0;


    /** Initializes the applet NewJApplet */
    public void init() {
        try {
            java.awt.EventQueue.invokeAndWait(new Runnable() {

                public void run() { int i;
                    initComponents();
                    
                }
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }

     
      
       
        df =new DecimalFormat("00.000E0"); 
        df1 =new DecimalFormat("0.000");
       image =
        new BufferedImage(200, 120, BufferedImage.TYPE_INT_RGB);
        gb = (Graphics2D)image.createGraphics();
        gb.setBackground(Color.white);
        gb.clearRect(0,0,200,120);
        
        Lattice=new int[N][N];
        
        Analytical = new double[100];
        Analytical[0]=1;
        for(i=1;i<100;i++)
        {
        double x=i*0.05;
        if(x>2.27) Analytical[i]=0.0;
        else Analytical[i]=Math.pow((1-Math.pow(Math.sinh(2*J/x),-4)),0.125);
        
        }    
        
        //timer = new Timer(1, this);
        //timer.setInitialDelay(1);
        //timer.start(); 
       
        
        reset_all();
        //jPanel1.repaint();
    }
    
         public void run()
         { int i;
         
          while (Thread.currentThread() == calculatorThread) {
              
             Metropolis();
    
         }
         }
    
        public void start()
        {
            if (calculatorThread == null) {
            calculatorThread = new Thread(this);
            calculatorThread.start();
              }
        }
        
        
        public void stop() {
          calculatorThread = null;
}
        
        
        public void actionPerformed(ActionEvent e) {
           
          if(count>=loops) {return;}
          
         
          //jPanel1.paint(jPanel1.getGraphics());
          timer.setInitialDelay(20);
          timer.setDelay(20);
          timer.restart();
          
      }
        
        public void reset_all()
        {
        i=0;j=0;
        count=0;
        
        kT=2.0;
        jLabel12.setText("kT="+df1.format(kT));
        jSlider1.setValue((int)(kT*40));
        RandomSpin();
        ClearAverage();
        }
        
    /** 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();
        maglab = new javax.swing.JLabel();
        nsamplab = new javax.swing.JLabel();
        averlab = new javax.swing.JLabel();
        jPanel3 = new javax.swing.JPanel();
        jLabel12 = new javax.swing.JLabel();
        jSlider1 = new javax.swing.JSlider();
        jButton1 = new javax.swing.JButton();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        jButton4 = new javax.swing.JButton();

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

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

        jPanel2.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jPanel2.setMaximumSize(new java.awt.Dimension(120, 550));
        jPanel2.setMinimumSize(new java.awt.Dimension(120, 550));
        jPanel2.setPreferredSize(new java.awt.Dimension(120, 550));

        maglab.setText("magn");

        nsamplab.setText("nsampl");

        averlab.setText("Average");

        javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
        jPanel2.setLayout(jPanel2Layout);
        jPanel2Layout.setHorizontalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(averlab)
                    .addComponent(nsamplab)
                    .addComponent(maglab))
                .addContainerGap(100, Short.MAX_VALUE))
        );
        jPanel2Layout.setVerticalGroup(
            jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel2Layout.createSequentialGroup()
                .addGap(71, 71, 71)
                .addComponent(nsamplab)
                .addGap(38, 38, 38)
                .addComponent(maglab)
                .addGap(31, 31, 31)
                .addComponent(averlab)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jPanel3.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
        jPanel3.setMaximumSize(new java.awt.Dimension(32767, 550));
        jPanel3.setMinimumSize(new java.awt.Dimension(0, 550));

        jLabel12.setText("jLabel1");

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

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

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

        jButton3.setText("all up");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });

        jButton4.setText("randomize");
        jButton4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton4ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3);
        jPanel3.setLayout(jPanel3Layout);
        jPanel3Layout.setHorizontalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jButton2, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButton1, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jButton4, javax.swing.GroupLayout.PREFERRED_SIZE, 125, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                        .addGroup(jPanel3Layout.createSequentialGroup()
                            .addGap(53, 53, 53)
                            .addComponent(jLabel12))
                        .addGroup(jPanel3Layout.createSequentialGroup()
                            .addContainerGap()
                            .addComponent(jSlider1, javax.swing.GroupLayout.DEFAULT_SIZE, 125, Short.MAX_VALUE))
                        .addGroup(jPanel3Layout.createSequentialGroup()
                            .addContainerGap()
                            .addComponent(jButton3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
                .addContainerGap(24, Short.MAX_VALUE))
        );
        jPanel3Layout.setVerticalGroup(
            jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel3Layout.createSequentialGroup()
                .addGap(31, 31, 31)
                .addComponent(jLabel12)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jSlider1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jButton3)
                .addGap(18, 18, 18)
                .addComponent(jButton4)
                .addGap(40, 40, 40)
                .addComponent(jButton1)
                .addGap(81, 81, 81)
                .addComponent(jButton2)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        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, 256, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, 164, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(501, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, 446, Short.MAX_VALUE)
                    .addComponent(jPanel2, 0, 446, Short.MAX_VALUE)
                    .addComponent(jPanel1, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.PREFERRED_SIZE, 446, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(329, 329, 329))
        );
    }// </editor-fold>//GEN-END:initComponents

    private void jSlider1MouseDragged(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_jSlider1MouseDragged
        
        kT=jSlider1.getValue()*0.025;
        jLabel12.setText("kT="+df1.format(kT));
        //ClearAverage();
        //jPanel1.repaint();// TODO add your handling code here:
    }//GEN-LAST:event_jSlider1MouseDragged

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        ClearAverage();// TODO add your handling code here:
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
        reset_all();
        jPanel1.repaint();// TODO add your handling code here:
    }//GEN-LAST:event_jButton2ActionPerformed

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
        stop();
        AllUp();// TODO add your handling code here:
        start();
    }//GEN-LAST:event_jButton3ActionPerformed

    private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed
        RandomSpin();// TODO add your handling code here:
    }//GEN-LAST:event_jButton4ActionPerformed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JLabel averlab;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JSlider jSlider1;
    private javax.swing.JLabel maglab;
    private javax.swing.JLabel nsamplab;
    // End of variables declaration//GEN-END:variables
    
   
   
void AllUp ()
{
 int i,j;
 Graphics g=jPanel1.getGraphics();
 
  for (i = 0; i < N; i++)
    for (j = 0; j < N; j++) 
     { Lattice[i][j] = 1;
       g.setColor(Color.red);
             
             g.drawLine(i+2,j+2,i+2,j+2);
    }
       

}



void RandomSpin ()
{ double r; int i,j;
  Graphics g=jPanel1.getGraphics();
 
  for (i=0;i<N;i++) for (j=0;j<N;j++)
    { r=Math.random();
    if (r<0.5) 
      {Lattice[i][j]=-1;}
    else {Lattice[i][j]=1;}
    if(Lattice[i][j]>0) g.setColor(Color.red);
             else g.setColor(Color.black);
             g.drawLine(i+2,j+2,i+2,j+2);
    }
}

double Energy (int i, int j, int Spin)
{
  int left, right, top, bottom;
  
  // periodic b.c.
  
  left = (j == 0 ? (N - 1) : (j - 1));
  right = (j == (N - 1) ? 0 : (j + 1));
  top = (i == 0 ? (N - 1) : (i - 1));
  bottom = (i == (N - 1) ? 0 : (i + 1));

  return - 2.0 * J * Spin * (Lattice[i][left] + Lattice[i][right]+
			     Lattice[top][j] + Lattice[bottom][j]);
}

void Metropolis()

  { Graphics g; int i,j,ix,iy,il;
    g=jPanel1.getGraphics();
     Graphics2D g2 = (Graphics2D)g;
    
       
       
       
       for(i=0;i<N;i++)for(j=0;j<N;j++)
       { 
       
       
                     
 
   
      {
	Spin = Lattice[i][j] < 1 ? 1 : -1; 
	// calculate energy change
	DE = Energy (i, j, Spin); 
	// if DE < 0 then flip spin  
	if (DE < 0) 
	  { Lattice[i][j] = Spin; 
             if(Spin>0) g.setColor(Color.red);
             else g.setColor(Color.black); 
        
       //g.fillRect(i+2,j+2,1,1);
          g.drawLine(i+2,j+2,i+2,j+2);
            
            }
	else {
	  // use BoltzmaNn factor to decide
	  r = Math.random();
	  if (Math.exp(- DE/kT) > r)
          { Lattice[i][j] = Spin;
            if(Spin>0) g.setColor(Color.red);
             else g.setColor(Color.black);
             g.drawLine(i+2,j+2,i+2,j+2);
            }
            
	} /* else */
        
      
        
      } 

  }
    
  

  number_samples++;
        magsum=0;
  for (i=0;i<N;i++)for(j=0;j<N;j++) magsum=magsum+Lattice[i][j];
  magav=magav+(double)magsum;
  

  nsamplab.setText("samples="+number_samples);
  averlab.setText("average="+df1.format(magav/number_samples));

 
  maglab.setText("M="+df1.format(magsum));
  
       
  gb.clearRect(0,0,200,120);
  gb.setColor(Color.red);
  ix=(int) (kT*40)+2; iy=110-(int) (100.0*Math.abs(magav)/(N*N*number_samples));
  gb.drawOval(ix-5, iy-5, 10,10); 
  gb.setColor(Color.black);
  for(ix=1;ix<100;ix++)
  gb.drawLine(2*(ix-1),110-(int)(100*Analytical[ix-1]),2*ix,110-(int)(100*Analytical[ix]));
  
  
  
  
   g2.drawImage(image, 0, 250, null);
  }

void ClearAverage()

{ magav=0.0; number_samples=0;}



    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);
        
          stop();
           for(i=0;i<N;i++)for (j=0;j<N;j++)
           {
            if(Lattice[i][j]>0) g.setColor(Color.red);
             else g.setColor(Color.black); 
        
       
          g.drawLine(i+2,j+2,i+2,j+2);
           
           }
        
      
       
            g2.drawImage(image, 0, 250, null);
            
            g2.setColor(Color.black);
            g2.drawString("kT",180,380);
            g2.drawString("average magnetisation",0,240);
         start();
          
        }
    }
}
     
     
     
