# THIS FILE IS A PART OF VCStudio
# PYTHON 3

import os
import datetime
import threading

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

# Own modules
from settings import settings
from settings import talk
from project_manager import pm_project

from studio import analytics
from studio import studio_nodes
from studio import studio_dialogs
from studio import story
from studio import analytics
from studio import checklist

#UI modules
from UI import UI_elements
from UI import UI_color

################################################################################

# This file is going to handle SCHEDULING. Primarily the output of the schedules
# to the screen. But also probably a lot of other things related to schediles.

################################################################################

def filter(project, dates):
    
    ############################################################################
    
    # This function is called on reading of analytics read. It will check whether
    # schedules are finished. Or if they are even found. Using studio/checklist.py
    # as a help.
    
    ############################################################################
    
    checkcashe = {} # Temporary checklist cashe.
    
    delete = []  # Stuff I want to delete later
    
    for date in dates:
        for i in ["assets", "scenes", "files"]:
            if i in dates[date]:
                for url in dates[date][i]:
                    for num, entry in enumerate(dates[date][i][url]):
                        if dates[date][i][url][num][1] == "schedule":
                            
                            # First of all. I didn't think about it when 
                            # writting the analytics read
                            # that I will need to know whether schedules 
                            # are [Checked] or [Un-Checked]
                        
                            if not "[Checked]" in dates[date][i][url][num]\
                            and not "[Un-Checked]" in dates[date][i][url][num]:
                                dates[date][i][url][num].insert(3, "[Un-Checked]")
                            
                            # Then let's actually try to find whether the task
                            # is checked.
                            
                        
                            # For now let's do in a simple way. Because
                            # if the whole checklist is 100% done. Then
                            # obviously the task is also checked.
                            
                            path = dates[date][i][url][num][2]
                            
                            
                            try:
                                
                                # Let's check if path exists in the project first.
                                if os.path.exists(project+"/dev"+url+path):
                                    path = project+"/dev"+url+path
                                        
                                    
                                elif os.path.exists(project+"/rnd"+url+path):
                                    path = project+"/rnd"+url+path
                                        
                                elif os.path.exists(project+"/set/"+path):
                                    path  = project+"/set/"+path
                                    
                                elif os.path.exists(project+"/"+path):
                                    path  = project+"/"+path
                                            
                                if path not in checkcashe:
                                    checkcashe[path] = checklist.get_list(path)
                                
                                # Here we check whether the checklist is 100%
                                
                                if checkcashe[path]["fraction"] == 1.0:
                                    dates[date][i][url][num][3] = "[Checked]"
                                    
                                # But what if it's not? Now we need to check 
                                # them 1 by one.    
                                    
                                else:
                                    
                                    dates[date][i][url][num][3] = "[Un-Checked]"
                                    
                                    task = checklist.get_task_by_path(checkcashe[path]["subtasks"],dates[date][i][url][num][4])
                                    
                                    # Now if the task is not found. We delete the schedule
                                    if task:
                                        if task["fraction"] == 1.0:
                                            dates[date][i][url][num][3] = "[Checked]"
                                    
                                    else:
                                        delete.append([date,i,url,dates[date][i][url][num]])
                            except:
                                delete.append([date,i,url,dates[date][i][url][num]])
    
    # Deleting all kinds of buddah
    
    for i in delete:
        q,w,e,r = i
        if r in dates[q][w][e]:
            dates[q][w][e].remove(r)
    
                 
           
    return dates
    
def get_schedules(dates):
    
    ############################################################################
    
    # This function will parse the dates data from the analytics. And get only
    # the schedules. In the format {date {url, [list of schedules]}}
    
    ############################################################################
    newdates = {}
    
    for date in dates:
        if date not in newdates:
            newdates[date] = {}
        
        for i in ["assets", "scenes", "files"]:
            if i in dates[date]:
                for url in dates[date][i]:
                    for num, entry in enumerate(dates[date][i][url]):
                        if entry[1] == "schedule":
                            if url not in newdates[date]:
                                newdates[date][url] = []
                            if [entry, num] not in newdates[date][url]:
                                newdates[date][url].append([entry, num])
                            
    
    return newdates
    
    
