#!/usr/bin/python

import sys
from string import join

from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Flowable, Frame
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.rl_config import defaultPageSize
from reportlab.lib.units import inch
from reportlab.lib.colors import black, white
from reportlab.pdfgen import canvas

PAGE_HEIGHT = defaultPageSize[1]
PAGE_WIDTH = defaultPageSize[0]
styles = getSampleStyleSheet()

from sgfparser import *
    

class boardPDF(Flowable):

    def __init__(self, filename, pos = (0,0), boardsize = 19, unit = .25, region=(1,1,19,19)):
        self.boardsize = boardsize
        self.unit = unit * inch
        self.pos = pos
        self.region = region

        self.blackList = []
        self.whiteList = []

    def initBoard(self):
        self.canv.translate(-(self.region[0]-1)*self.unit, -(self.region[1]-1)*self.unit)         
        self.p = self.canv.beginPath()
        self.p.rect(.6*self.unit+(self.region[0]-1.5)*self.unit, .6*self.unit+(self.region[1]-1.5)*self.unit,
                    (self.region[2])*self.unit, (self.region[3])*self.unit)
        self.canv.clipPath(self.p,0)
        # self.canv.translate(-(.5*inch+(self.region[0]-.49)*self.unit), -(.5*inch+(self.region[1]-.49)*self.unit))
        
        l1 = [ self.unit*.6 + i * self.unit for i in range(self.boardsize) ]
        self.canv.grid(l1, l1)

        self.canv.saveState()
        self.canv.setLineWidth(2.5)
        self.canv.setLineCap(2)
        l1 = [self.unit*.6, self.unit*.6 + (self.boardsize-1)*self.unit]
        self.canv.grid(l1, l1)
        self.canv.restoreState()

        if self.boardsize == 19:
            for i in range(3):
                for j in range(3):
                    self.canv.circle(self.unit*.6 + (i*6 + 3) * self.unit, self.unit*.6 + (j*6 + 3) * self.unit,
                                     .075 * self.unit, 1, 1)
        elif self.boardsize == 13:
            for i in range(3):
                for j in range(3):
                    self.canv.circle(self.unit*.6 + (i*3 + 3) * self.unit, self.unit*.6 + (j*3 + 3) * self.unit,
                                     .075 * self.unit, 1, 1)
        elif self.boardsize == 9:
            for i in range(2):
                for j in range(2):
                    self.canv.circle(self.unit*.6 + (i*4 + 2) * self.unit, self.unit*.6 + (j*4 + 2) * self.unit,
                                     .075 * self.unit, 1, 1)
            self.canv.circle(self.unit*.6 + 4 * self.unit, self.unit*.6 + 4 * self.unit, .075 * self.unit, 1, 1)
 
##    def save(self):
##        self.board.showPage()
##        self.board.save()    

    def draw(self):
        self.initBoard()
        for x, y, text in self.blackList: self.drawBlackStone(x, y, text)
        for x, y, text in self.whiteList: self.drawWhiteStone(x, y, text)

    def wrap(self, availWidth, availHeight):
        return (self.region[2]) * self.unit, (self.region[3]) * self.unit

    def split(self, availWidth, availHeight):
        return []

    def getSpaceAfter(self):
        return 0
    
    def getSpaceBefore(self):
        return 0
        
    def blackStone(self, x, y, text = None):
        self.blackList.append((x, y, text))

    def drawBlackStone(self, x, y, text=None):
        self.canv.saveState()
        self.canv.setStrokeColor(black)
        self.canv.setFillColor(black)
        self.canv.circle(self.unit*.6 + (x-1)*self.unit, self.unit*.6 + (y-1)*self.unit, .472*self.unit, 1, 1)
    
        if not text is None:
            self.canv.setStrokeColor(white)
            self.canv.setFillColor(white)
            self.canv.setFont('Helvetica', self.unit*.5)
            self.canv.drawCentredString(self.unit*.6 + (x-1)*self.unit, self.unit*.6 + y*self.unit-1.18*self.unit, text)

        self.canv.restoreState()

    def whiteStone(self, x, y, text = None):
        self.whiteList.append((x, y, text))

    def drawWhiteStone(self, x, y, text=None):
        self.canv.saveState()
        self.canv.setStrokeColor(black)
        self.canv.setFillColor(white)
        self.canv.circle(self.unit*.6 + (x-1)*self.unit, self.unit*.6 + (y-1)*self.unit, .472*self.unit, 1, 1)
    
        if not text is None:
            self.canv.setStrokeColor(black)
            self.canv.setFillColor(black)
            self.canv.setFont('Helvetica', self.unit*.5)
            self.canv.drawCentredString(self.unit*.6 + (x-1)*self.unit, self.unit*.6 + y*self.unit-1.18*self.unit, text)

        self.canv.restoreState()


