# THIS FILE IS A PART OF VCStudio
# PYTHON 3

import os
import datetime

# GTK module ( Graphical interface
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import cairo

# Own modules
from settings import settings
from settings import talk

# Studio
from studio import story

# UI modules
from UI import UI_testing
from UI import UI_color
from UI import UI_elements
from UI import UI_math

def node_dot(layer, win, x, y, direction="in", entry="end"):
    
    # This function will draw a dot to which various nodes are connected. And
    # from which connections going off.
    
    # This is a very alpha version of the dot thing
    
    raw_entry = entry
    if type(entry) == list:
        entry = entry[0]+":"+entry[1]
    
    
    if entry.startswith("scene:") or entry in ["start", "end"]:
        UI_color.set(layer, win, "progress_background")
    else:
        UI_color.set(layer, win, "node_imagefile")
    
    UI_elements.roundrect(layer, win,
        x,
        y, 
        0,
        0,
        6)
    
    
    
    if direction != "in":
        win.out_dots[entry] = [x+6, y+6]
                
    elif entry.startswith("scene:") or entry in ["start", "end"]:
        for arrow in win.story["arrows"]:
            if raw_entry == arrow[1]:
                
                fr = arrow[0]
                if type(fr) == list:
                    fr = fr[0]+":"+fr[1]
                
                try:
                    UI_color.set(layer, win, "progress_background")
                    layer.move_to(
                        win.out_dots[fr][0], 
                        win.out_dots[fr][1]
                        )
                    layer.line_to(x+6, y+6)
                    layer.stroke()
                    
                except:
                    pass
    
    elif entry.startswith("asset:"):
        for link in win.story["links"]:
            
            if link[0] == "file":
                link = link[1]
                fr = "file:"+link
                
                
                if entry[entry.find(":")+1:] in link:
                    try:
                        UI_color.set(layer, win, "node_imagefile")
                        layer.move_to(
                            win.out_dots[fr][0], 
                            win.out_dots[fr][1]
                            )
                        layer.line_to(x+6, y+6)
                        layer.stroke()
                        
                    except:
                        pass
                
    
def start_node(outlayer, win, x, y, width, height):
    
    # This function will draw a start node in the top left corner of the story
    # editor. This is where the story begins. 
    
    # Making the layer
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
    layer = cairo.Context(surface)
    
    
    # Clip
    UI_elements.roundrect(layer, win,
        0,
        0, 
        width,
        height,
        10,
        fill=False)
    layer.clip()
    
    # Background
    UI_color.set(layer, win, "dark_overdrop")
    layer.rectangle(0,0,width, height)
    layer.fill()
    
    # top banner
    
    UI_color.set(layer, win, "node_badfile")
    layer.rectangle(0,0,width, 20)
    layer.fill()
    
    # Text saying START
    UI_color.set(layer, win, "text_normal")
    layer.set_font_size(15)
    layer.move_to(width/2-len(talk.text("Start"))*9/2,15)
    layer.show_text(talk.text("Start"))
    
    
    
    # Outputting the layer
    outlayer.set_source_surface(surface, x, y)
    outlayer.paint() 
    
    # Dot
    node_dot(outlayer, win, x+width-7, y+height-12, direction="out", entry="start")
    
    
def end_node(outlayer, win, x, y, width, height):
    
    # This function will draw a end node in the bottom right corner of the story
    # editor. This is where the story ends. 
    
    # Making the layer
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
    layer = cairo.Context(surface)
    
    
    # Clip
    UI_elements.roundrect(layer, win,
        0,
        0, 
        width,
        height,
        10,
        fill=False)
    layer.clip()
    
    # Background
    UI_color.set(layer, win, "dark_overdrop")
    layer.rectangle(0,0,width, height)
    layer.fill()
    
    # top banner
    
    UI_color.set(layer, win, "node_badfile")
    layer.rectangle(0,0,width, 20)
    layer.fill()
    
    # Text saying END
    UI_color.set(layer, win, "text_normal")
    layer.set_font_size(15)
    layer.move_to(width/2-len(talk.text("End"))*9/2,15)
    layer.show_text(talk.text("End"))
    
    # Outputting the layer
    outlayer.set_source_surface(surface, x, y)
    outlayer.paint() 
    
    # Dot
    node_dot(outlayer, win, x-2, y+height-12)