def draw(outlayer, win):
    
    x = 10
    y = 70
    width = win.current["w"] / 4 - 20
    height = win.current["h"] - 80
    
    # At the top above the schedules. In the bar. i want to put 2
    # buttons. One will hide done schedules, the other will
    # hide everything scheduled for other users.
    
    if "schedule_layer_settings" not in win.current:
        win.current["schedule_layer_settings"] = {
            "checked":False,
            "multiuser":False
            }
    
    for num, button in enumerate(win.current["schedule_layer_settings"]):
        
        if win.current["schedule_layer_settings"][button]:
            
            UI_color.set(outlayer, win, "progress_time")
            UI_elements.roundrect(outlayer, win,
                20+width-(40*num)-60,
                15, 
                40,
                40,
                10)
        
        def do():
            win.current["schedule_layer_settings"][button] = not win.current["schedule_layer_settings"][button]
        
        UI_elements.roundrect(outlayer, win,
            20+width-(40*num)-60,
            15, 
            40,
            40,
            10,
            do,
            button)
        
    
    # Now let's make a layer.
    
    # Making the layer
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
    layer = cairo.Context(surface)
    layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
    
    # Clip
    UI_elements.roundrect(layer, win,
        0,
        0, 
        width,
        height,
        10,
        fill=False)
    layer.clip()
    
    
    # Getting various screadule data
    schedules = get_schedules(win.analytics["dates"])
    new_date_format = "%Y/%m/%d"
    today = datetime.datetime.strftime(datetime.datetime.today(), new_date_format)
    
    
    UI_elements.text(outlayer, win, "current_date_setting",
        width-100-(width-6*40),
        15,
        (width-6*40),
        40,
        set_text=win.current["date"])
    
    if win.text["current_date_setting"]["text"] != win.current["date"]\
    and analytics.ifdate(win.text["current_date_setting"]["text"]):
        def do():
            win.current["date"] = win.text["current_date_setting"]["text"]
            win.textactive = ""
            
        UI_elements.roundrect(outlayer, win, 
            width-140,
            15,
            40,
            40,
            10,
            button=do,
            icon="ok",
            tip=talk.text("checked"))
    
    elif win.current["date"] != today:
        def do():
            win.current["date"] = today
            win.text["current_date_setting"]["text"] = today
            win.textactive = ""
        
        UI_elements.roundrect(outlayer, win, 
            width-140,
            15,
            40,
            40,
            10,
            button=do,
            icon="cancel",
            tip=talk.text("cancel"))
    
    
    
    slist = []
    
    for date in schedules:
        
        if win.current["date"] != today and date != win.current["date"]:
            continue
        
        for item in schedules[date]:
            if win.cur in item or not win.cur:
                
                slist.append([date, item, schedules[date][item]])
                
    
    # Selection magic
    if "schedule_task_selected" not in win.current:
        win.current["schedule_task_selected"] = False
    
    # Let's draw them to the screen in some way
    
    if "schedule" not in win.scroll:
        win.scroll["schedule"] = 0
    
    current_Y = 0
    
    for entry in slist:
        
        for thing in entry[2]:
            
            
            
            # Parsing the cur to get name and type 
            name = entry[1][entry[1].rfind("/")+1:]
            acur = entry[1].replace(name, "").replace("/", "")
            
            if entry[1].count("/") > 1:
                tmp = entry[1].replace("/","",1).split("/")
                acur, name  = tmp[0], tmp[1]
            else:
                name = entry[1][entry[1].rfind("/")+1:]
                acur  = ""
            
            
            fullurl = ""
            for e in thing[0][4][:-1]:
                fullurl = fullurl+e+" > "
            
            
            if acur in ["chr", "veh", "loc","obj"]:
                itemtype = "assets"
            elif not acur:
                itemtype = "files"
            else:
                itemtype = "scenes"
            
            try:
                if not win.analytics["dates"][entry[0]][itemtype]\
                            [entry[1]]:
                    continue
            except:
                continue
            
            
            UI_color.set(layer, win, "node_background")
            
            # If not all users show only current user's tasks
            if not win.current["schedule_layer_settings"]["multiuser"]\
            and thing[0][-1] != win.settings["Username"]:
                continue   
            
            # If the task is checked
            if thing[0][3] == "[Checked]":
                if not win.current["schedule_layer_settings"]["checked"]:
                    continue
                UI_color.set(layer, win, "node_blendfile") # The Green 
                    
                
            elif entry[0] != "1997/07/30":
                
                if entry[0] < today:
                    UI_color.set(layer, win, "node_badfile") # The Red
                elif entry[0] > today:
                    UI_color.set(layer, win, "node_asset") # The Purple
            
            UI_elements.roundrect(layer, win,
                0,
                win.scroll["schedule"] + current_Y, 
                width,
                75,
                10)
            
            # Selection button
            def do():
                
                if win.current["tool"] == "selection":
                    
                    if win.current["schedule_task_selected"] != [ thing, entry[1] ]:
                        win.current["schedule_task_selected"] = [ thing, entry[1] ]

                    else:
                        win.current["schedule_task_selected"] = False
                    
                    # Clearing the text
                    try:
                        del win.text["schedule_username_setting"]
                        del win.text["schedule_date_setting"]
                        del win.text["schedule_time_setting"]            
                    except:
                        pass
            UI_elements.roundrect(layer, win,
                0,
                win.scroll["schedule"] + current_Y, 
                width,
                75,
                10,
                button=do,
                tip=entry[1]+" : "+fullurl+thing[0][4][-1],
                offset=[x,y],
                fill=False)
            layer.stroke()
            
            ############# GRABBING FOR RE-SCHEDULING ##############
            
            
                
            # Grab
            if win.current["LMB"]\
            and int(win.current["LMB"][0]) in range(int(x), int(x+width))\
            and int(win.current["LMB"][1]) in range(int(y+win.scroll["schedule"] + current_Y), int(y+win.scroll["schedule"] + current_Y+75))\
            and win.current["tool"] == "selection"\
            and int(win.current["LMB"][0]) not in range(int(win.current["mx"]-2), int(win.current["mx"]+2))\
            and int(win.current["LMB"][1]) not in range(int(win.current["my"]-2), int(win.current["my"]+2)):
                
                try:
                    
                    pop = win.analytics["dates"][entry[0]][itemtype]\
                            [entry[1]].pop(thing[1])
                    
                    dev = ""
                    if itemtype == "assets":
                        dev = "/dev"
                    if itemtype == "scenes":
                        dev = "/rnd"
                    
                    win.current["tool"] = "schedule"
                    win.current["grab_data"] = [dev+entry[1]+thing[0][2], win.url, entry[1], pop[4], pop[-1]]
                    win.url = "analytics"
                except:
                    pass                
                
            # If you leave it here.
            if win.current["tool"] == "schedule" and not win.current["LMB"]:
                
                path, back, cur, schedulepath, username = win.current["grab_data"].copy()
                path = path.replace(win.project, "")
                path = path[path.find(cur)+len(cur):]
                tname = cur[cur.rfind("/")+1:]
                tacur = cur.replace(name, "").replace("/", "")
                
                if tacur in ["chr", "veh", "loc","obj"]:
                    itemtype = "assets"
                elif not tacur:
                    itemtype = "files"
                else:
                    itemtype = "scenes"
                
                theday = win.current["date"]
                
                if theday not in win.analytics["dates"]:
                    win.analytics["dates"][theday] = {}
                
                if itemtype not in win.analytics["dates"][theday]:
                    win.analytics["dates"][theday][itemtype] = {}
                
                if cur not in win.analytics["dates"][theday][itemtype]:
                    win.analytics["dates"][theday][itemtype][cur] = []
                
                win.analytics["dates"][theday][itemtype][cur].append(
                    ["00:00:00",
                    "schedule",
                    path,
                    "[Un-Checked]",
                    schedulepath,
                    username]
                    )
            
            
                # RETURNING BACK TO NORMAL
                    
                win.url = back
                win.current["tool"] = "selection"
                analytics.save(win.project, win.analytics)
                win.analytics = analytics.load(win.project)
                win.checklists = {}
                
                # Multiuser sycning
                win.multiuser["request"] = "analytics"
            
            
            
            ######################################################### 
            
            
            
            # ICON
            UI_elements.image(layer, win, 
                "settings/themes/"+win.settings["Theme"]+"/icons/schedule.png",
                5, win.scroll["schedule"] + current_Y+5, 40, 40)
            
            # MAIN TASK
            UI_color.set(layer, win, "text_normal")
            layer.set_font_size(20)
            layer.move_to(
                50,
                win.scroll["schedule"] + current_Y+25,
                )
            layer.show_text(thing[0][4][-1])
            
            # TASK URL INSIDE THE CHECKLIST
            
            if fullurl:
                layer.set_font_size(10)
                layer.move_to(
                    60+len(thing[0][4][-1])*12,
                    win.scroll["schedule"] + current_Y+25,
                    )
                layer.show_text(fullurl)
            
            # NAME OF THE ASSET / SHOT
            if acur in ["chr", "veh", "loc", "obj"]:
                assetname = talk.text(acur)+": "+name
            else:
                assetname = entry[1]
            
            layer.set_font_size(15)
            layer.move_to(
                50,
                win.scroll["schedule"] + current_Y+45,
                )
            layer.show_text(assetname)
            
            # DATE
            if entry[0] != "1997/07/30" and entry[0] != today:
                layer.set_font_size(15)
                layer.move_to(
                    width-130,
                    win.scroll["schedule"] + current_Y+45,
                    )
                layer.show_text(entry[0])
            
            # TIME
        
            layer.set_font_size(15)
            layer.move_to(
                width-130,
                win.scroll["schedule"] + current_Y+65,
                )
            layer.show_text(thing[0][0])
            
            # USERNAME
            layer.set_font_size(15)
            layer.move_to(
                20,
                win.scroll["schedule"] + current_Y+65,
                )
            layer.show_text(talk.text("user_schedules")+" "+thing[0][-1])
            
            # IF SELECTED THERE WILL BE MORE STUFF
            if win.current["schedule_task_selected"] == [ thing, entry[1] ]:
                UI_color.set(layer, win, "text_normal")
                UI_elements.roundrect(layer, win,
                    1,
                    win.scroll["schedule"] + current_Y, 
                    width-2,
                    75,
                    10,
                    fill=False)
                layer.stroke()
                
                current_Y = current_Y + 85
                
                # If it's a task from an asset or a scene. There should be a link
                # to it. But first let's check that's it's infect an asset.
                # because...
                
                if entry[1]:
                    
                    goto = "script"
                    itemtype = "scenes"
                    
                    # If asset:
                    if acur in ["chr", "veh", "loc","obj"]:
                        # ICON
                        UI_elements.image(layer, win, 
                            "settings/themes/"+win.settings["Theme"]+"/icons/"+acur+".png",
                            25, win.scroll["schedule"] + current_Y+5, 40, 40)
                        
                        goto = "assets"
                        itemtype = "assets"
                        
                    elif not acur:
                        itemtype = "files"
                    else:
                        goto = "script"
                        itemtype = "scenes"
                    
                    if goto == "script":
                        # ICON
                        UI_elements.image(layer, win, 
                            "settings/themes/"+win.settings["Theme"]+"/icons/scene.png",
                            25, win.scroll["schedule"] + current_Y+5, 40, 40)
                        
                    # Here comes the link button
                    
                    def do():
                        win.url = goto
                        win.cur = entry[1]
                        win.current["asset_left_panel"] = "schedule"
                    UI_elements.roundrect(layer, win,
                        20,
                        win.scroll["schedule"] + current_Y+5, 
                        width-20,
                        40,
                        10,
                        button=do,
                        tip=entry[1]+" : "+fullurl+thing[0][4][-1],
                        offset=[x,y],
                        fill=False)
                    layer.stroke()
                    
                    #Title
                    UI_color.set(layer, win, "text_normal")
                    layer.set_font_size(20)
                    layer.move_to(
                        80,
                        win.scroll["schedule"] + current_Y+30,
                        )
                    layer.show_text(assetname)
                    
                    current_Y = current_Y + 50
                
                # Next thing! Let's show the most editable values. I think the first
                # one. For the director will be important. Is to edit the USER.
                # or in other words. Who is doing the task.
                
                # In the end It will be a drop down menu. Like all of it. But for this
                # I need to implement MULTIUSER first. And it's not a priority right
                # now. So a simple text editor could be okay.
                
                # ICON
                UI_elements.image(layer, win, 
                    "settings/themes/"+win.settings["Theme"]+"/icons/user.png",
                    25, win.scroll["schedule"] + current_Y+5, 40, 40)
                
                UI_elements.text(layer, win, "schedule_username_setting",
                    80,
                    win.scroll["schedule"] + current_Y+5,
                    width-80,
                    40,
                    set_text=thing[0][-1],
                    tip=talk.text("username"),
                    offset=[x,y])
                
                if win.text["schedule_username_setting"]["text"] != thing[0][-1]:
                    def do():
                        thing[0][-1] = win.text["schedule_username_setting"]["text"]
                        analytics.save(win.project, win.analytics)
                        
                        # Multiuser sycning
                        win.multiuser["request"] = "analytics"
                        
                    UI_elements.roundrect(layer, win, 
                        width-40,
                        win.scroll["schedule"] + current_Y+5,
                        40,
                        40,
                        10,
                        button=do,
                        icon="ok",
                        tip=talk.text("checked"),
                        offset=[x,y])
                
                current_Y = current_Y + 50 
                
                # DATE : TIME 
                
                UI_elements.image(layer, win, 
                    "settings/themes/"+win.settings["Theme"]+"/icons/schedule.png",
                    25, win.scroll["schedule"] + current_Y+5, 40, 40)
                
                UI_elements.text(layer, win, "schedule_date_setting",
                    80,
                    win.scroll["schedule"] + current_Y+5,
                    (width-80)/2-20,
                    40,
                    set_text=entry[0],
                    tip=talk.text("username"),
                    offset=[x,y])
                
                ### DELETE KEY ###
                
                if acur in ["chr", "veh", "loc","obj"]:
                    itemtype = "assets"
                elif not acur:
                    itemtype = "files"
                else:
                    itemtype = "scenes"
                
                if 65535 in win.current["keys"]:
                    pop = win.analytics["dates"][entry[0]][itemtype]\
                            [entry[1]].pop(thing[1])
                    win.current["keys"] = []
                    
                    analytics.save(win.project, win.analytics)
                    win.analytics = analytics.load(win.project)
                    
                if win.text["schedule_date_setting"]["text"] != entry[0]\
                and analytics.ifdate(win.text["schedule_date_setting"]["text"]):
                    def do():
                    
                        
                        
                        pop = win.analytics["dates"][entry[0]][itemtype]\
                            [entry[1]].pop(thing[1])
                        
                        if win.text["schedule_date_setting"]["text"] not in win.analytics["dates"]:
                            win.analytics["dates"][win.text["schedule_date_setting"]["text"]] = {}
                        if itemtype not in win.analytics["dates"][win.text["schedule_date_setting"]["text"]]:
                            win.analytics["dates"][win.text["schedule_date_setting"]["text"]][itemtype] = {}
                        if entry[1] not in win.analytics["dates"][win.text["schedule_date_setting"]["text"]][itemtype]:
                            win.analytics["dates"][win.text["schedule_date_setting"]["text"]][itemtype][entry[1]] = []
                        
                        win.analytics["dates"][win.text["schedule_date_setting"]["text"]][itemtype]\
                        [entry[1]].append(pop)
                    
                        analytics.save(win.project, win.analytics)
                        win.analytics = analytics.load(win.project)
                        
                        # Multiuser sycning
                        win.multiuser["request"] = "analytics"
                        
                    UI_elements.roundrect(layer, win, 
                        (width-80)/2+20,
                        win.scroll["schedule"] + current_Y+5,
                        40,
                        40,
                        10,
                        button=do,
                        icon="ok",
                        tip=talk.text("checked"),
                        offset=[x,y])
                
                # TIME
                
                UI_elements.text(layer, win, "schedule_time_setting",
                    80+(width-80)/2,
                    win.scroll["schedule"] + current_Y+5,
                    (width-80)/2,
                    40,
                    set_text=thing[0][0],
                    tip=talk.text("username"),
                    offset=[x,y])
                
                if win.text["schedule_time_setting"]["text"] != thing[0][0]\
                and analytics.iftime(win.text["schedule_time_setting"]["text"]):
                    def do():
                        thing[0][0] = win.text["schedule_time_setting"]["text"]
                        
                        analytics.save(win.project, win.analytics)
                        win.analytics = analytics.load(win.project)
                        
                        # Multiuser sycning
                        win.multiuser["request"] = "analytics"
                        
                    UI_elements.roundrect(layer, win, 
                        width-40,
                        win.scroll["schedule"] + current_Y+5,
                        40,
                        40,
                        10,
                        button=do,
                        icon="ok",
                        tip=talk.text("checked"),
                        offset=[x,y])
                
                
                
                current_Y = current_Y + 70 
                
            
            else:
                current_Y = current_Y + 85
        
                
    
    # Outputting the layer
    outlayer.set_source_surface(surface, x, y)
    outlayer.paint() 
    
    # Scroll
    UI_elements.scroll_area(outlayer, win, "schedule", 
        x+0,
        y+50,
        width, 
        height-50,
        current_Y,
        bar=True,
        mmb=True)