from __future__ import division
from PIL import Image, ImageDraw, ImageFont, ImageOps
import re

def textBox(text, font, position, limits, colour, draw_black):
    str = ""
    limit = [0, 0]
    limit[0] = limits[0] - position[0]
    limit[1] = limits[1] - position[1]
    words = text.split(" ")
    i = 0 #index of first word
    sizex, sizey = draw_black.multiline_textsize(str, font) #size of the textbox
    #while more words to be added to string AND string textbox height < height limit
    for word in words:
        sizex, sizey = draw_black.multiline_textsize(str + word, font)
        sizex2, sizey2 = draw_black.multiline_textsize(str, font)
        if sizex < limit[0]: #if width of gen textbox < width limit
            str += word + " "
        else:
            sizex, sizey = draw_black.multiline_textsize(str + "\n" + word, font)
            if(sizey > limit[1]):
                break
            else:
                str = str.rstrip(" ")
                str += "\n" + word + " "
    draw_black.text(position, str, font = font, fill = 0)


def putImage(imagepath, maskpath, position, colour):
    img = Image.open(imagepath)
    mask = Image.open(maskpath).convert(mode='1')
    if colour is "black":
        image_black.paste(img, position, mask)
    if colour is "yellow":
        image_yellow.paste(img, position, mask)
        black_invert = ImageOps.invert(image_black.convert('L'))
        draw_yellow.bitmap((0,0), black_invert, 255)

class TextWidget():
    #this example widget will have a set size: 3x1 cells (one column)
    #an instance of this widget class can be created and pasted to canvas
    def __init__(self, cwidth, cheight, x = 0, y = 0, width = 1, height = 1, str = ""):
        self.width = width
        self.height = height
        self.wt = cwidth*width
        self.ht = cheight*height
        self.cellX = x
        self.cellY = y
        self.image_yellow = Image.new('1', (self.wt, self.ht), 255) #255: clear the frame
        self.draw_yellow = ImageDraw.Draw(self.image_yellow)
        self.image_black = Image.new('1', (self.wt, self.ht), 255) #255: clear the frame
        self.draw_black = ImageDraw.Draw(self.image_black)
        self.font = ImageFont.truetype('DejaVuSans.ttf', 16)
        self.updateWidget(str)

    def drawText(self, str):
        #define parameters for text placement
        position = (0,0)
        limit = (self.wt, self.ht)
        #write the string in the widget
        textBox(str, self.font, position, limit, "black", self.draw_black)

    def saveImages(self):
        print("saving widget images")
        self.image_black.save("imgBlackWidget.bmp")
        self.image_yellow.save("imgYellowWidget.bmp")

    def updateWidget(self, str):
        self.draw_black.rectangle((0, 0, self.wt, self.ht), fill=255)
        self.draw_yellow.rectangle((0, 0, self.wt, self.ht), fill=255)
        self.drawText(str)
        self.saveImages()

class ImageWidget():
    #this widget displays an image
    #needs to recieve an image file as input. Then resize and convert to monochrome.
    def __init__(self, cwidth, cheight, x = 0, y = 0, width = 1, height = 1, mode = "mono", img = ""):
        self.width = width
        self.height = height
        self.wt = cwidth*width
        self.ht = cheight*height
        self.cellX = x
        self.cellY = y
        self.image_yellow = Image.new('1', (self.wt, self.ht), 255) #255: clear the frame
        self.draw_yellow = ImageDraw.Draw(self.image_yellow)
        self.image_black = Image.new('1', (self.wt, self.ht), 255) #255: clear the frame
        self.draw_black = ImageDraw.Draw(self.image_black)
        self.mode = mode
        self.updateWidget(Image.open(img))

    def resizeImg(self, img):
    	#scale image down until whole image fits inside the cell
        iRatio = img.size[0]/img.size[1] #image ratio
        cRatio = self.wt/self.ht #canvas ratio
        if cRatio > iRatio: #height is limiting dimension
            fixedImg = img.resize((int(self.ht*iRatio), self.ht))
            print(" limited by height")
            return fixedImg
        if cRatio < iRatio: #width is limiting dimension
            fixedImg = img.resize((self.wt, int(self.wt/iRatio)))
            print(" limited by width")
            return fixedImg
        fixedImg = img
        print(" ratios are equal, not limited")
        return fixedImg

    def zoomImg(self, img):
    	#enlarge the image and crop to fill the widget canvas
    	iRatio = img.size[0]/img.size[1] #image ratio
        cRatio = self.wt/self.ht #canvas ratio
        if cRatio > iRatio:
        	print("new sizes as calcd in resize: "+str(self.wt)+" "+str(self.wt/iRatio))
        	fixedImg = img.resize((self.wt, int(self.wt/iRatio))) #width = wt, calc new height w/ ratio
      		offset = 0.5*(fixedImg.size[1] - self.ht) #centre by height
      		cropped = fixedImg.crop((0, offset, self.wt, offset+self.ht))
      		cropped.load()
      		print("zoomed to fill height")
      		return cropped
        if cRatio < iRatio:
        	fixedImg = img.resize((int(self.ht*iRatio), self.ht)) #height = ht, calc new width w/ ratio
    		offset = 0.5*(fixedImg.size[0] - self.wt) #centre by width
      		cropped = fixedImg.crop((offset, 0, offset+self.wt, self.ht))
      		cropped.load()
      		print("zoomed to fill width")
      		return cropped
      	print("not zoomed")
      	return img.resize((self.wt, self.ht))

    def threshold(self, val):
        if(val>100):
            return 1
        else:
            return 0

    def bwImg(self, img):
        if self.mode is "mono":
            return img.convert('L').point(self.threshold, '1')
        if self.mode is "dither":
            return img.convert(mode='1')

    def pasteImg(self, img):
        iRatio = img.size[0]/img.size[1] #image ratio
        cRatio = self.wt/self.ht #canvas ratio
        if cRatio > iRatio: #needs to be centred horizontally
            offset = int(0.5*(self.wt - img.size[0]))
            self.image_black.paste(img, (offset, 0))
        if cRatio < iRatio: #needs to be centred vertically
            offset = int(0.5*(self.ht - img.size[1]))
            self.image_black.paste(img, (0, offset))

    def saveImages(self):
        print("saving widget images")
        self.image_black.save("imgBlackWidget.bmp")
        self.image_yellow.save("imgYellowWidget.bmp")

    def updateWidget(self, img):
        rsImg = self.resizeImg(img)
        rsImg.save("rsImg.bmp")
        newImg = self.bwImg(rsImg)
        newImg.save("bwImg.bmp")
        print(" Dimensions are now: "+str(newImg.size[0])+"x"+str(newImg.size[1]))
        print(" Dimensions of widget canvas: "+str(self.wt)+"x"+str(self.ht))
        self.pasteImg(newImg)
        self.saveImages()
