from datetime import datetime
import obspython as obs

source_name = ""
scene_name = ""
switch_scene = True
diff = 0


def format_time(sec):
    mins = sec // 60
    sec = sec % 60
    hours = mins // 60
    mins = mins % 60

    return "{:02d}:{:02d}:{:02d}".format(hours, mins, sec)


def stopwatch():
    global source_name
    global diff
    global switch_scene
    global scene_name

    now = datetime.now()
    source = obs.obs_get_source_by_name(source_name)
    diff = end_countdown_time-(int(now.strftime("%H"))*3600)-(int(now.strftime("%M"))*60)-int(now.strftime("%S"))
    if diff == 0:
        obs.timer_remove(stopwatch)
        obs.remove_current_callback()
        if switch_scene == True:
            if scene_name != "":
                obs.obs_frontend_set_current_scene(obs.obs_get_source_by_name(scene_name))
    elif diff < 0:
        obs.timer_remove(stopwatch)
        obs.remove_current_callback()
        diff = 0
    try:
        settings = obs.obs_data_create()
        obs.obs_data_set_string(settings, "text", str(format_time(int(diff))))
        obs.obs_source_update(source, settings)
        obs.obs_data_release(settings)
    except UnboundLocalError:
        pass


def scene_updater():
    global source_name

    source = obs.obs_get_source_by_name(source_name)
    obs.obs_source_release(source)


def settings_updater(settings):
    global source_name
    global end_countdown_time
    global diff
    global switch_scene
    global scene_name

    source_name = obs.obs_data_get_string(settings, "source")
    end_countdown_time = (int(obs.obs_data_get_int(settings, "end_countdown_hour"))*3600) + (int(obs.obs_data_get_int(settings, "end_countdown_minute"))*60)
    switch_scene = obs.obs_data_get_bool(settings, "switch_scene")
    scene_name = obs.obs_data_get_string(settings, "end_scene")


def restart_timer_pressed(props, prop):
    global settings_global

    obs.timer_remove(stopwatch)
    obs.timer_add(stopwatch, 200)
    settings_updater(settings_global)


def script_description():
    return '{:s}'.format('\u0332'.join('Countdown To Time')) + "\nText Source: The text source where it shows the timer\nLive update: If enabled it will update the properties live to the timer\nEnd hour: The hour mark in 24-hour format on which the timer ends\nEnd minute: The minute mark on which the timer ends\nSwitch to scene: If enabled it will switch to the selected scene at the end of the timer\nEnd scene: The scene it will switch to if 'Switch to scene' is enabled\nUpdate / (Re)start Timer: When pressed it will update the properties if 'Live update' is disabled and will (re)start the timer if it hit the 0 mark"


def script_update(settings):
    global settings_global
    settings_global = settings

    if obs.obs_data_get_bool(settings, "live_update"):
        settings_updater(settings)
    obs.timer_remove(scene_updater)
    if source_name != "":
        obs.timer_add(scene_updater, 1000)


def script_unload():
    obs.timer_remove(stopwatch)
    obs.timer_remove(scene_updater)


def script_defaults(settings):
    global settings_global
    global switch_scene

    obs.obs_data_set_bool(settings, "live_update", True)
    obs.obs_data_set_bool(settings, "switch_scene", False)

    switch_scene = False
    settings_global = settings


def script_properties():
    props = obs.obs_properties_create()

    p = obs.obs_properties_add_list(props, "source", "Text Source", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)

    obs.obs_properties_add_bool(props, "live_update", "Live update")
    obs.obs_properties_add_int(props, "end_countdown_hour", "End hour:", 0, 23, 1)
    obs.obs_properties_add_int(props, "end_countdown_minute", "End minute:", 0, 59, 1)

    sources = obs.obs_enum_sources()

    if sources is not None:
        for source in sources:
            name = obs.obs_source_get_name(source)
            source_id = obs.obs_source_get_unversioned_id(source)
            if source_id == "text_gdiplus" or source_id == "text_ft2_source":
                name = obs.obs_source_get_name(source)
                obs.obs_property_list_add_string(p, name, name)
        obs.source_list_release(sources)

    obs.obs_properties_add_bool(props, "switch_scene", "Switch to scene")

    s = obs.obs_properties_add_list(props, "end_scene", "End Scene", obs.OBS_COMBO_TYPE_EDITABLE, obs.OBS_COMBO_FORMAT_STRING)

    scenes = obs.obs_frontend_get_scenes()
    if scenes is not None:
        for scene in scenes:
            name = obs.obs_source_get_name(scene)
            obs.obs_property_list_add_string(s, name, name)
        obs.source_list_release(scenes)
        
    obs.obs_properties_add_button(props, "restart_button", "Update / (Re)start Timer", restart_timer_pressed)

    return props