#
#   Python GUI - Drawing - Generic
#

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

class Canvas(Properties):

	_default_forecolor = black
	_default_backcolor = white
	_printing = False

	pencolor = overridable_property('pencolor', "Current color for stroking paths.")
	fillcolor = overridable_property('fillcolor', "Current color for filling paths.")
	textcolor = overridable_property('textcolor', "Current color for drawint text.")
	forecolor = overridable_property('forecolor', "Sets pen, fill and text colors to the same color.")
	backcolor = overridable_property('backcolor', "Current color for erasing regions.")
	pensize = overridable_property('pensize', "Width of pen for framing and stroking.")
	font = overridable_property('font', "Font for drawing text.")
	current_point = overridable_property('current_point', "The current point, or None.")
	printing = overridable_property('printing', "True if drawing destination is a non-display device.")

	#forecolor = overridable_property('forecolor', "Sets both pencolor and fillcolor.")

	def __init__(self):
		self.newpath()
	
	def get_printing(self):
		return self._printing

	def initgraphics(self):
		self.set_forecolor(self._default_forecolor)
		self.set_backcolor(self._default_backcolor)
		self.set_pensize(1)
		self.set_font(application_font)
	
	def set_forecolor(self, c):
		self.pencolor = c
		self.fillcolor = c
		self.textcolor = c
	
	def rmoveto(self, dx, dy):
		x0, y0 = self._current_point()
		self.moveto(x0 + dx, y0 + dy)
	
	def rlineto(self, dx, dy):
		x0, y0 = self.current_point
		self.lineto(x0 + dx, y0 + dy)
	
	def curve(self, sp, cp1, cp2, ep):
		self.moveto(sp)
		self.curveto(cp1, cp2, ep)
	
	def rcurveto(self, cp1, cp2, ep):
		x0, y0 = self.current_point
		x1, y1 = cp1
		x2, y2 = cp2
		x3, y3 = ep
		self.curveto(
			(x0 + x1, y0 + y1),
			(x0 + x2, y0 + y2),
			(x0 + x3, y0 + y3))
	
	def fill_stroke(self):
		self.fill()
		self.stroke()
	
	#  Rectangles
	
	def _pen_inset_rect(self, rect):
		l, t, r, b = rect
		p = 0.5 * self.pensize
		return (l + p, t + p, r - p, b - p)

	def rect(self, rect):
		l, t, r, b = rect
		self.moveto(l, t)
		self.lineto(r, t)
		self.lineto(r, b)
		self.lineto(l, b)
		self.closepath()
	
	def rect_frame(self, rect):
		self.rect(self._pen_inset_rect(rect))
	
	def fill_rect(self, rect):
		self.newpath()
		self.rect(rect)
		self.fill()
	
	def stroke_rect(self, rect):
		self.newpath()
		self.rect(rect)
		self.stroke()
	
	def frame_rect(self, rect):
		self.newpath()
		self.rect_frame(rect)
		self.stroke()

	def fill_stroke_rect(self, rect):
		self.rect_path(rect)
		self.fill_stroke()
	
	def fill_frame_rect(self, rect):
		self.fill_rect(rect)
		self.frame_rect(rect)
	
	def erase_rect(self, rect):
		self.newpath()
		self.rect(rect)
		self.erase()
	
	#  Ovals
	
	def oval_frame(self, rect):
		self.oval(self._pen_inset_rect(rect))
	
	def fill_oval(self, rect):
		self.newpath()
		self.oval_frame(rect)
		self.fill()
	
	def stroke_oval(self, rect):
		self.newpath()
		self.oval(rect)
		self.stroke()
	
	def frame_oval(self, rect):
		self.newpath()
		self.oval_frame(rect)
		self.stroke()

	def fill_stroke_oval(self, rect):
		self.newpath()
		self.oval(rect)
		self.fill_stroke()

	def fill_frame_oval(self, rect):
		self.fill_oval(rect)
		self.frame_oval()

	def erase_oval(self, rect):
		self.newpath()
		self.oval(rect)
		self.erase()
	
	#  Arcs
	
	def _arc_path(self, c, r, a0, a1):
#		x, y = c
#		a0r = a0 * deg
#		x0 = x + r * cos(a0r)
#		y0 = y + r * sin(a0r)
		self.newpath()
