# LogoMation-like turtle graphics

from math import * # Also for export
import Tkinter

class Error(Exception):
    pass

class RawPen:

    def __init__(self, canvas):
        self._canvas = canvas
        self._items = []
        self._tracing = 1
        self._arrow = 0
        self.degrees()
        self.reset()

    def degrees(self, fullcircle=360.0):
        self._fullcircle = fullcircle
        self._invradian = pi / (fullcircle * 0.5)

    def radians(self):
        self.degrees(2.0*pi)

    def reset(self):
        canvas = self._canvas
        self._canvas.update()
        width = canvas.winfo_width()
        height = canvas.winfo_height()
        if width <= 1:
            width = canvas['width']
        if height <= 1:
            height = canvas['height']
        self._origin = float(width)/2.0, float(height)/2.0
        self._position = self._origin
        self._angle = 0.0
        self._drawing = 1
        self._width = 1
        self._color = "black"
        self._filling = 0
        self._path = []
        self._tofill = []
        self.clear()
        canvas._root().tkraise()

    def clear(self):
        self.fill(0)
        canvas = self._canvas
        items = self._items
        self._items = []
        for item in items:
            canvas.delete(item)
        self._delete_turtle()
        self._draw_turtle()

    def tracer(self, flag):
        self._tracing = flag
        if not self._tracing:
            self._delete_turtle()
        self._draw_turtle()

    def forward(self, distance):
        x0, y0 = start = self._position
        x1 = x0 + distance * cos(self._angle*self._invradian)
        y1 = y0 - distance * sin(self._angle*self._invradian)
        self._goto(x1, y1)

    def backward(self, distance):
        self.forward(-distance)

    def left(self, angle):
        self._angle = (self._angle + angle) % self._fullcircle
        self._draw_turtle()

    def right(self, angle):
        self.left(-angle)

    def up(self):
        self._drawing = 0

    def down(self):
        self._drawing = 1

    def width(self, width):
        self._width = float(width)

    def color(self, *args):
        if not args:
            raise Error, "no color arguments"
        if len(args) == 1:
            color = args[0]
            if type(color) == type(""):
                # Test the color first
                try:
                    id = self._canvas.create_line(0, 0, 0, 0, fill=color)
                except Tkinter.TclError:
                    raise Error, "bad color string: %s" % `color`
                self._set_color(color)
                return
            try:
                r, g, b = color
            except:
                raise Error, "bad color sequence: %s" % `color`
        else:
            try:
                r, g, b = args
            except:
                raise Error, "bad color arguments: %s" % `args`
        assert 0 <= r <= 1
        assert 0 <= g <= 1
        assert 0 <= b <= 1
        x = 255.0
        y = 0.5
        self._set_color("#%02x%02x%02x" % (int(r*x+y), int(g*x+y), int(b*x+y)))

    def _set_color(self,color):
        self._color = color
        self._draw_turtle()

    def write(self, arg, move=0):
        x, y = start = self._position
        x = x-1 # correction -- calibrated for Windows
        item = self._canvas.create_text(x, y,
                                        text=str(arg), anchor="sw",
                                        fill=self._color)
        self._items.append(item)
        if move:
            x0, y0, x1, y1 = self._canvas.bbox(item)
            self._goto(x1, y1)
        self._draw_turtle()

    def fill(self, flag):
        if self._filling:
            path = tuple(self._path)
            smooth = self._filling < 0
            if len(path) > 2:
                item = self._canvas._create('polygon', path,
                                            {'fill': self._color,
                                             'smooth': smooth})
                self._items.append(item)
                self._canvas.lower(item)
                if self._tofill:
                    for item in self._tofill:
                        self._canvas.itemconfigure(item, fill=self._color)
                        self._items.append(item)
        self._path = []
        self._tofill = []
        self._filling = flag
        if flag:
            self._path.append(self._position)

    def circle(self, radius, extent=None):
        if extent is None:
            extent = self._fullcircle
        x0, y0 = self._position
        xc = x0 - radius * sin(self._angle * self._invradian)
        yc = y0 - radius * cos(self._angle * self._invradian)
        if radius >= 0.0:
            start = self._angle - 90.0
        else:
            start = self._angle + 90.0
            extent = -extent
        if self._filling:
            if abs(extent) >= self._fullcircle:
                item = self._canvas.create_oval(xc-radius, yc-radius,
                                                xc+radius, yc+radius,
                                                width=self._width,
                                                outline="")
                self._tofill.append(item)
            item = self._canvas.create_arc(xc-radius, yc-radius,
                                           xc+radius, yc+radius,
                                           style="chord",
                                           start=start,
                                           extent=extent,
                                           width=self._width,
                                           outline="")
            self._tofill.append(item)
        if self._drawing:
            if abs(extent) >= self._fullcircle:
                item = self._canvas.create_oval(xc-radius, yc-radius,
                                                xc+radius, yc+radius,
                                                width=self._width,
                                                outline=self._color)
                self._items.append(item)
            item = self._canvas.create_arc(xc-radius, yc-radius,
                                           xc+radius, yc+radius,
                                           style="arc",
                                           start=start,
                                           extent=extent,
                                           width=self._width,
                                           outline=self._color)
            self._items.append(item)
        angle = start + extent
        x1 = xc + abs(radius) * cos(angle * self._invradian)
        y1 = yc - abs(radius) * sin(angle * self._invradian)
        self._angle = (self._angle + extent) % self._fullcircle
        self._position = x1, y1
        if self._filling:
            self._path.append(self._position)
        self._draw_turtle()

    def heading(self):
        return self._angle

    def setheading(self, angle):
        self._angle = angle
        self._draw_turtle()

    def window_width(self):
        width = self._canvas.winfo_width()
        if width <= 1:  # the window isn't managed by a geometry manager
            width = self._canvas['width']
        return width

    def window_height(self):
        height = self._canvas.winfo_height()
        if height <= 1: # the window isn't managed by a geometry manager
            height = self._canvas['height']
        return height

    def position(self):
        x0, y0 = self._origin
        x1, y1 = self._position
        return [x1-x0, -y1+y0]

    def setx(self, xpos):
        x0, y0 = self._origin
        x1, y1 = self._position
        self._goto(x0+xpos, y1)

    def sety(self, ypos):
        x0, y0 = self._origin
        x1, y1 = self._position
        self._goto(x1, y0-ypos)

    def goto(self, *args):
        if len(args) == 1:
            try:
                x, y = args[0]
            except:
                raise Error, "bad point argument: %s" % `args[0]`
        else:
            try:
                x, y = args
            except:
                raise Error, "bad coordinates: %s" % `args[0]`
        x0, y0 = self._origin
        self._goto(x0+x, y0-y)

    def _goto(self, x1, y1):
        x0, y0 = start = self._position
        self._position = map(float, (x1, y1))
        if self._filling:
            self._path.append(self._position)
        if self._drawing:
            if self._tracing:
                dx = float(x1 - x0)
                dy = float(y1 - y0)
                distance = hypot(dx, dy)
                nhops = int(distance)
                item = self._canvas.create_line(x0, y0, x0, y0,
                                                width=self._width,
                                                capstyle="round",
                                                fill=self._color)
                try:
                    for i in range(1, 1+nhops):
                        x, y = x0 + dx*i/nhops, y0 + dy*i/nhops
                        self._canvas.coords(item, x0, y0, x, y)
                        self._draw_turtle((x,y))
                        self._canvas.update()
                        self._canvas.after(10)
                    # in case nhops==0
                    self._canvas.coords(item, x0, y0, x1, y1)
                    self._canvas.itemconfigure(item, arrow="none")
                except Tkinter.TclError:
                    # Probably the window was closed!
                    return
            else:
                item = self._canvas.create_line(x0, y0, x1, y1,
                                                width=self._width,
                                                capstyle="round",
                                                fill=self._color)
            self._items.append(item)
        self._draw_turtle()

    def _draw_turtle(self,position=[]):
        if not self._tracing:
            return
        if position == []:
            position = self._position
        x,y = position
        distance = 8
        dx = distance * cos(self._angle*self._invradian)
        dy = distance * sin(self._angle*self._invradian)
        self._delete_turtle()
        self._arrow = self._canvas.create_line(x-dx,y+dy,x,y,
                                          width=self._width,
                                          arrow="last",
                                          capstyle="round",
                                          fill=self._color)
        self._canvas.update()

    def _delete_turtle(self):
        if self._arrow != 0:
            self._canvas.delete(self._arrow)
        self._arrow = 0



