
import websocket
import json
import requests
import socket
import tkinter as tk
from tkinter import *
import threading
import obspython as obs

hostname = socket.gethostname()
IPAddr = socket.gethostbyname(hostname)

#https://github.com/upgradeQ/OBS-Studio-Python-Scripting-Cheatsheet-obspython-Examples-of-API#print-all-source-settings-and-filter-names

connectionIP = '192.168.1.154'
count = -1
songs = ''
bibles = ''
impress = ''
pictures = ''
medias = ''
custom = ''
boolRun = False
currentItem = ''

def on_message(ws, message):
    #print(message)
    messageProcess()        

def on_error(ws, error):
    print(error)

def on_close(ws, close_status_code, close_msg):
    print("### closed ###")

def on_open(ws):
    print("Opened connection")

def buttonClick(widget):
    global boolRun
    boolRun = not boolRun
    if boolRun:
        widget.configure(text = "controlled by OpenLP")
        widget.configure(bg = "#ff0000")
    else:
        widget.configure(text = "NOT controlled by OpenLP")
        widget.configure(bg = "#00ff00")

def startWsConn():
    wsapp = websocket.WebSocketApp('ws://{}:4317'.format(IPAddr),
                                  on_open=on_open,
                                  on_message=on_message,
                                  on_error=on_error,
                                  on_close=on_close)
    print("start")
    wsapp.run_forever()
    print("run")
    
class Application(tk.Frame):

    def __init__(self, master=None):
        tk.Frame.__init__(self, master)
        self.config(bg="grey")
        self.pack()
        self.master.attributes('-alpha', 0.4) # window opacity
        self.master.overrideredirect(True)

        # changes the window default opacity 0 to 1
        win_opacity = 0.8

        # calculate the screen width based on the resolution
        screen_width = self.master.winfo_screenwidth()
        screen_x= int(screen_width/2)

        self.master.attributes('-alpha', win_opacity) # window opacity
        self.master.configure(bg='grey') # window color
        self.master.overrideredirect(1) # borderless window
        self.master.attributes('-topmost', True) # keep always on top
        self.master.geometry(f'{240}x{28}+{screen_x}+{0}') # window size(x) and position

        button1 = tk.Button(self, command=lambda: buttonClick(button1), text= "NOT controlled by OpenLP")
        button1.configure(bg = "#00ff00")
        button1.pack()

def messageProcess():
    print("time ticker")
    global thd1
    if not thd1.is_alive():
        thd1.start()
    global boolRun
    if boolRun:
        global connectionIP
        global currentItem
        global count
        count = count + 1
        print(count)
        try:
            response = requests.get('http://{}:4316/api/v2/controller/live-item'.format(connectionIP))
            message = json.loads(response.content)
            openLpItem = message.get('name') #type of item shown in OpenLP
            if (openLpItem != None and currentItem != openLpItem):
                currentItem = openLpItem
                global bibles
                global songs
                global impress
                global pictures
                global medias
                global custom
                scenes = obs.obs_frontend_get_scenes()
                print(1)
                for scene in scenes:
                    sceneName = obs.obs_source_get_name(scene)
                    if openLpItem == 'bibles' and bibles != "":
                        if sceneName == bibles:
                            obs.obs_frontend_set_current_scene(scene)
                            break
                    elif openLpItem == 'songs' and songs != "":
                        if sceneName == songs:
                            obs.obs_frontend_set_current_scene(scene)
                            break
                    elif openLpItem == 'presentations' and impress != "":
                        if sceneName == impress:
                            obs.obs_frontend_set_current_scene(scene)
                            break
                    elif openLpItem == 'images' and pictures != "":
                        if sceneName == pictures:
                            obs.obs_frontend_set_current_scene(scene)
                            break
                    elif openLpItem == 'media' and medias != "":
                        if sceneName == medias:
                            obs.obs_frontend_set_current_scene(scene)
                            break
                    elif openLpItem == 'custom' and custom != "":
                        if sceneName == custom:
                            obs.obs_frontend_set_current_scene(scene)
                            break
                print(2)
        except requests.ConnectionError:
            print("no connection to OpenLP")

# https://obsproject.com/wiki/Scripting-Tutorial-Source-Shake
# Description displayed in the Scripts dialog window
def script_description():
    return """OBS controlled by OpenLP!!>"""

