from PIL import Image, ImageDraw, ImageFont
import random

##
# Check createverbar, createhorbar arguments.
#
# @raise {ValueError} invalid arguments.
#
def checkbarargs(maxw, maxh, worh, barcolor, bgcolor):
    maxw = int(maxw)
    if maxw <= 0:
        raise ValueError('invalid max width')
    maxh = int(maxh)
    if maxh <= 0:
        raise ValueError('invalid max height')
    worh = int(worh)
    if worh < 0:
        raise ValueError('invalid height')
    if len(barcolor) < 3:
        raise ValueError('invalid bar color')
    if len(bgcolor) < 3:
        raise ValueError('invalid bar color')

##
# Create vertical bar image.
#
# @param[in] {int} maxw max width
# @param[in] {int} maxh max height
# @param[in] {int} h bar height
# @param[in] {tuple} barcolor (r, g, b, a)
# @param[in] {tuple} bgcolor (r, g, b, a)
#
# @return {PIL.Image}
#
def createverbar(maxw, maxh, h, barcolor=(255,255,255,255), bgcolor=(128,128,128,255)):
    checkbarargs(maxw, maxh, h, barcolor, bgcolor)

    bar = Image.new('RGBA', (maxw, maxh))
    d = ImageDraw.Draw(bar)

    bgbox = (0, 0, maxw, maxh-h)
    barbox = (0, maxh-h, maxw, maxh)

    d.rectangle(xy=bgbox, fill=bgcolor)
    d.rectangle(xy=barbox, fill=barcolor)
    del d

    return bar

##
# Create horizontal bar image.
#
# @param[in] {int} maxw max width
# @param[in] {int} maxh max height
# @param[in] {int} w bar width
# @param[in] {tuple} barcolor (r, g, b, a)
# @param[in] {tuple} bgcolor (r, g, b, a)
#
# @return {PIL.Image}
#
def createhorbar(maxw, maxh, w, barcolor=(255,255,255,255), bgcolor=(128,128,128,255)):
    checkbarargs(maxw, maxh, w, barcolor, bgcolor)

    bar = Image.new('RGBA', (maxw, maxh))
    d = ImageDraw.Draw(bar)

    bgbox = (w, 0, maxw, maxh)
    barbox = (0, 0, w, maxh)

    d.rectangle(xy=bgbox, fill=bgcolor)
    d.rectangle(xy=barbox, fill=barcolor)
    del d

    return bar

##
# Save Image to file-system.
#
# @param[in] {Image} img
# @param[in] {str} path
#
def saveimage(img, path):
    import os
    if not os.path.isdir(os.path.dirname(path)):
        raise ValueError('invalid save path. "{0}" is not a directory'.format(path))
    img.save(path)

##
# Create and save vertical bar image to file-system.
#
# Example:
#
#   bar = saveverbar('/tmp/bar.png', 500, 50, 100, 400, barcolor=(255,128,0,0), bgcolor=(0,0,0,255))
#   bar.show()
# 
# @param[in] {str} path save image path
# @param[in] {int} nvisitors number of limit of visitors
# @param[in] {int} n number of visitors
# @param[in] {int} maxw max width of bar image
# @param[in] {int} maxh max height of bar image
# @param[in] {tuple} barcolor bar color. default to (255,255,255)
# @param[in] {tuple} bgcolor bg color. default to (128,128,128)
#
# @return {Image} saved Pillow image
#
def saveverbar(path, nvisitors, n, maxw, maxh, barcolor=(255,255,255,255), bgcolor=(128,128,128,255)):
    nvisitors = int(nvisitors) or 1
    n = int(n)
    maxw = int(maxw)
    maxh = int(maxh)

    h = maxh * (1/nvisitors * n)
    img = createverbar(maxw, maxh, h, barcolor, bgcolor)
    saveimage(img, path)

    return img

##
# Create and save horizontal bar image to file-system.
#
# Example:
#
#   bar = savehorbar('/tmp/bar.png', 500, 50, 100, 400, barcolor=(255,128,0,0), bgcolor=(0,0,0,255))
#   bar.show()
# 
# @param[in] {str} path save image path
# @param[in] {int} nvisitors number of limit of visitors
# @param[in] {int} n number of visitors
# @param[in] {int} maxw max width of bar image
# @param[in] {int} maxh max height of bar image
# @param[in] {tuple} barcolor bar color. default to (255,255,255)
# @param[in] {tuple} bgcolor bg color. default to (128,128,128)
#
# @return {Image} saved Pillow image
#
def savehorbar(path, nvisitors, n, maxw, maxh, barcolor=(255,255,255,255), bgcolor=(128,128,128,255)):
    nvisitors = int(nvisitors) or 1
    n = int(n)
    maxw = int(maxw)
    maxh = int(maxh)

    h = maxw * (1/nvisitors * n)
    img = createhorbar(maxw, maxh, h, barcolor, bgcolor)
    saveimage(img, path)

    return img

##
# Create and save calendar tails image to file-system.
#
# @param[in] {str} path save image path
# @param[in] {int} nvisitors number of limit of visitors
# @param[in] {int} n number of visitors
# @param[in] {int} maxw max width of bar image
# @param[in] {int} maxh max height of bar image
#
# @return {Image} saved Pillow image
#
def savecalrect(path, nvisitors, n, maxw=32, maxh=32):
    nvisitors = int(nvisitors) or 1

    per = 1/nvisitors * n
    nput = int(per * 100)

    img = Image.new('RGBA', (maxw, maxh))
    d = ImageDraw.Draw(img)

    box = (0, 0, maxw, maxh)
    bgcolor = (255,255,255,0)

    random.seed()

    d.rectangle(xy=box, fill=bgcolor)
    for _ in range(0, nput):
        ofsx = random.randint(2, 30)
        ofsy = random.randint(2, 30)
        d.ellipse(xy=(ofsx, ofsy, ofsx+2, ofsy+2), fill=(255,180,60,255))

    del d
    saveimage(img, path)

    return img