#		self.moveto(x0, y0)
		self.arc(c, r, a0, a1)
	
	def _arc_frame_path(self, c, r, a0, a1):
		self._arc_path(c, r - 0.5 * self.pensize, a0, a1)
	
	def stroke_arc(self, c, r, a0, a1):
		self._arc_path(c, r, a0, a1)
		self.stroke()
	
	def frame_arc(self, c, r, a0, a1):
		self._arc_frame_path(c, r, a0, a1)
		self.stroke()
	
		#  Wedges
	
	def wedge(self, c, r, a0, a1):
		self.moveto(*c)
		self.arc(c, r, a0, a1)
		self.closepath()
	
	def fill_wedge(self, c, r, a0, a1):
		self.newpath()
		self.wedge(c, r, a0, a1)
		self.fill()
	
	def stroke_wedge(self, c, r, a0, a1):
		self.newpath()
		self.wedge(c, r, a0, a1)
		self.stroke()
	
	def fill_stroke_wedge(self, c, r, a0, a1):
		self.newpath()
		self.wedge(c, r, a0, a1)
		self.fill_stroke()
	
	def erase_wedge(self, c, r, a0, a1):
		self.newpath()
		self.wedge(c, r, a0, a1)
		self.erase()
	
	#  Polylines
	
	def lines(self, points):
		point_iter = iter(points)
		self.moveto(*point_iter.next())
		for p in point_iter:
			self.lineto(*p)
	
	def linesto(self, points):
		for p in points:
			self.lineto(*p)
	
	def stroke_lines(self, points):
		self.newpath()
		self.lines(points)
		self.stroke()
	
	#  Polycurves
	
	def curves(self, points):
		self.moveto(*points[0])
		for i in xrange(1, len(points), 3):
			self.curveto(*points[i:i+3])
	
	def curvesto(self, points):
		for i in xrange(0, len(points), 3):
			self.curveto(*points[i:i+3])
				
	def stroke_curves(self, points):
		self.newpath()
		self.curves(points)
		self.stroke()
				
	#  Polygons

	def poly(self, points):
		self.lines(points)
		self.closepath()
		
	def fill_poly(self, points):
		self.newpath()
		self.poly(points)
		self.fill()
	
	def stroke_poly(self, points):
		self.newpath()
		self.poly(points)
		self.stroke()
	
	def fill_stroke_poly(self, points):
		self.newpath()
		self.poly(points)
		self.fill_stroke()

	def erase_poly(self, points):
		self.newpath()
		self.poly(points)
		self.erase()

	#  Loops
	
	def loop(self, points):
		self.curves(points)
		self.closepath()
	
	def fill_loop(self, points):
		self.newpath()
		self.loop(points)
		self.fill()
	
	def stroke_loop(self, points):
		self.newpath()
		self.loop(points)
		self.stroke()
	
	def fill_stroke_loop(self, points):
		self.newpath()
		self.loop(points)
		self.fill_stroke()

	def erase_loop(self, points):
		self.newpath()
		self.loop(points)
		self.erase()

#
#   Python GUI - Drawing - Generic
#

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

class Canvas(Properties):

	_default_forecolor = black
	_default_backcolor = white
	_printing = False

	pencolor = overridable_property('pencolor', "Current color for stroking paths.")
	fillcolor = overridable_property('fillcolor', "Current color for filling paths.")
	textcolor = overridable_property('textcolor', "Current color for drawint text.")
	forecolor = overridable_property('forecolor', "Sets pen, fill and text colors to the same color.")
	backcolor = overridable_property('backcolor', "Current color for erasing regions.")
	pensize = overridable_property('pensize', "Width of pen for framing and stroking.")
	font = overridable_property('font', "Font for drawing text.")
	current_point = overridable_property('current_point', "The current point, or None.")
	printing = overridable_property('printing', "True if drawing destination is a non-display device.")

	#forecolor = overridable_property('forecolor', "Sets both pencolor and fillcolor.")

	def __init__(self):
		self.newpath()
	
	def get_printing(self):
		return self._printing

	def initgraphics(self):
		self.set_forecolor(self._default_forecolor)
		self.set_backcolor(self._default_backcolor)
		self.set_pensize(1)
		self.set_font(application_font)
	
	def set_forecolor(self, c):
		self.pencolor = c
		self.fillcolor = c
		self.textcolor = c
	
	def rmoveto(self, dx, dy):
		x0, y0 = self._current_point()
		self.moveto(x0 + dx, y0 + dy)
	
	def rlineto(self, dx, dy):
		x0, y0 = self.current_point
		self.lineto(x0 + dx, y0 + dy)
	
	def curve(self, sp, cp1, cp2, ep):
		self.moveto(sp)
		self.curveto(cp1, cp2, ep)
	
	def rcurveto(self, cp1, cp2, ep):
		x0, y0 = self.current_point
		x1, y1 = cp1
		x2, y2 = cp2
		x3, y3 = ep
		self.curveto(
			(x0 + x1, y0 + y1),
			(x0 + x2, y0 + y2),
			(x0 + x3, y0 + y3))
	
	def fill_stroke(self):
		self.fill()
		self.stroke()
	
	#  Rectangles
	
	def _pen_inset_rect(self, rect):
		l, t, r, b = rect
		p = 0.5 * self.pensize
		return (l + p, t + p, r - p, b - p)

	def rect(self, rect):
		l, t, r, b = rect
		self.moveto(l, t)
		self.lineto(r, t)
		self.lineto(r, b)
		self.lineto(l, b)
		self.closepath()
	
	def rect_frame(self, rect):
		self.rect(self._pen_inset_rect(rect))
	
	def fill_rect(self, rect):
		self.newpath()
		self.rect(rect)
		self.fill()
	
	def stroke_rect(self, rect):
		self.newpath()
		self.rect(rect)
		self.stroke()
	
	def frame_rect(self, rect):
		self.newpath()
		self.rect_frame(rect)
		self.stroke()

	def fill_stroke_rect(self, rect):
		self.rect_path(rect)
		self.fill_stroke()
	
	def fill_frame_rect(self, rect):
		self.fill_rect(rect)
		self.frame_rect(rect)
	
	def erase_rect(self, rect):
		self.newpath()
		self.rect(rect)
		self.erase()
	
	#  Ovals
	
	def oval_frame(self, rect):
		self.oval(self._pen_inset_rect(rect))
	
	def fill_oval(self, rect):
		self.newpath()
		self.oval_frame(rect)
		self.fill()
	
	def stroke_oval(self, rect):
		self.newpath()
		self.oval(rect)
		self.stroke()
	
	def frame_oval(self, rect):
		self.newpath()
		self.oval_frame(rect)
		self.stroke()

	def fill_stroke_oval(self, rect):
		self.newpath()
		self.oval(rect)
		self.fill_stroke()

	def fill_frame_oval(self, rect):
		self.fill_oval(rect)
		self.frame_oval()

	def erase_oval(self, rect):
		self.newpath()
		self.oval(rect)
		self.erase()
	
	#  Arcs
	
	def _arc_path(self, c, r, a0, a1):
