import plotly.graph_objects as go
from PIL import Image, ImageOps, ImageDraw, ImageFont, ImageFile
import numpy as np

def rotate_via_numpy(xy, radians):
    """Use numpy to build a rotation matrix and take the dot product."""
    x, y = xy
    c, s = np.cos(radians), np.sin(radians)
    j = np.matrix([[c, s], [-s, c]])
    m = np.dot(j, [x, y])

    return float(m.T[0]), float(m.T[1])

def gauge_base():
    labels = ['Red','Amber','Green','Blank']
    values = [20, 20, 60, 40]

    colors = ['#158b90', 
              '#f8981d', 
              '#f93f17', 
              '#ffffff']

    # Use `hole` to create a donut-like pie chart
    fig = go.Figure(data=[go.Pie(labels=labels, values=values, hole=.75)])

    fig.update_traces(textinfo='none', 
                      textfont_size=20,
                      rotation=77.14,
                      sort=False,
                    marker=dict(colors=colors))
    
    fig.update_layout(font_family="Arial"        )

    fig.update(layout_showlegend=False)

    fig.write_image("fig1.png", scale=4)


def donut():
    labels = ['DMIRS','Other Agencies','Applicant','Parallel']
    values = [37, 157, 1, 21]

    colors = ['#9ac4c7', '#b4afbb', '#cc8671', '#a9cada']

    # Use `hole` to create a donut-like pie chart
    fig = go.Figure(data=[go.Pie(labels=labels, values=values, hole=.6)])

    fig.update_traces(textinfo='value', textfont_size=20,
                    marker=dict(colors=colors, line=dict(color='#FFFFFF', width=3)))

    fig.update(layout_showlegend=False)
                    

    #fig.show()
    fig.write_image("fig1.png", width=600, height=600, scale=4)


def text(img: Image.Image, text, size, x, y, anchor="ms", colour="black"):
    x = img.width * x
    y = img.height * y
    
    draw = ImageDraw.Draw(img)
    font = ImageFont.truetype("arial", size)
    
    draw.text((x,y), text, font=font, fill=colour,anchor=anchor)

def gauge_labels():
    img = Image.open("fig1.png")
    inv = ImageOps.invert(img.convert("RGB"))
    print(img.size)
    print(inv.getbbox())
    
    bb = inv.getbbox()
    
    # Something is wrong, get out
    if bb is None: return
    
    gauge_width = bb[2] - bb[0]
    
    
    
    
    border = gauge_width * 0.1
    
    bb = (bb[0]-border, bb[1]-border, bb[2]+border, bb[3]+border)
    
    w = bb[2]-bb[0]
    h = bb[3]-bb[1]
    
    out = img.crop(bb)
    
    txt0 = (0.155,0.889)
    
    text(out, "0%", 80, txt0[0], txt0[1], anchor="rt" )
    text(out, "100%", 80, 1-txt0[0], txt0[1], anchor="lt" )
    
    text(out, "95%", 150, 0.5, 0.55, anchor="md")
    text(out, "Target 65 BD", 100, 0.5, 0.55, anchor="ma")  
    
    # pointer
    gcx = w/2
    gcy = gauge_width / 2 + border
    
    gauge_inside_radius = (gauge_width / 2) * 0.75 * 0.95
    
    pct = 0.95
    
    # gauage is made of 14 segments - 6 red, 2 amber, 2 green, 2 blank
    # red starts at 5 segments ccw of top (pi/7*5), and green ends at 5 segments cw from top
    # convert pct to radians of rotation from start of red
    rad = np.pi/7*5 - (np.pi/7*10 * pct)
    
    tri_pts = [(-35, -gauge_inside_radius), (35, -gauge_inside_radius), (0, -gauge_inside_radius-200)]
    tri_pts = [rotate_via_numpy(a, rad) for a in tri_pts]    
    tri_pts = tuple( (a[0]+gcx, a[1]+gcx) for a in tri_pts)
    
    # print(f'w h {w} {h}')
    # print(f'gauge_width {gauge_width}')
    # print(f'border {border}')
    # print(f'gcx gcy {gcx} {gcy}')
    
    draw = ImageDraw.Draw(out)
    draw.polygon(tri_pts, fill=(0,0,0))
      
    out.save("fig2.png")   

if __name__ == "__main__":
    #gauge()
    gauge_labels()
    
   
    # txt0pos = (txt0[0] * w, txt0[1] * h)
    # txt100pos = ((1-txt0[0])*w, txt0[1]*h)
    
    # draw = ImageDraw.Draw(out)
    # font = ImageFont.truetype("arial", 80)
    
    # draw.text(txt0pos, "0%", font=font, fill="black",anchor="rt")
    # draw.text(txt100pos, "100%", font=font, fill="black",anchor="lt")
    

