'''
Author Martin McBride
Copyright (c) 2018
'''

import cairo

class Drawable():

    BOTTOM_LEFT = 0    
    BOTTOM_CENTRE = 1    
    BOTTOM_RIGHT = 2    
    MIDDLE_LEFT = 3    
    CENTRE = 4
    MIDDLE_RIGHT = 5    
    TOP_LEFT = 6    
    TOP_CENTRE = 7    
    TOP_RIGHT = 8    
    
    def __init__(self,
                 visible=True,
                 alpha=None,
                 cp=(0, 0),
                 translate=None,
                 scale=None,
                 rotate=None):
        self.visible = visible
        self.alpha = alpha
        self.cp = cp
        self.translate = translate
        self.scale=scale
        self.rotate = rotate
        
    def draw(self, ctx):
        pass
    
    def bounds(self, ctx):
        pass
    
    def create_state(self, ctx):
        ctx.save()
        t = self.translate if self.translate is not None else (0, 0)
        if self.rotate is not None or self.scale is not None or self.translate is not None:
            centre = self.get_centre_point(ctx)
            ctx.translate(centre[0]+t[0], centre[1]+t[1])
            if self.rotate is not None:
                ctx.rotate(self.rotate)
            if self.scale is not None:
                ctx.scale(*self.scale)
            ctx.translate(-centre[0], -centre[1])
            
    def restore_state(self, ctx):
        ctx.restore()
        
    def get_centre_point(self, ctx):
        x0, y0, x1, y1 = self.bounds(ctx)
        if self.cp == self.BOTTOM_LEFT:
            return (x0, y0)
        if self.cp == self.BOTTOM_CENTRE:
            return ((x0+x1)/2, y0)
        if self.cp == self.BOTTOM_RIGHT:
            return (x1, y0)
        elif self.cp == self.MIDDLE_LEFT:
            return (x0, (y0+y1)/2)
        if self.cp == self.CENTRE:
            return ((x0+x1)/2, (y0+y1)/2)
        if self.cp == self.MIDDLE_RIGHT:
            return (x1, (y0+y1)/2)
        elif self.cp == self.TOP_LEFT:
            return (x0, y1)
        if self.cp == self.TOP_CENTRE:
            return ((x0+x1)/2, y1)
        if self.cp == self.TOP_RIGHT:
            return (x1, y1)
        else:
            return self.cp
        
        
        
class Rectangle(Drawable):
    
    def __init__(self,
                 visible=True,
                 alpha=None,
                 cp=(0, 0),
                 translate=(0, 0),
                 scale=None,
                 rotate=None,
                 width=100,
                 height=100,
                 color=(0, 0, 0)):
        Drawable.__init__(self, visible, alpha, cp, translate, scale, rotate)
        self.width = width
        self.height = height
        self.color = color[:]

    def draw(self, ctx):
        if self.visible:
            Drawable.create_state(self, ctx)
            ctx.new_path()
            ctx.rectangle(0, 0, self.width, self.height)
            ctx.set_source_rgb(*self.color)
            ctx.fill()
            Drawable.restore_state(self, ctx)
            
    def bounds(self, ctx):
        return (0, 0, self.width, self.height)

class Text(Drawable):
    
    def __init__(self,
                 visible=True,
                 alpha=None,
                 cp=(0, 0),
                 translate=(0, 0),
                 scale=None,
                 rotate=None,
                 text='text',
                 font='ariel',
                 size=16,
                 color=(0, 0, 0)):
        Drawable.__init__(self, visible, alpha, cp, translate, scale, rotate)
        self.text = text
        self.font = font
        self.size = size
        self.color = color[:]

    def draw(self, ctx):
        if self.visible:
            ctx.select_font_face(self.font,
                                cairo.FONT_SLANT_NORMAL,
                                cairo.FONT_WEIGHT_BOLD)
            ctx.set_font_size(self.size)
            Drawable.create_state(self, ctx)
            ctx.new_path()
            ctx.move_to(0, 0)
            ctx.set_source_rgb(*self.color)
            ctx.show_text(self.text)
            Drawable.restore_state(self, ctx)
            
    def bounds(self, ctx):
        x, y, width, height, dx, dy = ctx.text_extents(self.text)
        return (0, 0, width, height)
            
class Image(Drawable):
    
    def __init__(self,
                 path,
                 visible=True,
                 alpha=None,
                 cp=(0, 0),
                 translate=(0, 0),
                 scale=None,
                 rotate=None,
                 width=100,
                 height=100):
        Drawable.__init__(self, visible, alpha, cp, translate, scale, rotate)
        self.width = width
        self.height = height
        self.path = path

    def draw(self, ctx):
        if self.visible:
            img = cairo.ImageSurface.create_from_png(self.path)
            Drawable.create_state(self, ctx)
            ctx.set_source_surface(img, 0, 0)
            ctx.paint()
            Drawable.restore_state(self, ctx)
            
    def bounds(self, ctx):
        return (0, 0, self.width, self.height)
            

@@ -2461,32 +2461,36 @@
                 
+fill
 color=(0, 0, 0))
@@ -2480,32 +2480,95 @@
 lcolor=(0, 0, 0)
+,%0A                 linecolor=None,%0A                 linewidth=1
 ):%0A        Drawa
@@ -2697,32 +2697,36 @@
        self.
+fill
 color = 
 color%5B:%5D%0A%0A  
@@ -2709,32 +2709,103 @@
 fillcolor = 
+fill
 color
-%5B:%5D
+%0A        self.linecolor = linecolor%0A        self.linewidth = linewidth
 %0A%0A    def dr
@@ -2834,32 +2834,71 @@
  if self.visible
+ and (self.fillcolor or self.linecolor)
 :%0A            Dr
@@ -3004,32 +3004,67 @@
 h, self.height)%0A
+            if self.fillcolor:%0A    
             ctx.
@@ -3076,32 +3076,36 @@
 ource_rgb(*self.
+fill
 color)%0A         
@@ -3111,16 +3111,20 @@
     
+   
+ 
 ctx.fill
 ()%0A 
@@ -3119,16 +3119,222 @@
 ctx.fill
+_preserve() if self.linecolor else ctx.fill()%0A            if self.linecolor:%0A                ctx.set_source_rgb(*self.linecolor)%0A                ctx.set_line_width(self.linewidth)%0A                ctx.stroke
 ()%0A     
@@ -3798,16 +3798,20 @@
         
+fill
 color=(0
@@ -3986,24 +3986,28 @@
    self.
+fill
 color = 
 color%5B:%5D
@@ -4002,16 +4002,17 @@
 r = 
+fill
 color
-%5B:%5D
 %0A%0A  
@@ -4396,16 +4396,20 @@
 b(*self.
+fill
 color)%0A 

Add stroke to rectangles