/**
 *
 * PrimeGen.java
 * 
 *
 */

import de.tubs.cs.sc.casim.State;
import de.tubs.cs.sc.casim.Cell;
import de.tubs.cs.sc.casim.Lattice;
import java.awt.Color;
import java.awt.Font;


/**
 * PrimeGen
 */
public class PrimeGen extends State {
    /**
     * (1) add state variables here
     * i.e. int condition;
     */
    private int redL;
    private int redR;
    private int blueL;
    private int blueR;
    private int greenL;
    private int greenR;
    private int collisionR;
    private int collisionL;
    private boolean partition;
    private boolean leftBorder;
    private boolean rightBorder;
    public static ResultFrame resultFrame = new ResultFrame("Ergebnis");
    public static int[] conditionCounter = new int[100];
    private int sum;
    private static int counter = 0;
   
	
    /**
     * (2) add initialization of state variables here
     */
    public void PrimeGen() {
	sum = 0;
	redL = 0;
	redR = 0;
	blueL = 0;
	blueR = 0;
	greenL = 0;
	greenR = 0;
	partition = false;
	leftBorder = false;
	rightBorder = false;
	collisionR = 0;
	collisionL = 0;
	

    }
    /**
     * (3) add lattice initialization here
     * access is (StateClass)l.getState(...)
     */
    public static void initialize(Lattice l, int option) {
	((PrimeGen)l.getState(0)).redR = 1;
	((PrimeGen)l.getState(0)).blueR = 1;
	((PrimeGen)l.getState(0)).leftBorder = true;
	((PrimeGen)l.getState(l.getX() - 1)).rightBorder = true;
	counter = 0;
	int width = l.getX();
	int k = 1;
	while(k*(k+1)/2 < width) { k++; }
	resultFrame.reset("**Achtung**\nBreite des Arrays: " + width + ".\n" + "Bei dieser Größe" 
			  + " kann für die Richtigkeit der gefundenen Primzahlen nur bis zur Zahl "
			  + (k*k -1 ) + " garantiert werden.\n" );
	resultFrame.resize(230, 350);
	resultFrame.show();
	
	for(int i=0; i<conditionCounter.length; i++) {
	    conditionCounter[i] = 0;
	}
	resultFrame.setCounter(0);
	

    }
    /**
     * (4) add drawing color definition here
     * an array of Color's is recommended
     * returning null means the cell will not be drawn
     */
    public Color getColor() {
	if(collisionR != 0) { return Color.yellow; }
	if(collisionL != 0) { return Color.pink; }
	if(greenR != 0 || greenL != 0) {
	    return Color.green;
	}
	
	if(redR != 0 || redL != 0) {
	    return Color.red;
	}
	
	if(blueR != 0 || blueL != 0) {
	    return Color.blue;
	}
             
	
	if(partition) { return Color.gray; }
	
	
	return null;
    }
    /**
     * (5) add state variables copy code here
     * do a field to field copy from s to this
     */ 
    public void copy(State s) {
	PrimeGen source = (PrimeGen)s;
	redR = source.redR;
	redL = source.redL;
	blueR = source.blueR;
	blueL = source.blueL;
	greenR = source.greenR;
	greenL = source.greenL;
	partition = source.partition;
	leftBorder = source.leftBorder;
	rightBorder = source.rightBorder;
	collisionR = source.collisionR;
	collisionL = source.collisionL;
    }
    public int getCode() {
	sum = 0;
	switch(redL) {
	case 1: sum += 1;
	case 2: sum += 2;
	case 3: sum += 4;
	}
	switch(redR) {
	case 1: sum += 8;
	case 2: sum += 16;
	case 3: sum += 32;
	}
	switch(blueL) {
	case 1: sum += 64;
	case 2: sum += 128;
	}
	switch(blueR) {
	case 1: sum += 256;
	}
	switch(greenL) {
	case 1: sum += 512;
	}
	switch(greenR) {
	case 1: sum += 1024;
	case 2: sum += 2048;
	}
	if(partition) { sum += 4096; }
	switch(collisionL) {
	case 1: sum += 8192;
	}
	switch(collisionR) {
	case 1: sum += 16384;
	}

	return sum;
    }
    /**
     * (6) add transion function code here
     * evaluating the new state of the cell
     * use i.e. cell.getNeighbors to get the neighborhood set
     */
    public void  transition(Cell cell) {
	State nb[] = cell.getNeighbors();
	int x;	
	boolean found = false;
	if(!rightBorder && !leftBorder) { 
	    x = getCode();
	} else {
	    x = 0;
	}
	int i = 0;
	if( x != 0 ) {
	    while(conditionCounter[i] != 0) {
		if(x == conditionCounter[i]) {
		    found = true;
		}
		i++;
	    }
	    
	    if(!found) {
		conditionCounter[i] = x;
		resultFrame.setCounter(i+1);
	    }
	    
	}

	
	if(leftBorder) { 
	    counter++; 
	    if(counter % 3 == 0 && ((PrimeGen)nb[2]).redL != 1 && counter != 3 ) {
		resultFrame.setResult( ""+ (counter/3) );
	
	    }
	}
	
	if(collisionR != 0) { collisionR--; }
	if(collisionL != 0) { collisionL--; }
	if(redR != 0) { redR--;	}
	if(redL != 0) { redL--;	}
	if(blueR != 0) { blueR--; }
	if(blueL != 0) { blueL--; }
	if(greenR != 0) { greenR--; }
	if(greenL != 0) { greenL--; }
	
	
	if( partition && ((PrimeGen)nb[2]).greenL == 1) {
	    redL = 3;
	}
	
	if( ((PrimeGen)nb[1]).greenR == 1 ) {
	    if(greenR != 0) { collisionR = 1; }
	    greenR = 2;
	}
	if( ((PrimeGen)nb[2]).greenL == 1) {
	   
	    greenL = 1;
	}
	if( ((PrimeGen)nb[1]).redR == 1 ) {
	    redR = 3;
	}
	if( ((PrimeGen)nb[2]).redL == 1) {
	    redL = 3;
	}
	if( ((PrimeGen)nb[1]).blueR == 1 ) {
	    blueR = 1;
	}
	
	if(  partition && ((PrimeGen)nb[1]).greenR == 1) {
	    greenR = 0;
	    greenL = 1;
	}
	
	
	if( partition && ((PrimeGen)nb[2]).greenL == 1 ) {
	    if( ((PrimeGen)nb[1]).greenR == 1 ) { collisionL = 1; } 
	    greenL = 0;
	    greenR = 2;
	}
	
	    
	if( partition && ((PrimeGen)nb[2]).blueL == 1) {
	    redL = 3;
	    greenR = 2;
	}
	
	if( leftBorder && redL == 2 ) {
	    redL = 0;
	}

	if( ((PrimeGen)nb[1]).collisionR == 1 ) {
	    greenR = 2;
	}
	if( ((PrimeGen)nb[2]).collisionL == 1 ) {
	    greenL = 1;
	}

	if( ((PrimeGen)nb[1]).blueR == 1 && ((PrimeGen)nb[1]).redR == 1 ) {
	    blueR = 0;
	    blueL = 2;
	    redR = 2;
	    partition = true;
	}
	if( ((PrimeGen)nb[2]).blueL == 1 && !rightBorder ) {
	    blueL = 1;
	}
	if( ((PrimeGen)nb[1]).blueL == 1 && ((PrimeGen)nb[1]).leftBorder ) {
	    blueR = 1;
	}
	if( partition && ((PrimeGen)nb[2]).blueL == 1 ) {
	    blueL = 0;
	    blueR = 1;
	}
	
	
	if( rightBorder ) {
	    blueR = 0;
	    redR = 0;
	    redL = 0;
	}
	
    }
    /**
     * (7) add code for definition of constant states here
     * if the state class is used in lattices with constant boundary
     * conditions, it should return the constant state
     */
    public State getConstant() {

	return null;
    }
    
    
}