_root = None
_canvas = None
_pen = None

class Pen(RawPen):

    def __init__(self):
        global _root, _canvas
        if _root is None:
            _root = Tkinter.Tk()
            _root.wm_protocol("WM_DELETE_WINDOW", self._destroy)
        if _canvas is None:
            # XXX Should have scroll bars
            _canvas = Tkinter.Canvas(_root, background="white")
            _canvas.pack(expand=1, fill="both")
        RawPen.__init__(self, _canvas)

    def _destroy(self):
        global _root, _canvas, _pen
        root = self._canvas._root()
        if root is _root:
            _pen = None
            _root = None
            _canvas = None
        root.destroy()


def _getpen():
    global _pen
    pen = _pen
    if not pen:
        _pen = pen = Pen()
    return pen

def degrees(): _getpen().degrees()
def radians(): _getpen().radians()
def reset(): _getpen().reset()
def clear(): _getpen().clear()
def tracer(flag): _getpen().tracer(flag)
def forward(distance): _getpen().forward(distance)
def backward(distance): _getpen().backward(distance)
def left(angle): _getpen().left(angle)
def right(angle): _getpen().right(angle)
def up(): _getpen().up()
def down(): _getpen().down()
def width(width): _getpen().width(width)
def color(*args): _getpen().color(*args)
def write(arg, move=0): _getpen().write(arg, move)
def fill(flag): _getpen().fill(flag)
def circle(radius, extent=None): _getpen().circle(radius, extent)
def goto(*args): _getpen().goto(*args)
def heading(): return _getpen().heading()
def setheading(angle): _getpen().setheading(angle)
def position(): return _getpen().position()
def window_width(): return _getpen().window_width()
def window_height(): return _getpen().window_height()
def setx(xpos): _getpen().setx(xpos)
def sety(ypos): _getpen().sety(ypos)

def demo():
    reset()
    tracer(1)
    up()
    backward(100)
    down()
    # draw 3 squares; the last filled
    width(3)
    for i in range(3):
        if i == 2:
            fill(1)
        for j in range(4):
            forward(20)
            left(90)
        if i == 2:
            color("maroon")
            fill(0)
        up()
        forward(30)
        down()
    width(1)
    color("black")
    # move out of the way
    tracer(0)
    up()
    right(90)
    forward(100)
    right(90)
    forward(100)
    right(180)
    down()
    # some text
    write("startstart", 1)
    write("start", 1)
    color("red")
    # staircase
    for i in range(5):
        forward(20)
        left(90)
        forward(20)
        right(90)
    # filled staircase
    fill(1)
    for i in range(5):
        forward(20)
        left(90)
        forward(20)
        right(90)
    fill(0)
    # more text
    write("end")
    if __name__ == '__main__':
        _root.mainloop()

if __name__ == '__main__':
    demo()