def outputSGF(cursor, b, max=50, startWith = 1, firstMoveNum=1):

    d = {}
    superL = []
    counter = 1

    while counter < startWith:

        # AB's, AW's
        # captures!!!!!!!!
        
        if cursor.currentNode().has_key('B'):
            x = ord(cursor.currentNode()['B'][0][0]) - ord('a') + 1
            y = b.boardsize - (ord(cursor.currentNode()['B'][0][1]) - ord('a'))
            b.blackStone(x, y, '')
            d[(x,y)] = ('B', None)
            counter += 1
        elif cursor.currentNode().has_key('W'):
            x = ord(cursor.currentNode()['W'][0][0]) - ord('a') + 1
            y = b.boardsize - (ord(cursor.currentNode()['W'][0][1]) - ord('a'))
            b.whiteStone(x, y, '')
            d[(x,y)] = ('W', None)
            counter += 1
            
        if cursor.noChildren(): cursor.next()
        else: return

    counter = 0
    while 1 and counter < max:

        # AB's, AW's

        # more elaborate 'x at y'
        
        if cursor.currentNode().has_key('B'):
            x = ord(cursor.currentNode()['B'][0][0]) - ord('a') + 1
            y = b.boardsize - (ord(cursor.currentNode()['B'][0][1]) - ord('a'))
            if not d.has_key((x,y)):
                b.blackStone(x, y, `counter+firstMoveNum`)
                d[(x,y)] = ('B', counter+firstMoveNum)
            else:
                if d[(x,y)][1]:
                    superL.append(`counter+firstMoveNum` + ' at ' + `d[(x,y)][1]`)
                else:
                    superL.append(`counter+firstMoveNum` + ' at ???')
            counter += 1
        elif cursor.currentNode().has_key('W'):
            x = ord(cursor.currentNode()['W'][0][0]) - ord('a') + 1
            y = b.boardsize - (ord(cursor.currentNode()['W'][0][1]) - ord('a'))
            if not d.has_key((x,y)):
                b.whiteStone(x, y, `counter+firstMoveNum`)
                d[(x,y)] = ('W', counter+firstMoveNum)
            else:
                if d[(x,y)][1]:
                    superL.append(`counter+firstMoveNum` + ' at ' + `d[(x,y)][1]`)
                else:
                    superL.append(`counter+firstMoveNum` + ' at ???')
            counter += 1
            
        if cursor.noChildren(): cursor.next()
        else: break

        # b.board.drawString(inch, .25*inch, join(superL, ', '))

def myFirstPage(canvas, doc):
    canvas.saveState()
    canvas.setFont('Times-Bold', 16)
    canvas.drawCentredString(PAGE_WIDTH/2.0, PAGE_HEIGHT-108, Title)
    canvas.setFont('Times-Roman', 9)
    canvas.drawString(inch, 0.75*inch, 'First page / %s' % pageinfo)
    canvas.restoreState()
    
def myLaterPages(canvas, doc):
    canvas.saveState()
    canvas.setFont('Times-Roman', 9)
    canvas.drawString(inch, 0.75*inch, 'Page %d %s' % (doc.page, pageinfo))
    canvas.restoreState()


if __name__ == '__main__':

    if len(sys.argv) <= 1:
        print 'usage'

    file = open(sys.argv[1])
    sgf = file.read()
    file.close()

    c = Cursor(sgf, 1)
    
    b = boardPDF('goboard2', (0,3), 19, .25, (4, 4, 8, 8))
    outputSGF(c, b, 50, 50, 50)

##     Title = sys.argv[1]
##     pageinfo = 'baby case'

##     doc = SimpleDocTemplate('goboard3.pdf')
##     Story = [Spacer(1, 2*inch)]
##     style = styles['Normal']
##     for i in range(5):
##         bogustext = ('This is paragraph number %s.  ' % `i`) * 20
##         p = Paragraph(bogustext, style)
##         Story.append(p)
##         Story.append(Spacer(1, 0.2*inch))

##     Story.append(b)

##     for i in range(5,15):
##         bogustext = ('This is paragraph number %s.  ' % `i`) * 5
##         p = Paragraph(bogustext, style)
##         Story.append(p)
##         Story.append(Spacer(1, 0.2*inch))

##     doc.build(Story, onFirstPage = myFirstPage, onLaterPages = myLaterPages)

    styles = getSampleStyleSheet()
    style = styles['Normal']
    Story = []

    for i in range(2):
        bogustext = ('This is paragraph number %s.  ' % `i`) * 15
        p = Paragraph(bogustext, style)
        Story.append(p)
        Story.append(Spacer(1, 0.2*inch))

    bogustext = ('This is an extra paragraph without spacer') * 15
    p = Paragraph(bogustext, style)
    Story.append(p)

    for i in range(5,10):
        bogustext = ('This is paragraph number %s.  ' % `i`) * 10
        p = Paragraph(bogustext, style)
        Story.append(p)
        Story.append(Spacer(1, 0.2*inch))

    ca = canvas.Canvas('goboard4.pdf')

    ht = 0
    for i in range(6):
        ht += Story[i].wrap(5.8*inch, 4*inch)[1]

    ht += 16
    f1 = Frame(inch, 9*inch-ht, 6*inch, ht, showBoundary=1)
    f1.addFromList(Story, ca)
    
    f2 = Frame(inch, 2.5*inch, 3*inch, 6.5*inch-ht, showBoundary=1)
    f2.addFromList([b], ca)

    f3 = Frame(4*inch, 2.5*inch, 3*inch, 6.5*inch-ht, showBoundary=1)
    f3.addFromList(Story, ca)

    f4 = Frame(inch, inch, 6*inch, 1.5*inch, showBoundary=1)
    f4.addFromList(Story, ca)
    
    ca.save()
