package edu.unl.consystlab.sudokuSolver;
import edu.unl.consystlab.sudokuSolver.constructorInterface;
import java.awt.*;
import java.util.List;
import java.util.*;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;

import edu.unl.consystlab.sudokuSolver.variableIndexAndValueGrouping;

import edu.unl.consystlab.sudokuSolver.assignSingletons;
import edu.unl.consystlab.sudokuSolver.problemVariable;
import edu.unl.consystlab.sudokuSolver.user_action;
import edu.unl.consystlab.sudokuSolver.consistencyAlgorithms.consistencyAlgorithm;


public class solBoard extends Container {

	private Image offscreen;
	
	constraintProblem parentProblem;
	sudokuInterface parentInterface;
	
	private final int UNIT_BORDER_WIDTH = 3;
	
	private int boardWidth;
	private int boardHeight;
	private int unitsWide;
	private int unitsHigh;
	private int cellWidth;
	private int cellHeight;
	private int numCols;
	private int numLines;
	private boolean isError;
	private String boardErrors;
	private solCell[] solCells;	
		
	
	//constructor pass the variable corresponding to this cell here
	public solBoard(String[][] mySolution, constraintProblem myProblem, sudokuInterface myInterface)
	{		
		isError = false;
		boardErrors = "";
		parentProblem = myProblem;
		parentInterface = myInterface;
		
		if(mySolution == null)
		{
			isError = true;
			boardErrors = boardErrors + "The solutions was not loaded correctly.\n";
		}
		numCols = parentProblem.totalColumns;  //these two should always be equal
		numLines = parentProblem.totalLines;
		
		if(numCols != numLines)
		{
			isError = true;
			boardErrors = boardErrors + "The number of columns and lines should be equal.\n";
		}
		if(numCols > 16)
		{
			isError = true;
			boardErrors = boardErrors + "The number of columns and lines should be less than 16.\n";
		}
		
		if(!isError)
		{
			unitsWide = (int)(numCols/parentProblem.columnsPerUnit);
			unitsHigh = (int)(numLines/parentProblem.linesPerUnit);
	
			//probably need an algorithm to assign these dynamically.
			boardWidth = 180;
			boardHeight = 180;
			
			//add room to draw the lines between the units.
			boardHeight += UNIT_BORDER_WIDTH * (unitsHigh - 1);			
			boardWidth += UNIT_BORDER_WIDTH * (unitsWide - 1);
			
			this.setSize(boardWidth,boardHeight);
			
			//TODO: need an algorithm to assign these dynamically.
			cellWidth = cellHeight = 20;
			
			solCells = new solCell[81];
			int tempCellNum =0;
			for(int lineIndex=0; lineIndex <9; lineIndex++)
			{
				for(int colIndex=0; colIndex<9; colIndex++)
				{
					//problemVariable tempVar = parentProblem.getVariable((lineIndex+1)+","+(colIndex+1));
					//String assignNum, int newCellWidth, int newCellHeight, solBoard newBoard
					System.out.println("mySolution[lineIndex][colIndex]");
					System.out.println(mySolution[lineIndex+1][colIndex+1]);
					solCells[tempCellNum] = new solCell(mySolution[lineIndex+1][colIndex+1], cellWidth, cellHeight, this);
					solCells[tempCellNum].setLocation( ((colIndex*cellHeight)+(int)Math.floor(colIndex/unitsWide)*UNIT_BORDER_WIDTH)
							,((lineIndex*cellWidth)+(int)Math.floor(lineIndex/unitsHigh)*UNIT_BORDER_WIDTH) );
					solCells[tempCellNum].setSize(cellWidth,cellHeight);
					//problemCells[tempCellNum].addActionListener(this);
					this.add(solCells[tempCellNum]);					
					tempCellNum++;
				}
			}
		}
	}
	
	public int getCellWidth()
	{
		return cellWidth;
	}
	public int getCellHeight()
	{
		return cellHeight;
	}
	public int getUnitBorderWidth()
	{
		return UNIT_BORDER_WIDTH;
	}
	
	public void update(Graphics g)
	{
		Graphics bufferGraphics;

		offscreen = createImage(this.getWidth(), this.getHeight());
		bufferGraphics = offscreen.getGraphics();
//		bufferGraphics.setColor(getBackground());
//		bufferGraphics.fillRect(0,0,this.getWidth(), this.getHeight());
//		bufferGraphics.setColor(getForeground());
		for(int i=0; i <= 80; i++)
		{
			bufferGraphics.translate(solCells[i].getX(), solCells[i].getY());
			solCells[i].paint(bufferGraphics);
			//problemCells[i].setBackgroundColor(Color.RED);
			bufferGraphics.translate(-solCells[i].getX(), -solCells[i].getY());
		}		
		//bufferGraphics.setClip(0,0,this.getWidth(), this.getHeight());

		//super.paint(bufferGraphics);
		
		if(!isError)
		{
			Graphics2D g2 = (Graphics2D)bufferGraphics;
//			Graphics2D g2 = (Graphics2D)g;
			
			//make the line thicker
			//g2.setStroke(new BasicStroke(3.3f));
			g2.setColor(Color.BLACK);
			
			//draw the unit separating "lines" which are actually
			//filled rectangles.
			
			//do the horizontal lines first
			for(int lineIndex = 1; lineIndex < unitsWide; lineIndex++)
			{
				g2.fillRect(  0, ( lineIndex*(cellHeight*(int)(numLines)/(unitsHigh)) + ((lineIndex-1)*UNIT_BORDER_WIDTH) )
						, boardWidth, UNIT_BORDER_WIDTH  );
			}
			
			//now the veritical lines
			for(int colIndex = 1; colIndex < unitsHigh; colIndex++)
			{
				g2.fillRect( ( colIndex*(cellWidth*(int)(numCols)/(unitsWide)) + ((colIndex-1)*UNIT_BORDER_WIDTH) ), 0
						, UNIT_BORDER_WIDTH, boardHeight  );				
			}			
		}
		else
		{
			Label errorLabel = new Label(boardErrors);
			errorLabel.setLocation(0, 0);
			errorLabel.setSize(this.boardWidth, this.boardHeight);
			
			this.add(errorLabel);
		}
		
		g.drawImage(offscreen,0,0,this);
		offscreen.flush();
		bufferGraphics.dispose();
	}
	
	
	
	public void paint(Graphics g){
		
		this.update(g);				
	}

	
	public Color getDomainValueColor(int xIndex, int yIndex, String value)
	{
		return(Color.BLACK);
	}
	
	
	
}

