# THIS FILE IS A PART OF VCStudio
# PYTHON 3


import os
from subprocess import *

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

#UI modules
from UI import UI_elements
from UI import UI_color

# story
from studio import story
from studio import analytics
from studio import history
from studio import studio_dialogs

# network
from network import multiuser_terminal

def layer(win):
    
    # Making the layer
    surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, win.current['w'],
                                                      win.current['h'])
    layer = cairo.Context(surface)
    
    
    #text setting
    layer.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
    
    UI_color.set(layer, win, "dark_overdrop")
    layer.rectangle(
        0,
        0,
        win.current["w"],
        win.current["h"],
        )
    layer.fill()
    
    
    
    ############################################################################
    
    # This is our multiuser UI. From here the user will start and stop the server
    # for the multiuser. See what that server has to say. And write text messages
    # to all the other users. Like a little messaging app, so they will not use
    # closed source apps for this. I know a lot of companies that ustilize 
    # whatsapp for this. This is not cool. And I can make a little app here.
    
    # The way it's going to look it the folosing.
    
    
    ############################################################################
    # START / STOP BUTTON                                #                     #
    ######################################################  BOB: Hello World   #
    #                                                    #                     #
    #   server started                                   #  Steve: What's Up   #
    #   BOB connected                                    #                     #
    #   Steve connected                                  #  John: Hey guys     #
    #   John connected                                   #  who can make the   #
    #   Steve updated Moria                              #  rig for Moria?     #
    #   John reqested Moria                              #                     #
    #   Steve sent Moria to John                         #  Steve: I can.      #
    #                                                    #                     #
    #################################################### #  John: Thanks.      #
    #  3 users connected:                                #                     #
    #        BOB                                         #                     #
    #        John                                        #######################
    #        Steve                                       #                 #   #
    ############################################################################
    
    # I know that it's a bit unfair to give so much space to a terminal like
    # output window. But this is kind of the most important thing in the 
    # entire Multiuser. The server. Actually the server will run only on one
    # computer. But all users will feel like they are controlling the server.
    
    # I don't like when one user thinks that he is more important then the other
    # . Because in the film production. Usually the director listens even to 
    # the guy who makes the tea. In the case of this program I want everybody
    # to feel exactly the same amount of power.
    
    ############################################################################
    
    win.multiuser["unread"] = 0
    
    # SERVER PEACE FRAME
    UI_color.set(layer, win, "node_background")
    UI_elements.roundrect(layer, win, 
        80,
        80,
        win.current["w"]/3*2-160,
        win.current["h"]/2-100,
        10)
    
    # USERS PEACE FRAME
    UI_color.set(layer, win, "node_background")
    UI_elements.roundrect(layer, win, 
        80,
        win.current["h"]/2,
        win.current["w"]/3*2-160,
        win.current["h"]/2-80,
        10)
    
    # THE SIDE PEACE FRAME
    UI_color.set(layer, win, "node_background")
    UI_elements.roundrect(layer, win, 
        win.current["w"]/3*2-60,
        80,
        win.current["w"]/3-20,
        win.current["h"]-160,
        10)
    
    ####### SERVER PART #######
    
    # On the top panel first button will be either make a server. Or if server exists,
    # close the server. This will require a little dialog similar to when deleting 
    # scenes in the story editor.
    
    # I'm going to hack my way into checking the server. Basically it autoconnects to
    # it if one is up. So..
    
    if win.multiuser["server"]:
        
        def do():
            
            # Simple UDP message
            multiuser_terminal.message("VCStudio ABORT MULTIUSER")
            
        UI_elements.roundrect(layer, win, 
            90,
            90,
            40,
            40,
            10,
            button=do,
            icon="server_close",
            tip=talk.text("multiuser_server_stop"))
    else:
        def do():
            
            # Simple Popen
            Popen(["python3", "network/multiuser_server.py", win.analytics["name"]])
            
        UI_elements.roundrect(layer, win, 
            90,
            90,
            40,
            40,
            10,
            button=do,
            icon="server_new",
            tip=talk.text("multiuser_server_start"))
    
    # Server outputs part. I'm creating a layer for it just because it needs
    # a clipping.
    
    x = 90
    y = 140
    width = win.current["w"]/3*2-160-20
    height = win.current["h"]/2-170
    
    
    # Making the layer
    surface2 = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
    node = cairo.Context(surface2)
    node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
    
    # Clip
    UI_elements.roundrect(node, win,
        0,
        0, 
        width,
        height,
        10,
        fill=False)
    node.clip()
    
    # Background tester
    #UI_color.set(node, win, "dark_overdrop")
    #node.rectangle(0,0,width, height)
    #node.fill()
    
    # Here I want to have the output of the server in a raw fasion. 
    if "multiuser_terminal" not in win.scroll:
        win.scroll["multiuser_terminal"] = 0
    
    current_Y = 10
    
    for message in win.multiuser["terminal"]:
        
        # We are going to draw a little server icon.
        UI_elements.image(node, win, 
            "settings/themes/"+win.settings["Theme"]+"/icons/server.png",
            10,
            current_Y+win.scroll["multiuser_terminal"],
            40,
            40)
        
        # And we want to have the text of the message
        
        UI_color.set(node, win, "text_normal")
        node.set_font_size(15)
        node.move_to( 60, current_Y+win.scroll["multiuser_terminal"]+27)
        node.show_text(message)
        
        current_Y = current_Y + 50
    
    # Outputting the layer
    layer.set_source_surface(surface2, x, y)
    layer.paint() 
    
    UI_elements.scroll_area(layer, win, "multiuser_terminal", 
        x,
        y,
        width, 
        height,
        current_Y,
        bar=True,
        mmb=True)
    
        
    
    ############ USERS PART ##############
    
    # Here in this part I want to put a complite list of currently connected users.
    # I have few ideas of what functionality could be added to here. But at this 
    # point I'm just trying to make the window somewhat busy looking. 
    
    # So we need to make layer here. Since I want to clip it. But be able to draw outisde 
    # the clipping area later.
    
    x = 90
    y = win.current["h"]/2+10
    width = win.current["w"]/3*2-160-20
    height = win.current["h"]/2-80-60
    
    
    # Making the layer
    surface2 = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
    node = cairo.Context(surface2)
    node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
    
    # Clip
    UI_elements.roundrect(node, win,
        0,
        0, 
        width,
        height,
        10,
        fill=False)
    node.clip()
    
    # Background tester
    #UI_color.set(node, win, "dark_overdrop")
    #node.rectangle(0,0,width, height)
    #node.fill()
    
    
    
    if "multiuser_users" not in win.scroll:
        win.scroll["multiuser_users"] = 0
    
    current_Y = 10
    
    for ip in list(win.multiuser["users"].keys()):
        try:
            user = win.multiuser["users"][ip]
        except:
            continue
        
        username = user["username"]
        
        # For each user I want to show the name, then IP:PORT
        
        # If it's us on the list I want to draw a little rectangle arround
        # this particular user
        
        if ip == win.multiuser["userid"]:
            UI_color.set(node, win, "node_blendfile")
            UI_elements.roundrect(node, win,
                0,
                current_Y+win.scroll["multiuser_users"]-5, 
                width,
                45,
                10)
        
        
        # User Icon
        UI_elements.image(node, win, 
            "settings/themes/"+win.settings["Theme"]+"/icons/user.png",
            10,
            current_Y+win.scroll["multiuser_users"],
            40,
            40)
        
        # Text
        
        UI_color.set(node, win, "text_normal")
        node.set_font_size(20)
        node.move_to( 60, current_Y+win.scroll["multiuser_users"]+25)
        node.show_text(username+" | "+ip)
        
        current_Y = current_Y + 50
        
        
    # Outputting the layer
    layer.set_source_surface(surface2, x, y)
    layer.paint() 
    
    UI_elements.scroll_area(layer, win, "multiuser_users", 
        x,
        y,
        width, 
        height,
        current_Y,
        bar=True,
        mmb=True)
    
    
    
    # At the bottom I want to have a little multiuser icon with the count of users.
    # then a user icon and a name selection.
    
    UI_elements.image(layer, win, 
        "settings/themes/"+win.settings["Theme"]+"/icons/multiuser.png",
        x,
        y+height+5,
        40,
        40)
    
    # The little count thing at the corner 
    if win.multiuser["users"]:
        count = str(len(win.multiuser["users"]))
        
        UI_color.set(layer, win, "node_background")
        UI_elements.roundrect(layer, win,
            x+25,
            y+height, 
            len(count)*12+6,
            25,
            5)
        layer.fill()
        UI_color.set(layer, win, "text_normal")
        layer.set_font_size(20)
        layer.move_to(x+28,y+height+20)
        layer.show_text(count)
    
    
    # Documentation entry
    def do():
        def after(win, var):
           pass
        
        studio_dialogs.help(win, "help", after, SEARCH=talk.text("documentation_multiuser"))
    
    UI_elements.roundrect(layer, win,
        win.current["w"]/3*2-160,
        win.current["h"]-120, 
        40,
        40,
        10,
        do,
        icon="question")
    
    # CANCEl
    
    def do():
        win.url = "story_editor"
        
    UI_elements.roundrect(layer, win, 
        win.current["w"]/3*2-120,
        win.current["h"]-120,
        40,
        40,
        10,
        button=do,
        icon="cancel",
        tip=talk.text("cancel"))
    
    # Short cut ESC
    if 65307 in win.current["keys"] and not win.textactive:
        do()    
    
     
     
    ########## THE MESSANGER APP ON THE RIGHT ##########
     
    # I'm creating a layer for it just because it needs a clipping.
    
    x = win.current["w"]/3*2-50
    y = 90
    width = win.current["w"]/3-40
    height = win.current["h"]-220
    
    
    # Making the layer
    surface2 = cairo.ImageSurface(cairo.FORMAT_ARGB32, int(width), int(height))
    node = cairo.Context(surface2)
    node.select_font_face("Monospace", cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
    
    # Clip
    UI_elements.roundrect(node, win,
        0,
        0, 
        width,
        height,
        10,
        fill=False)
    node.clip()
    
    # Background tester
    #UI_color.set(node, win, "dark_overdrop")
    #node.rectangle(0,0,width, height)
    #node.fill()
    
    
    # So here I want to present all the messages by all the users.
    if "multiuser_messages" not in win.scroll:
        win.scroll["multiuser_messages"] = 0
    
    current_Y = 10
    
    for message in win.multiuser["messages"]:
        
        # let's get the name of the user
        username = message[0]
        
        if username == "Multiuser Server":
            continue
        
        # User Icon
        UI_elements.image(node, win, 
            "settings/themes/"+win.settings["Theme"]+"/icons/user.png",
            10,
            current_Y+win.scroll["multiuser_messages"],
            40,
            40)
        
        UI_color.set(node, win, "text_normal")
        node.set_font_size(20)
        node.move_to(60,
            current_Y+win.scroll["multiuser_messages"]+25)
        node.show_text(username)
        
        current_Y = current_Y + 50
        
        # Now the message it self going to need to have line breaks. For this
        # we are going to make similar rendering to the one in the script
        # writer. But simpler.
        
        tileX = 10
        
        for word in message[1].split(" "):
            
            
            if tileX + len(word)*12+12 > width-10:
                tileX = 10
                current_Y = current_Y + 30
            
            UI_color.set(node, win, "text_normal")
            node.set_font_size(20)
            node.move_to(tileX,
                current_Y+win.scroll["multiuser_messages"]+25)
            node.show_text(word)
            
            tileX = tileX + len(word)*12+12
            
        current_Y = current_Y + 50
    
    # Outputting the layer
    layer.set_source_surface(surface2, x, y)
    layer.paint() 
    
    UI_elements.scroll_area(layer, win, "multiuser_messages", 
        x,
        y,
        width, 
        height,
        current_Y,
        bar=True,
        mmb=True)
    
    # So here after the messages I want to make a little input for the new
    # message and a send button
    
    UI_elements.text(layer, win, "multiuser_message",
        x,
        y+height+5,
        width-50,
        40)
    
    # Send button
    
    def do():
        
        if win.text["multiuser_message"]["text"]:
            win.multiuser["request"] = ["message", win.text["multiuser_message"]["text"]]
            win.text["multiuser_message"]["text"] = ""
        
    UI_elements.roundrect(layer, win, 
        x+width-40,
        y+height+5,
        40,
        40,
        10,
        button=do,
        icon="send")
    
    # ENTER
    if 65293 in win.current["keys"]:
        do()
        win.current["keys"] = []
    
    return surface
