# Copyright (c) 2014, Guillermo López-Anglada. Please see the AUTHORS file for details.
# All rights reserved. Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.)

import sublime

import os

from .sublime import after


class OutputPanel(object):
    """Manages an ST output panel.

    Can be used as a file-like object.
    """

    def __init__(self, name,
                 base_dir=None,
                 syntax='Packages/Text/Plain text.tmLanguage',
                 **kwargs):
        """
        @name
          This panel's name.
        @base_dir
          Directory used to look files matched by regular expressions.
        @syntax:
          This panel's syntax.
        @kwargs
          Any number of settings to set in the underlying view via `.set()`.

          Common settings:
            - result_file_regex
            - result_line_regex
            - word_wrap
            - line_numbers
            - gutter
            - scroll_past_end
        """

        self.name = name
        self.window = sublime.active_window()

        if not hasattr(self, 'view'):
            # Try not to call get_output_panel until the regexes are assigned
            self.view = self.window.create_output_panel(self.name)

        # Default to the current file directory
        if (not base_dir and
                self.window.active_view() and
                self.window.active_view().file_name()):
            base_dir = os.path.dirname(self.window.active_view().file_name())

        self.set('result_base_dir', base_dir)
        self.set('syntax', syntax)

        self.set('result_file_regex', '')
        self.set('result_line_regex', '')
        self.set('word_wrap', False)
        self.set('line_numbers', False)
        self.set('gutter', False)
        self.set('scroll_past_end', False)

    def set(self, name, value):
        self.view.settings().set(name, value)

    def _clean_text(self, text):
        return text.replace('\r', '')

    def write(self, text):
        assert isinstance(text, str), 'must pass decoded text data'
        text = self._clean_text(text)
        fun = lambda: self.view.run_command('append', {'characters': text, 'force': True, 'scroll_to_end': True})
        after(0, fun)

    def flush(self):
        pass

    def show(self):
        # Call create_output_panel a second time after assigning the above
        # settings, so that it'll be picked up as a result buffer
        self.window.create_output_panel(self.name)
        self.window.run_command('show_panel', {
            'panel': 'output.' + self.name})

    def close(self):
        pass


class ErrorPanel(object):
    def __init__(self):
        self.panel = OutputPanel('dart.info')
        self.panel.write('=' * 80)
        self.panel.write('\n')
        self.panel.write("Dart - Something's not quite right\n")
        self.panel.write('=' * 80)
        self.panel.write('\n')
        self.panel.write('\n')

    def write(self, text):
        self.panel.write(text)

    def show(self):
        self.panel.show()

@@ -210,22 +210,44 @@
 .)%0A%0A
-import sublime
+from threading import Lock%0Aimport os
 %0A%0Aim
@@ -251,18 +251,23 @@
 %0Aimport 
-o
 s
+ublime
 %0A%0Afrom .
@@ -312,24 +312,50 @@
 el(object):%0A
+    _write_lock = Lock()%0A%0A
     %22%22%22Manag
@@ -2163,49 +2163,58 @@
     
-text = s
+with OutputPan
 el
-f
 ._
-clean_text(text)%0A        fun
+write_lock:%0A            do_write
  = l
@@ -2257,67 +2257,332 @@
 ', %7B
-'characters': text, 'force': True, 'scroll_to_end': True%7D)%0A
+%0A                'characters': self._clean_text(text),%0A                'force': True,%0A                'scroll_to_end': True,%0A                %7D)%0A            # XXX: If we don't sync with the GUI thread here, the command above%0A            # won't work if this method is called from .set_timeout_async().%0A            # BUG?%0A    
     
@@ -2598,11 +2598,16 @@
 (0, 
-fun
+do_write
 )%0A%0A 
@@ -2640,16 +2640,324 @@
   pass%0A%0A
+    def hide(self):%0A        # Call create_output_panel a second time after assigning the above%0A        # settings, so that it'll be picked up as a result buffer%0A        # self.window.create_output_panel(self.name)%0A        self.window.run_command('hide_panel', %7B%0A            'panel': 'output.' + self.name%7D)%0A%0A
     def 

synchronize panel writing with UI thread