def scene_node(outlayer, win, x, y, width, height, name="Unknown", fraction=0.0):
    
    # This function will draw scene nodes.  
    
    entry = ['scene', name]
    
    if int(x) in range(int(0-width), int(win.current["w"]))\
    and int(y) in range(int(0-height), int(win.current["h"])):
        
        # Making the layer
        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
        layer = cairo.Context(surface)
        
        
        
        selected = False
        if win.url == "story_editor":
        
            if win.current["LMB"] and entry in win.story["selected"]:
                if int(win.current["LMB"][0]) in range(int(x), int(x+width))\
                and int(win.current["LMB"][1]) in range(int(y), int(y+height)):
                    win.current["tool"] = "grab"
                    win.story["active"] = entry
                
            
            if win.current["LMB"] and win.current["tool"] == "selection":
                
                # If mouse over. But way more complex. Because we might select more then
                # 1 scene at ones.
                
                mx = win.current["mx"]
                my = win.current["my"]
                pmx = win.current["LMB"][0]
                pmy = win.current["LMB"][1]
                
                intersect = UI_math.rectangle_overlap(
                    [mx, my, pmx-mx, pmy-my],
                    [x,y,width, height])
                    
                # Now let's make a higlight
                if intersect:
                    selected = True
            
            elif win.previous["LMB"] and win.previous["tool"] == "selection":
                
                # If you released the mouse while selecting. Then do selecting. I guess.
                mx = win.previous["mx"]
                my = win.previous["my"]
                pmx = win.previous["LMB"][0]
                pmy = win.previous["LMB"][1]
                
                intersect = UI_math.rectangle_overlap(
                    [mx, my, pmx-mx, pmy-my],
                    [x,y,width, height])
                    
                # Now let's make a selection
                if intersect:
                    win.story["selected"].append(entry)
                    
                    if win.story["active"] not in win.story["selected"]:
                        win.story["active"] = entry
                
            if entry in win.story["selected"]:
                selected = True
        
        if selected:
            
            
            if win.current["tool"] == "grab":
                try:
                    if win.current["LMB"]:
                        x +=  win.current["mx"] - win.current["LMB"][0]
                        y +=  win.current["my"] - win.current["LMB"][1]
                        
                        
                    elif win.previous["LMB"]:
                        win.story["scenes"][name]["position"][0]\
                          +=  win.previous["mx"] - win.previous["LMB"][0]
                        win.story["scenes"][name]["position"][1]\
                          +=  win.previous["my"] - win.previous["LMB"][1]
                        
                        x +=  win.previous["mx"] - win.previous["LMB"][0]
                        y +=  win.previous["my"] - win.previous["LMB"][1]
                        
                        
                        
                        
                    else:    
                        win.current["tool"] = "selection"
                        
                        # In case there is a parent event in the scene.
                        
                        if win.story["scenes"][name]["parent"]:
                            
                            
                            parent = win.story["scenes"][name]["parent"]
                            win.story["events"][parent]["position"] = [x, y]
                            win.story["events"][parent]["size"] = [0, 0]
                        
                except:
                    raise()
                
            # The selected outline
            
            UI_color.set(outlayer, win, "progress_background")
            
            if win.story["active"] == entry:
                UI_color.set(outlayer, win, "text_normal")
                outlayer.set_line_width(4)
            UI_elements.roundrect(outlayer, win,
                x,
                y, 
                width,
                height,
                10,
                fill=False)
            outlayer.stroke()
            outlayer.set_line_width(2)
        
        # Clip
        UI_elements.roundrect(layer, win,
            0,
            0, 
            width,
            height,
            10,
            fill=False)
        layer.clip()
        
        # Background
        UI_color.set(layer, win, "dark_overdrop")
        layer.rectangle(0,0,width, height)
        layer.fill()
        
        # top banner
        
        UI_color.set(layer, win, "node_blendfile")
        layer.rectangle(0,0,width, 20)
        layer.fill()
        
        # Text saying The name of the scene
        UI_color.set(layer, win, "text_normal")
        layer.set_font_size(15)
        layer.move_to(15,15)
        layer.show_text(name)
        
        # Fraction
        UI_color.set(layer, win, "progress_background")
        UI_elements.roundrect(layer, win,
            10,
            height-20, 
            width-20,
            0,
            5)
        
        UI_color.set(layer, win, "progress_active")
        UI_elements.roundrect(layer, win,
            10,
            height-20, 
            (width-20)*fraction,
            0,
            5)
        
        
        # Outputting the layer
        outlayer.set_source_surface(surface, x, y)
        outlayer.paint() 
        
    
    # Dots
    node_dot(outlayer, win, x-5, y+25, entry=entry)
    node_dot(outlayer, win, x+width-7, y+25, direction="out",entry=entry)

