package model;

import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Stack;

import location.Location;
import state.SegState;
import cell.Cell;
import cell.SegCell;
import grid.SquareGrid;
import gui.CellSocietyGUI;

public class SegModel extends Model {
	
	private double mySimilarity = 0.5;
	private Map<Location,Cell> myCells;

	public SegModel(int rows, int columns, CellSocietyGUI CSGUI) {
		super(rows, columns, CSGUI);
		myCells = new HashMap<>();
	}
	
	@Override
	public void setParameters(Map<String,String> map){
		super.setParameters(map);
		if(map.containsKey("PERCENT_SIMILAR"))
			mySimilarity = Double.parseDouble(map.get("PERCENT_SIMILAR"));
	}

	@Override
	public void buildGrid(List<Map<String, String>> cells, CellSocietyGUI CSGUI) {
		myCells.clear();
		cells.forEach(map -> {
			int x = Integer.parseInt(map.get("x"));
			int y = Integer.parseInt(map.get("y"));
			int state = Integer.parseInt(map.get("state"));
			SegCell cell = new SegCell(new SegState(state), new Location(x, y, getWidth(), getHeight()), CSGUI);
			cell.setSimilarity(mySimilarity);
			myCells.put(cell.getLocation(), cell);
		});
		if (myCells.size() < getWidth() * getHeight())
			System.err.println("Missing Cell Info!");
		SquareGrid grid = new SquareGrid(getWidth(), getHeight(), myCells);
		grid.setNeighbors();
		setMyGrid(grid);
	}
	
	@Override
	public void step(){
		Stack<Cell> dissatisfiedList = getDissatisfiedCells();
		Stack<Cell> vacentList = getVacentCells();
		Collections.shuffle(vacentList);
		while(!dissatisfiedList.isEmpty() && !vacentList.isEmpty()){
			SegCell dissatisfiedCell = (SegCell)dissatisfiedList.pop();
			SegCell vacentCell = (SegCell)vacentList.pop();
			vacentCell.determineNextState(dissatisfiedCell.getState());
			dissatisfiedCell.determineNextState(vacentCell.getState());
		}
		myCells.forEach((loc,cell)->{cell.goToNextState();});
	}
	
	private Stack<Cell> getDissatisfiedCells(){
		Stack<Cell> list = new Stack<>();
		myCells.forEach((loc,cell)->{
			if(!((SegCell)cell).isEmpty() && !((SegCell)cell).isSatisfied())
				list.add(cell);
		});
		return list;
	}
	
	private Stack<Cell> getVacentCells(){
		Stack<Cell> list = new Stack<>();
		myCells.forEach((loc,cell)->{
			if(((SegCell)cell).isEmpty())
				list.add(cell);
		});
		return list;
	}

}

@@ -1438,28 +1438,24 @@
 k%3CCell%3E 
-dissatisfied
+exchange
 List = g
@@ -1483,33 +1483,28 @@
 ;%0A%09%09
-Stack%3CCell%3E vacentList = 
+exchangeList.addAll(
 getV
@@ -1511,24 +1511,25 @@
 acentCells()
+)
 ;%0A%09%09Collecti
@@ -1544,29 +1544,34 @@
 fle(
-vacent
+exchange
 List);%0A
+%09%09%0A
 %09%09while(
 !dis
@@ -1570,60 +1570,30 @@
 ile(
-!dissatisfiedList.isEmpty() && !vacentList.isEmpty()
+exchangeList.size()%3E=2
 )%7B%0A%09
@@ -1602,32 +1602,21 @@
 SegCell 
-dissatisfiedC
+c
 ell
+1
  = (SegC
@@ -1619,28 +1619,24 @@
 SegCell)
-dissatisfied
+exchange
 List.pop
@@ -1650,26 +1650,21 @@
 SegCell 
-vacentC
+c
 ell
+2
  = (SegC
@@ -1667,22 +1667,24 @@
 SegCell)
-vacent
+exchange
 List.pop
@@ -1690,26 +1690,21 @@
 p();%0A%09%09%09
-vacentC
+c
 ell
+2
 .determi
@@ -1715,32 +1715,21 @@
 xtState(
-dissatisfiedC
+c
 ell
+1
 .getStat
@@ -1741,24 +1741,13 @@
 %0A%09%09%09
-dissatisfiedC
+c
 ell
+1
 .det
@@ -1766,18 +1766,13 @@
 ate(
-vacentC
+c
 ell
+2
 .get

Change algorithm for SegModel