#		x, y = c
#		a0r = a0 * deg
#		x0 = x + r * cos(a0r)
#		y0 = y + r * sin(a0r)
		self.newpath()
#		self.moveto(x0, y0)
		self.arc(c, r, a0, a1)
	
	def _arc_frame_path(self, c, r, a0, a1):
		self._arc_path(c, r - 0.5 * self.pensize, a0, a1)
	
	def stroke_arc(self, c, r, a0, a1):
		self._arc_path(c, r, a0, a1)
		self.stroke()
	
	def frame_arc(self, c, r, a0, a1):
		self._arc_frame_path(c, r, a0, a1)
		self.stroke()
	
		#  Wedges
	
	def wedge(self, c, r, a0, a1):
		self.moveto(*c)
		self.arc(c, r, a0, a1)
		self.closepath()
	
	def fill_wedge(self, c, r, a0, a1):
		self.newpath()
		self.wedge(c, r, a0, a1)
		self.fill()
	
	def stroke_wedge(self, c, r, a0, a1):
		self.newpath()
		self.wedge(c, r, a0, a1)
		self.stroke()
	
	def fill_stroke_wedge(self, c, r, a0, a1):
		self.newpath()
		self.wedge(c, r, a0, a1)
		self.fill_stroke()
	
	def erase_wedge(self, c, r, a0, a1):
		self.newpath()
		self.wedge(c, r, a0, a1)
		self.erase()
	
	#  Polylines
	
	def lines(self, points):
		point_iter = iter(points)
		self.moveto(*point_iter.next())
		for p in point_iter:
			self.lineto(*p)
	
	def linesto(self, points):
		for p in points:
			self.lineto(*p)
	
	def stroke_lines(self, points):
		self.newpath()
		self.lines(points)
		self.stroke()
	
	#  Polycurves
	
	def curves(self, points):
		self.moveto(*points[0])
		for i in xrange(1, len(points), 3):
			self.curveto(*points[i:i+3])
	
	def curvesto(self, points):
		for i in xrange(0, len(points), 3):
			self.curveto(*points[i:i+3])
				
	def stroke_curves(self, points):
		self.newpath()
		self.curves(points)
		self.stroke()
				
	#  Polygons

	def poly(self, points):
		self.lines(points)
		self.closepath()
		
	def fill_poly(self, points):
		self.newpath()
		self.poly(points)
		self.fill()
	
	def stroke_poly(self, points):
		self.newpath()
		self.poly(points)
		self.stroke()
	
	def fill_stroke_poly(self, points):
		self.newpath()
		self.poly(points)
		self.fill_stroke()

	def erase_poly(self, points):
		self.newpath()
		self.poly(points)
		self.erase()

	#  Loops
	
	def loop(self, points):
		self.curves(points)
		self.closepath()
	
	def fill_loop(self, points):
		self.newpath()
		self.loop(points)
		self.fill()
	
	def stroke_loop(self, points):
		self.newpath()
		self.loop(points)
		self.stroke()
	
	def fill_stroke_loop(self, points):
		self.newpath()
		self.loop(points)
		self.fill_stroke()

	def erase_loop(self, points):
		self.newpath()
		self.loop(points)
		self.erase()

# #   Python GUI - Drawing - Generic # #forecolor = overridable_property('forecolor', "Sets both pencolor and fillcolor.") #  Rectangles #  Ovals #  Arcs #		x, y = c #		a0r = a0 * deg #		x0 = x + r * cos(a0r) #		y0 = y + r * sin(a0r) #		self.moveto(x0, y0) #  Wedges #  Polylines #  Polycurves #  Polygons #  Loops