package optimizacija;

import java.awt.Color;
import java.awt.Graphics;
import java.util.Random;

public class Spin extends OptimizacijskiProblem {
	private int mreza[][];
	private Random rng;
	private boolean konec;
	
	public Spin(int n) {
		rng = new Random();
		konec = false;
		nakljucnoStanje(n);
	}
	
	@Override
	public double energija() {
		int e = 0;
		int n = mreza.length;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				int s = mreza[i][j];
				if (i > 0)   e -= s * mreza[i-1][j];
				if (i < n-1) e -= s * mreza[i+1][j];
				if (j > 0)   e -= s * mreza[i][j-1];
				if (j < n-1) e -= s * mreza[i][j+1];
			}
		}
		return e;
	}

	public double razlikaEnergije(int i, int j) {
		int n = mreza.length;
		int s = 0;
		if (i > 0) s += mreza[i-1][j];
		if (i < n-1) s += mreza[i+1][j];
		if (j > 0) s += mreza[i][j-1];
		if (j < n-1) s += mreza[i][j+1];
		return 2 * mreza[i][j] * s;
	}
		
	@Override
	public String ime() {
		return "Spinska mreža";
	}

	@Override
	public boolean konec() {
		return konec;
	}

	private int nakljucniSpin() {
		return (rng.nextBoolean() ? 1 : -1);
	}

	@Override
	public void nakljucnoStanje(int n) {
		konec = false;	
		mreza = new int[n][n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				mreza[i][j] = nakljucniSpin();
			}
		}
	}

	@Override
	public void narisi(double razmerje, Graphics g) {
		int n = mreza.length;
		int d = Math.max(1, (int)(razmerje/n));
		if (n > 0) {
			for (int i = 0; i < n; i++) {
				for (int j = 0; j < n; j++) {
					g.setColor(mreza[i][j]>0 ? Color.black : Color.red);
					g.fillRect(d * i, d * j, d, d);	
				}
			}
		}
	}

	@Override
	public void optimiraj() {
		boolean k = true;
		int n = mreza.length;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				if (razlikaEnergije(i, j) < 0) {
					mreza[i][j] = -mreza[i][j];
					k = false;
				}
			}
		}
		konec = k;
	}

	@Override
	public int velikost() {
		return mreza.length;
	}
}
