import time
import sublime
from sublime_plugin import TextCommand, EventListener

from ..git_command import GitCommand


class GsStatusBarEventListener(EventListener):
    # Note: `on_activated` is registered in global_events.py
    def on_new_async(self, view):
        view.run_command("gs_update_status_bar")

    def on_post_save(self, view):
        view.run_command("gs_update_status_bar")


last_execution = 0
update_status_bar_soon = False


def view_is_transient(view):
    """Return whether a view can be considered 'transient'.

    We especially want to exclude widgets and preview views.
    """

    # 'Detached' (already closed) views and previews don't have
    # a window.
    window = view.window()
    if not window:
        return True

    if view.settings().get('is_widget'):
        return True

    return False


class GsUpdateStatusBarCommand(TextCommand, GitCommand):

    """
    Update the short Git status in the Sublime status bar.
    """

    def run(self, edit):
        if view_is_transient(self.view):
            return

        global last_execution, update_status_bar_soon
        if self.savvy_settings.get("git_status_in_status_bar"):

            millisec = int(round(time.time() * 1000))
            # If we updated to less then 100 ms we don't need to update now but
            # should update in 100 ms in case of current file change.
            #
            # So if this get called 4 timer with 20 ms in between each call
            # it will only update twice. Once at time 0 and one at time 100
            # even if it got called at 0, 20, 40, 60 and 80.

            if millisec - 100 > last_execution:
                sublime.set_timeout_async(self.run_async, 0)
            else:
                if not update_status_bar_soon:
                    update_status_bar_soon = True
                    sublime.set_timeout_async(self.run_async, 100)

            last_execution = int(round(time.time() * 1000))

    def run_async(self):
        # Ignore all possible errors
        try:
            self.get_repo_path(offer_init=False)
            short_status = self.get_branch_status_short()
            self.view.set_status("gitsavvy-repo-status", short_status)
        except Exception:
            self.view.erase_status("gitsavvy-repo-status")

        global update_status_bar_soon
        update_status_bar_soon = False

from sublime_plugin import TextCommand, EventListener

from ..git_command import GitCommand
from ..runtime import enqueue_on_worker, throttled


class GsStatusBarEventListener(EventListener):
    # Note: `on_activated` is registered in global_events.py
    def on_new(self, view):
        view.run_command("gs_update_status_bar")

    def on_post_save(self, view):
        view.run_command("gs_update_status_bar")


def view_is_transient(view):
    """Return whether a view can be considered 'transient'.

    We especially want to exclude widgets and preview views.
    """

    # 'Detached' (already closed) views and previews don't have
    # a window.
    window = view.window()
    if not window:
        return True

    if view.settings().get('is_widget'):
        return True

    return False


class GsUpdateStatusBarCommand(TextCommand, GitCommand):

    """
    Update the short Git status in the Sublime status bar.
    """

    def run(self, edit):
        enqueue_on_worker(throttled(self.run_impl, self.view))

    def run_impl(self, view):
        if view_is_transient(view):
            return

        if not self.savvy_settings.get("git_status_in_status_bar"):
            return

        # Ignore all possible errors
        try:
            self.get_repo_path(offer_init=False)
            short_status = self.get_branch_status_short()
            self.view.set_status("gitsavvy-repo-status", short_status)
        except Exception:
            self.view.erase_status("gitsavvy-repo-status")

Rewrite throttler for the status bar