def event_node(outlayer, win, x, y, width, height, name="Unknown"):
    
    # This function draws events.
    
    x = x - 20
    y = y - 20
    width = width + 40
    height = height + 40
    
    entry = ['event', name]
    
    
    # Making sure the size is alright
    if width < 100:
        width = 100
    if height < 100:
        height = 100
    
    # Making the layer
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
    layer = cairo.Context(surface)
    
    
    # Clip
    UI_elements.roundrect(layer, win,
        0,
        0, 
        width,
        height,
        10,
        fill=False)
    layer.clip()
    
    # Background
    UI_color.set(layer, win, "dark_overdrop")
    layer.rectangle(0,0,width, height)
    layer.fill()
    
    
    
    # Text saying The name of the event
    UI_color.set(layer, win, "text_normal")
    layer.set_font_size(15)
    layer.move_to(15,15)
    layer.show_text(name)
    
    
    
    # Outputting the layer
    outlayer.set_source_surface(surface, x, y)
    outlayer.paint() 
    


def link_node(outlayer, win, x, y, width=150, height=150, name="", num=0, linktype="file"):
    
    # This node will output links to files.
    
    if linktype == "asset":
        width += 50
        height += 80
    
    if int(x) in range(int(0-width), int(win.current["w"]))\
    and int(y) in range(int(0-height), int(win.current["h"])):
        
        # Making the layer
        surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
        layer = cairo.Context(surface)
        
        entry = [linktype, num]
        
        
        
        
        selected = False
        if win.url == "story_editor":
        
            if win.current["LMB"] and entry in win.story["selected"]:
                if int(win.current["LMB"][0]) in range(int(x), int(x+width))\
                and int(win.current["LMB"][1]) in range(int(y), int(y+height)):
                    win.current["tool"] = "grab"
                    win.story["active"] = entry
                
            
            if win.current["LMB"] and win.current["tool"] == "selection":
                
                # If mouse over. But way more complex. Because we might select more then
                # 1 scene at ones.
                
                mx = win.current["mx"]
                my = win.current["my"]
                pmx = win.current["LMB"][0]
                pmy = win.current["LMB"][1]
                
                intersect = UI_math.rectangle_overlap(
                    [mx, my, pmx-mx, pmy-my],
                    [x,y,width, height])
                    
                # Now let's make a higlight
                if intersect:
                    selected = True
            
            elif win.previous["LMB"] and win.previous["tool"] == "selection":
                
                # If you released the mouse while selecting. Then do selecting. I guess.
                mx = win.previous["mx"]
                my = win.previous["my"]
                pmx = win.previous["LMB"][0]
                pmy = win.previous["LMB"][1]
                
                intersect = UI_math.rectangle_overlap(
                    [mx, my, pmx-mx, pmy-my],
                    [x,y,width, height])
                    
                # Now let's make a selection
                if intersect:
                    win.story["selected"].append(entry)
                    
                    if win.story["active"] not in win.story["selected"]:
                        win.story["active"] = entry
                
            if entry in win.story["selected"]:
                selected = True
        
        if selected:
            
            
            if win.current["tool"] == "grab":
                try:
                    if win.current["LMB"]:
                        x +=  win.current["mx"] - win.current["LMB"][0]
                        y +=  win.current["my"] - win.current["LMB"][1]
                        
                        
                    elif win.previous["LMB"]:
                        win.story["links"][num][2][0]\
                          +=  win.previous["mx"] - win.previous["LMB"][0]
                        win.story["links"][num][2][1]\
                          +=  win.previous["my"] - win.previous["LMB"][1]
                        
                        x +=  win.previous["mx"] - win.previous["LMB"][0]
                        y +=  win.previous["my"] - win.previous["LMB"][1]
                        
                    else:    
                        win.current["tool"] = "selection"
                        
                        
                except:
                    raise()
        
            # The selected outline
            
            UI_color.set(outlayer, win, "progress_background")
            
            if win.story["active"] == entry:
                UI_color.set(outlayer, win, "text_normal")
                outlayer.set_line_width(4)
            UI_elements.roundrect(outlayer, win,
                x,
                y, 
                width,
                height,
                10,
                fill=False)
            outlayer.stroke()
            outlayer.set_line_width(2)
            
            
            
        # Clip
        UI_elements.roundrect(layer, win,
            0,
            0, 
            width,
            height,
            10,
            fill=False)
        layer.clip()
        
        # Background
        UI_color.set(layer, win, "dark_overdrop")
        layer.rectangle(0,0,width, height)
        layer.fill()
        
        if linktype == "asset":
            
            assettype = name[:name.rfind("/")].replace("/", "")
            
            if os.path.exists(win.project+"/dev"+name+"/renders/Preview.png"):
                UI_elements.image(layer, win, 
                    win.project+"/dev"+name+"/renders/Preview.png",
                    0, 0, width, height)
            elif os.path.exists(win.project+"/dev"+name+"/renders/Preview.jpg"):
                UI_elements.image(layer, win, 
                    win.project+"/dev"+name+"/renders/Preview.jpg",
                    0, 0, width, height)
            
            else:
                UI_elements.image(layer, win, 
                    "settings/themes/"+win.settings["Theme"]+"/icons/"+assettype+".png",
                    width/2, height/2-20, 40, 40)
            
            # Here I want to add some buttons for accessing the various folder of
            # the asset. And also to link stuff into those folders using nodes.
            
            # Darkening thing.
            UI_color.set(layer, win, "dark_overdrop")
            layer.rectangle(0,0,50, height)
            layer.fill()
            
            # Blendfiles
            def do():
                print("Blendfiles of "+name)
            
            UI_elements.roundrect(layer, win,
                5,
                25, 
                40,
                40,
                10,
                do,
                "blender",
                talk.text("blend_files_folder"),
                url="story_editor",
                offset=[x,y])
            
            
            
            # References
            def do():
                print("References of "+name)
            
            UI_elements.roundrect(layer, win,
                5,
                75, 
                40,
                40,
                10,
                do,
                "idea",
                talk.text("reference_folder"),
                url="story_editor",
                offset=[x,y])
            
            # Textures
            def do():
                print("Textures of "+name)
            
            UI_elements.roundrect(layer, win,
                5,
                125, 
                40,
                40,
                10,
                do,
                "texture",
                talk.text("tex_folder"),
                url="story_editor",
                offset=[x,y])
            
            # Renders
            def do():
                print("Renders of "+name)
            
            UI_elements.roundrect(layer, win,
                5,
                175, 
                40,
                40,
                10,
                do,
                "render",
                talk.text("renders_folder"),
                url="story_editor",
                offset=[x,y])
            
            # Fraction
            
            fraction = story.get_asset_data(win, name)["fraction"]
            
            UI_color.set(layer, win, "progress_background")
            UI_elements.roundrect(layer, win,
                65,
                height-20, 
                width-85,
                0,
                5)
            
            UI_color.set(layer, win, "progress_active")
            UI_elements.roundrect(layer, win,
                65,
                height-20, 
                (width-85)*fraction,
                0,
                5)
            
            
            UI_color.set(layer, win, "node_asset")    
            
        else:
            if os.path.exists(win.project+"/"+name):
                UI_elements.image(layer, win, 
                    win.project+"/"+name,
                    0, 0, width, height)
            
            else:
                UI_elements.image(layer, win, 
                    name,
                    0, 0, width, height)
            
            UI_color.set(layer, win, "node_imagefile") 
        
        # top banner
        
        
        layer.rectangle(0,0,width, 20)
        layer.fill()
        
        # Text saying The name of the event
        UI_color.set(layer, win, "text_normal")
        layer.set_font_size(15)
        layer.move_to(15,15)
        layer.show_text(name[name.rfind("/")+1:])
        
        # Outputting the layer
        outlayer.set_source_surface(surface, x, y)
        outlayer.paint() 
        
        if linktype == "asset":
            node_dot(outlayer, win, x-6, y+25+14, entry="shit")
            node_dot(outlayer, win, x-6, y+75+14, entry=["asset", name+"/reference"])
            node_dot(outlayer, win, x-6, y+125+14, entry=["asset", name+"/tex"])
            node_dot(outlayer, win, x-6, y+175+14, entry=["asset", name+"/renders"])
        else:
            node_dot(outlayer, win, x+width-6, y+120, entry=["file", name], direction="out")
    
    else: # If not in the frame
        if linktype == "file":
            try:
                del win.out_dots["file:"+name]
            except:
                pass