# 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
from settings import fileformats
from settings import oscalls

# Studio
from studio import story
from studio import analytics
from studio import studio_dialogs
from studio import checklist

# 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, "node_script")
    elif entry.startswith("blend:"):
        UI_color.set(layer, win, "node_blendfile")
    else:
        UI_color.set(layer, win, "node_imagefile")
    
    UI_elements.roundrect(layer, win,
        x,
        y, 
        0,
        0,
        6)
    
    if int(win.current["mx"]) in range(int(x), int(x+12))\
    and int(win.current["my"]) in range(int(y), int(y+12)):
        UI_color.set(layer, win, "text_normal")
        UI_elements.roundrect(layer, win,
            x,
            y, 
            0,
            0,
            6,
            fill=False)
        layer.stroke()
        
        # Start drawing the line
        
        if not  win.previous["LMB"] and win.current["LMB"] and direction != "in":
            
            # Out point
            
            win.current["tool"] = "connect"
            win.current["draw_dot"] = raw_entry
        
        elif not  win.previous["LMB"] and win.current["LMB"] and direction == "in" and win.current["tool"] != "connect":
            
            # Take out of the in point
            try:
                found = False
                win.current["tool"] = "connect"
                for arrow in win.story["arrows"]:
                    if raw_entry == arrow[1]:
                        win.current["draw_dot"] = arrow[0]#.copy()
                        found = arrow
                        break
                if found:
                    win.story["arrows"].remove(found)
                else:
                    win.current["draw_dot"] = "end"
            except:
                pass
            
            # Refrashing analytics
            story.save(win.project, win.story)
            win.analytics    = analytics.load(win.project)
            analytics.save(win.project, win.analytics)
            
                        
        # Connecting the line
        
        if  win.current["tool"] == "connect" and direction == "in" and not win.current["LMB"]:
            
            # Connecting the scenes together
            
            if raw_entry[0] not in ["file", "blend"] and win.current["draw_dot"][0] not in ["file", "blend"]:
                
                new_arrow = [
                    win.current["draw_dot"],
                    raw_entry
                    ]
                
                if new_arrow not in win.story["arrows"]:
                    win.story["arrows"].append(new_arrow)
            
            # Copying images to places
            
            elif raw_entry[0] == "asset" and win.current["draw_dot"][0] == "file":
                
                new = oscalls.copy_file(
                    win,
                    win.current["draw_dot"][1],
                    "dev"+raw_entry[1])                
                
                
                win.story["links"].append([
                    "file", new, [
                        win.current["mx"]-win.story["camera"][0]-75,
                        win.current["my"]-win.story["camera"][1]-75
                        ],
                    "" # Parent
                    ])
                
                # Now let's select and move the thing
                win.story["selected"] = [["file", len(win.story["links"])-1]]
                win.current["tool"] = "grab"
                win.current["LMB"] = [win.current["mx"], win.current["my"], True]
                
            elif raw_entry[0] == "blend" and win.current["draw_dot"][0] == "blend":
                
                new = oscalls.copy_file(
                    win,
                    win.current["draw_dot"][1],
                    "dev"+raw_entry[1])                
                
                
                win.story["links"].append([
                    "file", new, [
                        win.current["mx"]-win.story["camera"][0]-75,
                        win.current["my"]-win.story["camera"][1]-75
                        ],
                    "" # Parent
                    ])
                
                # Now let's select and move the thing
                win.story["selected"] = [["file", len(win.story["links"])-1]]
                win.current["tool"] = "grab"
                win.current["LMB"] = [win.current["mx"], win.current["my"], True]
                
            UI_math.filter_arrows(win)
            
            # Refrashing analytics
            story.save(win.project, win.story)
            win.analytics    = analytics.load(win.project)
            analytics.save(win.project, win.analytics)
            
    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, "node_script")
                    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
    
    elif entry.startswith("blend:"):
        for link in win.story["links"]:
            
            if link[0] == "file":
                link = link[1]
                fr = "blend:"+link
                
                
                if entry[entry.find(":")+1:]+"/" in link or entry[entry.find(":")+1:]+"." in link:
                    try:
                        UI_color.set(layer, win, "node_blendfile")
                        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]
    
    width = max(width,20)
    height = max(height,20)
    
    doparent = True
    
    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"\
        and int(win.current["mx"]) in range(50, int(win.current["w"]-50)) \
        and int(win.current["my"]) in range(50, int(win.current["h"]-30)):
        
            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))\
                and win.current["tool"] == "selection":
                    win.current["tool"] = "grab"
                    win.story["active"] = entry
                
            # Launching the item
            if int(win.current["mx"]) in range(int(x), int(x+width))\
            and int(win.current["my"]) in range(int(y), int(y+height)):
            
                if not win.current["LMB"] and win.previous["LMB"]\
                and entry in win.story["selected"]\
                and int(win.current["mx"]) == int(win.previous["LMB"][0])\
                and int(win.current["my"]) == int(win.previous["LMB"][1]):
                    
                    win.url = "scene"
            
            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:
                    
                    if entry not in win.story["selected"]:
                        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"] == "selection":
                UI_math.rectangle_surround(win, "selection", 
                    win.szone[0], win.szone[1],
                    [x,y], [width, height]
                    )
            
            # Now let's make the stratching thing do it's stratching. It's the
            # circle in the bottom, right corner of the selection.
            
            if win.current["tool"] == "scale" and win.current["LMB"] and win.previous["LMB"]:
                
                
                # let's get the points of the selection zone. 
                zx  = win.szone[0][0]
                zy  = win.szone[0][1]
                zsx = win.previous["LMB"][0]
                zsy = win.previous["LMB"][1]
                
                if win.current["mx"] > zx and win.current["my"] > zy:
                        
                    
                    # now let's get the motion fraction. 
                    
                    mvx = (x - zx) / (zsx - zx)
                    mvy = (y - zy) / (zsy - zy)
                    
                    svx = (win.current["mx"]- zx) / (win.previous["mx"]-zx)
                    svy = (win.current["my"]- zy) / (win.previous["my"]-zy)
                    
                    # now let's apply these
                    
                    win.story["scenes"][name]["position"][0]\
                     +=  (win.current["mx"] - win.previous["mx"])*mvx
                    
                    win.story["scenes"][name]["position"][1]\
                     +=  (win.current["my"] - win.previous["my"])*mvy
                     
                    win.story["scenes"][name]["size"][0]\
                     = max(win.story["scenes"][name]["size"][0] * svx, 40)
                    
                    win.story["scenes"][name]["size"][1]\
                     = max(win.story["scenes"][name]["size"][1] * svy, 40)
                    
                    
                    
            # Now let's do the simple grab tool.
            
            if win.current["tool"] == "grab":
                
                # If you press shift, You take things out of events
                if 65505 in win.current["keys"]:
                    doparent = False
                
                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]
                       
                        # Parent removing / assigning
                        
                        if not doparent:
                            win.story["scenes"][name]["parent"] = ""
                            
                        elif not win.story["scenes"][name]["parent"]:
                            
                            for event in win.story["events"]:
                                
                                mx, my = win.story["events"][event]["position"]
                                pmx, pmy = win.story["events"][event]["size"]
                                
                                if UI_math.rectangle_overlap(
                                    [mx, my, pmx, pmy],
                                    [x,y,width, height]):
                                    
                                    win.story["scenes"][name]["parent"] = event
                                    break
                        
                        
                    elif win.current["tool"] != "connect":    
                        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()
        
        # Tooltip
        
        if int(win.current["mx"]) in range(int(x), int(x+width))\
        and  int(win.current["my"]) in range(int(y), int(y+height)):
           UI_elements.tooltip(win, name)
        
        # Background
        UI_color.set(layer, win, "dark_overdrop")
        layer.rectangle(0,0,width, height)
        layer.fill()
        
        # top banner
        
        UI_color.set(layer, win, "node_script")
        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() 
        
    
    # In case there is a parent event in the scene.
        
    if win.story["scenes"][name]["parent"] and doparent:
        parent = win.story["scenes"][name]["parent"]
        UI_math.rectangle_surround(win, parent, 
            win.story["events"][parent]["position"],
            win.story["events"][parent]["size"],
            [x,y], [width, height]
            )
    
    # 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()
    
    
    # Here should be the event name thing. But I thought that it wasn't
    # important for a simple framing thing. 
       
    # 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"):
    
    filetype = ""
    
    # This node will output links to files.
    
    if linktype == "asset":
        width += 50
        height += 80
    
    else:
        # Let's find out what type of file is it.
        for f in fileformats.images:
            if name.endswith(f):
                filetype = "image"
        
        if not filetype:
            for f in fileformats.videos:
                if name.endswith(f):
                    filetype = "video"
    
    doparent = True
    
    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"\
        and int(win.current["mx"]) in range(50, int(win.current["w"]-50)) \
        and int(win.current["my"]) in range(50, int(win.current["h"]-30)):
        
            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))\
                and win.current["tool"] == "selection":
                    
                    
                    
                    win.current["tool"] = "grab"
                    win.story["active"] = entry
                
            # Launching the item
            if int(win.current["mx"]) in range(int(x), int(x+width))\
            and int(win.current["my"]) in range(int(y), int(y+height)):
            
                if not win.current["LMB"] and win.previous["LMB"]\
                and entry in win.story["selected"]\
                and int(win.current["mx"]) == int(win.previous["LMB"][0])\
                and int(win.current["my"]) == int(win.previous["LMB"][1]):
                    
                    if linktype == "file":
                        oscalls.file_open(win, name)
                    
                    elif int(win.current["mx"]) > x+40: # This is a hack. But whatever.
                        win.url = "assets"
                        win.cur = name
                        win.current["tool"] = "selection"
                    
            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:
                    if entry not in win.story["selected"]:
                        win.story["selected"].append(entry)

                    # Making it active.
                    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"] == "selection":
                UI_math.rectangle_surround(win, "selection", 
                    win.szone[0], win.szone[1],
                    [x,y], [width, height]
                    )
            
            # Now let's make the stratching thing do it's stratching. It's the
            # circle in the bottom, right corner of the selection.
            
            if win.current["tool"] == "scale" and win.current["LMB"] and win.previous["LMB"]:
                
                
                # let's get the points of the selection zone. 
                zx  = win.szone[0][0]
                zy  = win.szone[0][1]
                zsx = win.previous["LMB"][0]
                zsy = win.previous["LMB"][1]
                
                if win.current["mx"] > zx and win.current["my"] > zy:
                        
                    
                    # now let's get the motion fraction. 
                    
                    mvx = (x - zx) / (zsx - zx)
                    mvy = (y - zy) / (zsy - zy)
                    
                    # now let's apply these
                    
                    win.story["links"][num][2][0]\
                     +=  (win.current["mx"] - win.previous["mx"])*mvx
                    
                    win.story["links"][num][2][1]\
                     +=  (win.current["my"] - win.previous["my"])*mvy
            
            
            if win.current["tool"] == "grab":
                
                # If you press shift, You take things out of events
                if 65505 in win.current["keys"]:
                    doparent = False
                
                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]
                    
                        # Parent removing / assigning
                        
                        if not doparent:
                            win.story["links"][num][3] = ""
                            
                        elif not win.story["links"][num][3]:
                            
                            for event in win.story["events"]:
                                
                                mx, my = win.story["events"][event]["position"]
                                pmx, pmy = win.story["events"][event]["size"]
                                
                                if UI_math.rectangle_overlap(
                                    [mx, my, pmx, pmy],
                                    [x,y,width, height]):
                                    
                                    win.story["links"][num][3] = event
                                    break
                        
                    elif win.current["tool"] != "connect":    
                        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, cell="story_asset_previews")
            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, cell="story_asset_previews")
            
            else:
                UI_elements.image(layer, win, 
                    "settings/themes/"+win.settings["Theme"]+"/icons/"+assettype+".png",
                    width/2-20, 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.
            
            if int(win.current["mx"]) in range(int(x), int(x+width))\
            and  int(win.current["my"]) in range(int(y), int(y+height)):
                
                # Darkening thing.
                UI_color.set(layer, win, "dark_overdrop")
                layer.rectangle(0,0,50, height)
                layer.fill()
                
                def after(win, var):
                    if var:
                        win.story["links"].append([
                            "file", var, [
                            win.current["mx"]-win.story["camera"][0]-75,
                            win.current["my"]-win.story["camera"][1]-75
                            ],
                            ""
                            ])
                        
                        # Now let's select and move the thing
                        win.story["selected"] = [["file", len(win.story["links"])-1]]
                        win.current["tool"] = "grab"
                        win.current["LMB"] = [win.current["mx"], win.current["my"], True]
                
                    
            
                
                # Blendfiles
                def do():
                    studio_dialogs.file_select(win, name+"_blends", after, force=True, 
                        IMAGE=False, BLEND=True, VIDEO=False, FILE=False, CHR=True, VEH=True, 
                        LOC=True, OBJ=True, RND=False, FOLDER=False,  SEARCH=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():
                    studio_dialogs.file_select(win, name+"_reference", after, force=True, 
                        IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, 
                        LOC=True, OBJ=True, RND=False, FOLDER=False,  SEARCH=name+"/reference")
                
                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():
                    studio_dialogs.file_select(win, name+"_textures", after, force=True, 
                        IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, 
                        LOC=True, OBJ=True, RND=False, FOLDER=False,  SEARCH=name+"/tex")
                
                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():
                    studio_dialogs.file_select(win, name+"_renders", after, force=True, 
                        IMAGE=True, BLEND=False, VIDEO=True, FILE=False, CHR=True, VEH=True, 
                        LOC=True, OBJ=True, RND=False, FOLDER=False,  SEARCH=name+"/renders")
                
                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)
            else:
                
                # Fraction
                
                fraction = story.get_asset_data(win, 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)
            
            UI_color.set(layer, win, "node_asset")    
            
            # Tooltip
            
            if int(win.current["mx"]) in range(int(x+40), int(x+width))\
            and  int(win.current["my"]) in range(int(y), int(y+height)):
               UI_elements.tooltip(win, name)
            
        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)
            
            if name.endswith(".progress"):
                        
                fraction = checklist.get_fraction(win, name)
                
                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)
            
            if name.endswith(".blend"):
                UI_color.set(layer, win, "node_blendfile") 
                if "ast/" in name:
                    UI_color.set(layer, win, "node_asset") 
            elif filetype == "image":
                UI_color.set(layer, win, "node_imagefile") 
            
            elif filetype == "video":
                UI_color.set(layer, win, "node_videofile") 
            
            else:
                UI_color.set(layer, win, "node_script")
            
            
            # Tooltip
            
            if int(win.current["mx"]) in range(int(x), int(x+width))\
            and  int(win.current["my"]) in range(int(y), int(y+height)):
               UI_elements.tooltip(win, name)
            
        # 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=["blend", name])
            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:
            if name.endswith(".blend"):
                node_dot(outlayer, win, x+width-6, y+120, entry=["blend", name], direction="out")
            elif filetype in ["image", "video"]:
                node_dot(outlayer, win, x+width-6, y+120, entry=["file", name], direction="out")
    
    else: # If not in the frame
        if linktype == "file":
            try:
                if name.endswith(".blend"):
                    del win.out_dots["blend:"+name]
                else:
                    del win.out_dots["file:"+name]
            except:
                pass

    # In case there is a parent event in the scene.
        
    if win.story["links"][num][3] and doparent:
        parent = win.story["links"][num][3] 
        UI_math.rectangle_surround(win, parent, 
            win.story["events"][parent]["position"],
            win.story["events"][parent]["size"],
            [x,y], [width, height]
            )
                