# Called to set default values of data settings
def script_defaults(settings):
    global connectionIP
    obs.obs_data_set_default_string(settings, "connection", connectionIP)
    obs.obs_data_set_default_string(settings, "sceneSong", "songs")
    obs.obs_data_set_default_string(settings, "sceneBible", "bibles")
    obs.obs_data_set_default_string(settings, "sceneImpress", "impress")
    obs.obs_data_set_default_string(settings, "scenePicture", "pictures")
    obs.obs_data_set_default_string(settings, "sceneMedia", "medias")
    obs.obs_data_set_default_string(settings, "sceneCustom", "custom")
    obs.obs_data_set_default_bool(settings, "pingOpenLP", False)

# Called to display the properties GUI
def script_properties():
    props = obs.obs_properties_create()
    obs.obs_properties_add_bool(props, "pingOpenLP", "run/not run");
    obs.obs_properties_add_text(props, "connection", "Connection IP", obs.OBS_TEXT_DEFAULT)
    obs.obs_properties_add_text(props, "sceneSong", "song scene", obs.OBS_TEXT_DEFAULT)
    obs.obs_properties_add_text(props, "sceneBible", "bible scene", obs.OBS_TEXT_DEFAULT)
    obs.obs_properties_add_text(props, "sceneImpress", "presentation scene", obs.OBS_TEXT_DEFAULT)
    obs.obs_properties_add_text(props, "scenePicture", "picture scene", obs.OBS_TEXT_DEFAULT)
    obs.obs_properties_add_text(props, "sceneMedia", "Media scene", obs.OBS_TEXT_DEFAULT)
    obs.obs_properties_add_text(props, "sceneCustom", "custom scene", obs.OBS_TEXT_DEFAULT)
    return props

# Called at script load
def script_load(settings):
    global connectionIP
    global bibles
    global songs
    global impress
    global pictures
    global medias
    global custom

    hostname = socket.gethostname()
    connectionIP = socket.gethostbyname(hostname)
    if connectionIP == '':
        connectionIP = obs.obs_data_get_string(settings, "connection")
    songs = obs.obs_data_get_string(settings, "sceneSong")
    bibles = obs.obs_data_get_string(settings, "sceneBible")
    impress = obs.obs_data_get_string(settings, "sceneImpress")
    pictures = obs.obs_data_get_string(settings, "scenePicture")
    medias = obs.obs_data_get_string(settings, "sceneMedia")
    custom = obs.obs_data_get_string(settings, "sceneCustom")
    boolRun = False
    #boolRun = obs.obs_data_get_bool(settings, "pingOpenLP")
    #if boolRun:
    #    obs.timer_add(time_ticker, 2000)
    #    print("running")
    #else:
    #    obs.timer_remove(time_ticker)
    #    print("stopped")
    print("IP", connectionIP)

# Called at script unload
def script_unload():
    #obs.timer_remove(time_ticker)
    global thd1
    if thd1.is_alive():
        thd1.stop()
    global thd2
    if thd2.is_alive():
        thd2.stop()
    print("unloaded")
    
# Called at updating settings
def script_update(settings):
    global connectionIP
    global bibles
    global songs
    global impress
    global pictures
    global medias
    global custom
    global boolRun
    hostname = socket.gethostname()
    connectionIP = socket.gethostbyname(hostname)
    if connectionIP == '':
        connectionIP = obs.obs_data_get_string(settings, "connection")
    songs = obs.obs_data_get_string(settings, "sceneSong")
    bibles = obs.obs_data_get_string(settings, "sceneBible")
    impress = obs.obs_data_get_string(settings, "sceneImpress")
    pictures = obs.obs_data_get_string(settings, "scenePicture")
    medias = obs.obs_data_get_string(settings, "sceneMedia")
    custom = obs.obs_data_get_string(settings, "sceneCustom")
    boolRun = obs.obs_data_get_bool(settings, "pingOpenLP")
    print("update IP", connectionIP)

def runtk():  # runs in background thread
    global app
    app = Application()
    app.master.title('Sample application')
    app.mainloop()

thd1 = threading.Thread(target=runtk)   # gui thread
thd1.daemon = True  # background thread will exit if main thread exits
thd1.start()

thd2 = threading.Thread(target=startWsConn)   # gui thread
thd2.daemon = True  # background thread will exit if main thread exits
thd2.start()