#
#   Python GUI - Drawing - Generic
#

from StdColors import black, white
from StdFonts import application_font
from Properties import Properties, overridable_property

class Canvas(Properties):

    forecolor = overridable_property('forecolor', "Foreground color.")
    backcolor = overridable_property('backcolor', "Background color.")
    pensize = overridable_property('pensize', "Width of pen for framing and stroking.")
    font = overridable_property('font', "Font for showing text.")

    def __init__(self):
        self._init_gstack()
        self.newpath()

    def _init_gstack(self):
        self._gstack = []
    
    def initgraphics(self):
        self.set_forecolor(black)
        self.set_backcolor(white)
        self.set_pensize(1)
        self.set_font(application_font)
        self.initclip()

    def newpath(self):
        self._path = []
        self._current_subpath = None
        self._current_point = (0, 0)
    
    def moveto(self, x, y):
        self._current_subpath = None
        self._current_point = self._coords(x, y)
    
    def rmoveto(self, dx, dy):
        x, y = self._current_point
        self.moveto(x + dx, y + dy)
    
    def lineto(self, x, y):
        subpath = self._current_subpath
        if subpath is None:
            subpath = [self._current_point]
            self._path.append(subpath)
            self._current_subpath = subpath
        p = self._coords(x, y)
        subpath.append(p)
        self._current_point = p
    
    def rlineto(self, dx, dy):
        x, y = self._current_point
        self.lineto(x + dx, y + dy)
    
    def closepath(self):
        subpath = self._current_subpath
        if subpath:
            subpath.append(subpath[0])
            self._current_subpath = None
    
    def fill_poly(self, points):
        self.newpath()
        point_iter = iter(points)
        self.moveto(point_iter.next())
        for p in point_iter:
            self.lineto(p)
        self.closepath()
        self.fill()
    
    #  Implementations may set _coords to one of the following
    
    def _int_coords(self, x, y):
        return int(round(x)), int(round(y))
    
    def _float_coords(self, x, y):
        return x, y

