import re, sets, string, sys
import color, commands, default, method, mode2, regex, tab2
from point2 import Point

class Life(mode2.Fundamental):
    def __init__(self, w):
        mode2.Fundamental.__init__(self, w)
        self.add_action(LifeShiftLeft())
        self.add_action(LifeShiftRight())
        self.add_action_and_bindings(LifeDoTurn(), ('M-RETURN',))
        for c in string.letters + string.digits + string.punctuation:
            self.add_action_and_bindings(LifeInsertString(c), c)
        self.token = 'o'
        w.buffer.set_lines(self.normalize_board(), force=True)
        w.goto_beginning()
        
    def name(self):
        return "Life"
    def normalize_board(self):
        lines    = self.window.buffer.lines
        s        = ' ' * (self.window.width-1)
        newlines = [s] * (self.window.height-1)
        for i in range(0, min(len(lines), (self.window.height-1))):
            chars = [' '] * (self.window.width-1)
            for j in range(0, min(len(lines[i]), (self.window.height-1))):
                if lines[i][j] != ' ':
                    chars[j] = self.token
            newlines[i] = ''.join(chars)
        return newlines

class LifeShiftLeft(method.Method):
    def _execute(self, w, **vargs):
        newlines = list(w.buffer.lines)
        for i in range(0, len(newlines)):
            newlines[i] = newlines[i][10:] + newlines[i][:10]
        w.buffer.set_lines(newlines)
        w.goto_beginning()
class LifeShiftRight(method.Method):
    def _execute(self, w, **vargs):
        newlines = list(w.buffer.lines)
        for i in range(0, len(newlines)):
            newlines[i] = newlines[i][-10:] + newlines[i][:-10]
        w.buffer.set_lines(newlines)
        w.goto_beginning()

# insert text
class LifeInsertString(method.Method):
    _is_method = False
    def __init__(self, s):
        self.name   = "life-insert-string-%s" % (s)
        self.args   = []
        self.help   = "Insert %r into the current buffer." % s
        self.string = s
    def _execute(self, w, **vargs):
        if w.cursor_char() == '\n':
            return
        w.right_delete()
        w.insert_string_at_cursor(w.mode.token)

class LifeDoTurn(method.Method):
    '''Run a turn of life on the current buffer'''
    def _execute(self, w, **vargs):
        lines    = w.mode.normalize_board()
        newlines = list(lines)
        w.buffer.set_lines(lines)
        w.goto_beginning()
        for y in range(0, (w.height-1)):
            line = list(newlines[y])
            for x in range(0, (w.width-1)):
                on = lines[y][x] != ' '
                count = 0
                for (i,j) in ((-1, -1), (-1, 0), (-1, 1), (0, 1),
                              (0, -1), (1, -1), (1, 0), (1, 1)):
                    y2 = (y + i) % (w.height-2)
                    x2 = (x + j) % (w.width-2)
                    if lines[y2][x2] != ' ':
                        count += 1
                if count == 3 or count == 2 and on:
                    line[x] = w.mode.token
                else:
                    line[x] = ' '
            newlines[y] = ''.join(line)
        w.buffer.set_lines(newlines)
        w.goto_beginning()