from random import Random
from MineSquare import MineSquare
import pdb

class MineField:
    def __init__(self, width = 0, height = 0, mines = 0):
	self.setHeight(height)
	self.setWidth(width)
	self.m_mines = mines
	if width > 0 and height > 0:
	    self.m_field = []
	    for i in range(0,height*width):
		self.m_field.append(MineSquare())
	    self.populate(mines)

    def setHeight(self, h):
	self.m_height = h

    def setWidth(self, w):
	self.m_width = w

    def getHeight(self):
	return self.m_height

    def getWidth(self):
	return self.m_width

    def getSquare(self, x, y):
	if self.m_field and self.isSquareValid(x,y):
	    return self.m_field[x+(y*self.getWidth())]
	else:
	    return None
    
    def populate(self, mines):
	r = Random()
	r.seed()
	max = self.m_height * self.m_width
	n = r.randint(0,max)
	for i in range(1,self.m_mines):
	    while(self.m_field[n].getMined()):
		n = r.randint(0,max)
	    self.m_field[n].setMined(True)
	    self.incNeighborsOf((n - ((n/self.m_width) * self.m_width)), (n/self.m_width))
	
    def getMines(self):
	return self.m_mines

    def outputAsString(self):
	string = ""
	for i in range(0,self.m_width*self.m_height):
	    if i % self.m_width == 0:
		string = string + "\n"
	    sq = self.m_field[i]
	    if sq.getFlagged():
		c = " F"
	    elif sq.getCovered():
		c = " +"
	    else:
		c = " " + str(sq.getNeighbors())
	    string = string + c
	print string

    def uncover(self, x, y):
	if not self.isSquareValid(x,y):
	    return 0
	sq = self.getSquare(x,y)
	if sq.getFlagged():
	    return 0
	if not sq.getCovered():
	    return 0
	sq.setCovered(False)
	if sq.getMined():
	    return -1
	n = sq.getNeighbors()
	if n == 0:
	    self.uncover(x + 1, y + 1)
	    self.uncover(x, y + 1)
	    self.uncover(x - 1, y + 1)
	    self.uncover(x + 1, y)
	    self.uncover(x - 1, y)
	    self.uncover(x + 1, y - 1)
	    self.uncover(x, y + 1)
	    self.uncover(x - 1, y - 1)
	return n

    def check(self, x, y):
	ret = False
	flags = 0
	sq = self.getSquare(x,y)
	if not sq:
	    return False
	if sq.getCovered():
	    return False
	for i in range(-1,2):
	    for j in range(-1,2):
		if self.isSquareValid(x+i,y+j) and self.getSquare(x+i,y+j).getFlagged():
		    flags = flags + 1
	if flags == sq.getNeighbors():
	    for i in range(-1,2):
		for j in range(-1,2):
		    if (j != 0 or i != 0):
			if self.isSquareValid(x+i,y+j):
			    if self.uncover(x+i,y+j)==-1:
				ret = True
	return True

    def flag(self, x, y):
	if self.isSquareValid(x,y):
	    sq = self.getSquare(x,y)
	    if not sq.getCovered():
		return
	    sq.setFlagged(not sq.getFlagged())
    
    def incNeighborsOf(self, x, y):
	for i in range(-1,2):
	    for j in range(-1,2):
		if (j != 0 or i != 0):
		    if self.isSquareValid(x+i,y+j):
			self.getSquare(x+i,y+j).incrementNeighbors()
    
    def isSquareValid(self, x, y):
	if x >= self.getWidth() or x < 0:
	    return False
	if y >= self.getHeight() or y < 0:
	    return False
	return True

    def remaining(self):
	covered = 0
	for i in range(0,self.m_width*self.m_height):
	    if self.m_field[i].getCovered():
		covered = covered + 1
	return covered - self.m_mines