def marker(outlayer, win, name ,x, y ):

    # This function will draw markers to the screen. They are like shortcuts in
    # a story editor space. 
    
    
    
    if int(x) in range(int(60), int(win.current["w"]-100))\
    and int(y) in range(int(60), int(win.current["h"]-80)):
        width = 200
        height = 40
        
        inscreen = True
    else:
        
        x = min(max(x, 60), win.current["w"]-100)
        y = min(max(y, 60), win.current["h"]-80)
        
        width = 40
        height = 40
        
        inscreen = False
    
    # Making the layer
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
    layer = cairo.Context(surface)
    
    entry = ["marker", name]
    
    if inscreen:
        
        doparent = True
        
        selected = False
        if win.url == "story_editor"\
        and int(win.current["mx"]) in range(50, int(win.current["w"]-50)) \
        and int(win.current["my"]) in range(50, int(win.current["h"]-30)):
        
            if win.current["LMB"] and entry in win.story["selected"]:
                if int(win.current["LMB"][0]) in range(int(x), int(x+40))\
                and int(win.current["LMB"][1]) in range(int(y), int(y+height))\
                and win.current["tool"] == "selection":
                    
                    
                    
                    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:
                    if entry not in win.story["selected"]:
                        win.story["selected"].append(entry)

                    # Making it active.
                    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"] == "selection":
                UI_math.rectangle_surround(win, "selection", 
                    win.szone[0], win.szone[1],
                    [x,y], [width, height]
                    )
            
            # Now let's make the stratching thing do it's stratching. It's the
            # circle in the bottom, right corner of the selection.
            
            if win.current["tool"] == "scale" and win.current["LMB"] and win.previous["LMB"]:
                
                
                # let's get the points of the selection zone. 
                zx  = win.szone[0][0]
                zy  = win.szone[0][1]
                zsx = win.previous["LMB"][0]
                zsy = win.previous["LMB"][1]
                
                if win.current["mx"] > zx and win.current["my"] > zy:
                        
                    
                    # now let's get the motion fraction. 
                    
                    mvx = (x - zx) / (zsx - zx)
                    mvy = (y - zy) / (zsy - zy)
                    
                    # now let's apply these
                    
                    win.story["markers"][name][0]\
                     +=  (win.current["mx"] - win.previous["mx"])*mvx
                    
                    win.story["markers"][name][1]\
                     +=  (win.current["my"] - win.previous["my"])*mvy
            
            
            if win.current["tool"] == "grab":
                
                # If you press shift, You take things out of events
                if 65505 in win.current["keys"]:
                    doparent = False
                
                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["markers"][name][0]\
                          +=  win.previous["mx"] - win.previous["LMB"][0]
                        win.story["markers"][name][1]\
                          +=  win.previous["my"] - win.previous["LMB"][1]
                        
                        x +=  win.previous["mx"] - win.previous["LMB"][0]
                        y +=  win.previous["my"] - win.previous["LMB"][1]
                        
                        
                        # Parent removing / assigning
                        
                        if not doparent:
                            win.story["markers"][name][2]  = ""
                            
                        elif not win.story["markers"][name][2] :
                            
                            for event in win.story["events"]:
                                
                                mx, my = win.story["events"][event]["position"]
                                pmx, pmy = win.story["events"][event]["size"]
                                
                                if UI_math.rectangle_overlap(
                                    [mx, my, pmx, pmy],
                                    [x,y,width, height]):
                                    
                                    win.story["markers"][name][2] = event
                                    print(event)
                                    break
                        
                        
                    elif win.current["tool"] != "connect":    
                        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()
    
    # Pin Icon
    UI_elements.image(layer, win, 
        "settings/themes/"+win.settings["Theme"]+"/icons/pin.png",
        0, 0, 40, 40)
    
    
    
    # Outputting the layer
    outlayer.set_source_surface(surface, x, y)
    outlayer.paint() 
    
    if inscreen:
    
        
        # Text editor for the marker's name.
        
        UI_elements.text(outlayer, win, name+"_marker",
            x+40,
            y,
            width-40,
            40,
            set_text=name)
            
        if name != win.text[name+"_marker"]["text"] and win.text[name+"_marker"]["text"]:
            def do():
                
                
                win.story["selected"] = []
                win.story["markers"][win.text[name+"_marker"]["text"]] = [
                    x - win.story["camera"][0],
                    y - win.story["camera"][1],
                    win.story["markers"][name][2]
                    ]
                
                win.textactive = ""
                
                del win.story["markers"][name]
                
            UI_elements.roundrect(outlayer, win, 
                x+width-40,
                y,
                40,
                40,
                10,
                button=do,
                icon="ok",
                tip=talk.text("checked"))
            
            if 65293 in win.current["keys"]:
                do()
        
        # In case there is a parent event in the scene.
        
        if win.story["markers"][name][2] and doparent:
            parent = win.story["markers"][name][2] 
            UI_math.rectangle_surround(win, parent, 
                win.story["events"][parent]["position"],
                win.story["events"][parent]["size"],
                [x,y], [width, height]
                )
                
    else:
        
        if win.textactive == name+"_marker":
            win.textactive = ""
        
        def do():
            
            nex = 0-win.story["markers"][name][0] + win.current["w"]/2
            ney = 0-win.story["markers"][name][1] + win.current["h"]/2
            
            UI_elements.animate("cameraX", win, win.story["camera"][0],nex, time=20, force=True)
            UI_elements.animate("cameraY", win, win.story["camera"][1],ney, time=20, force=True)
            
        UI_elements.roundrect(outlayer, win, 
            x+width-40,
            y,
            40,
            40,
            10,
            button=do,
            tip=name,
            fill=False)
        outlayer.stroke()