# modified by discorny from url-text by Jim

import obspython as obs
import xml.etree.ElementTree as ET
from os.path import exists

# define variables
url = ""
interval = 100
search_all = False
namespace = ""


# create function to update text
def update_text():
    # no idea why these variables need to be here too... might try without
    global url

    global search_all

    global namespace




    if exists(url) == True and search_all == False:
        # create creates a tree structure in memory set to what i think is a variable
        # no idea how that works but it does
        tree = ET.parse(url)
        # this part is the meat
        # for every child of the root element in the tree structure
        for child in tree.iter():
            if child.tag.startswith("{"+namespace+"}"):
                childelement = child.tag.replace("{"+namespace+"}",'')
            else:
                childelement = child.tag

            # create var 'source' = tag of child of root element, e.g. "%clock%"
            source = obs.obs_get_source_by_name("%" + childelement + "%")
            # create var 'text' = text(attrib) of root element, e.g. "6:55"
            if child.text is not None:
                text = child.text
                # I think obs has a structure for settings, this creates a var with that structure
                settings = obs.obs_data_create()

                # i think this sets a setting in our settings var named "text" to equal our text variable
                # "text" is a front end setting of an obs text source
                obs.obs_data_set_string(settings, "text", text)
                # updates the source with name == to our source var with settings from our settings var
                obs.obs_source_update(source, settings)
                # not exactly sure what this does but i think it might allow for the settings variable
                # to be completely overwritten next time around
                obs.obs_data_release(settings)
    elif exists(url) == True and search_all == True:
        # create creates a tree structure in memory set to what i think is a variable
        # no idea how that works but it does
        tree = ET.parse(url)


        # sets what i think is a variable named root to the root element of the tree
        root = tree.getroot()

        # this part is the meat
        # for every child of the root element in the tree structure
        for child in root.iter():
            # create var 'source' = tag of child of root element, e.g. "%clock%"
            source = obs.obs_get_source_by_name("%" + child.tag + "%")
            # create var 'text' = text(attrib) of root element, e.g. "6:55"
            text = child.text
            # I think obs has a structure for settings, this creates a var with that structure
            settings = obs.obs_data_create()

            # i think this sets a setting in our settings var named "text" to equal our text variable
            # "text" is a front end setting of an obs text source
            obs.obs_data_set_string(settings, "text", text)
            # updates the source with name == to our source var with settings from our settings var
            obs.obs_source_update(source, settings)
            # not exactly sure what this does but i think it might allow for the settings variable
            # to be completely overwritten next time around
            obs.obs_data_release(settings)
    else:
        pass


# creates function for the refresh button that updates runs the updates_text function
# why the button couldn't just run update_text() instead idk
# maybe it makes it something that can run from the properties
def refresh_pressed(props, prop):
    update_text()


# ----------------------------------------
# just a description for obs properties
def script_description():
    return "Looks for text sources with names that match XML tags from Sportzcast LiveXML in %tag% format.\n\nE.g, To get <clock> data, create a new text source named %clock%\n\nBy Jim (modified by discorny)"


def script_update(settings):
    # TIL do i need to tell python what variables to bring in to each function?
    #answer: yes
    global url
    global interval
    global search_all
    global namespace

    url = obs.obs_data_get_string(settings, "url")

    interval = obs.obs_data_get_int(settings, "interval")

    search_all = obs.obs_data_get_bool(settings, "searchall")

    namespace = obs.obs_data_get_string(settings, "namespace")


    obs.timer_remove(update_text)

    if url != "":
        obs.timer_add(update_text, interval)


# sets defaults in obs
def script_defaults(settings):
    global interval
    global search_all
    # sets the default inverval to 10ms
    obs.obs_data_set_default_int(settings, "interval", interval)
    obs.obs_data_set_default_bool(settings, "searchall", search_all)



# creates properties that can be set in the script gui
def script_properties():

    # i think obs has a structure for properties and this creates a var with that structure
    props = obs.obs_properties_create()

    # creates a path type property, adds it to the props var, sets "url" as identifier,
    # displays "File Path", text type, only *.xml files, no default location
    obs.obs_properties_add_path(props, "url", "XML:", obs.OBS_TEXT_DEFAULT, "*.xml", "")

    obs.obs_properties_add_text(props, "namespace", "Namespace:", obs.OBS_TEXT_DEFAULT)

    obs.obs_properties_add_bool(props, "searchall", "Search Whole XML File")

    # creates int property, adds to pros var, sets indentifier to "interval",
    # displays "Update..." in GUI, min 1, max 9999, steps 1
    obs.obs_properties_add_int(props, "interval", "Update Interval (ms)", 1, 9999, 1)

    # creates button, adds to props, indentifier "button", displays "Refresh", runs refresh_pressed()
    obs.obs_properties_add_button(props, "button", "Refresh", refresh_pressed)
    # returns value of props when called
    return props
