import wx.richtext
from modules.interpreter.interactive_interpreter import Interpreter
import sys
import wx
from datetime import datetime
import time
class PanelConsole(wx.richtext.RichTextCtrl):
  def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    self.SetEditable(False)
    self.scene = None
    self.SetBackgroundColour(wx.Colour(33, 33, 33))
    self.BeginTextColour(wx.Colour(233, 233, 233))
    # self.command_interpreter = CommandInterpreter(self, parent, self.scene)
    self.command_interpreter = Interpreter(self, self.GetParent())
    self.WriteText("-=AVID Console=-\n")
    self.allow_interaction = True

  def update_scene(self):
    if hasattr(self, 'get_scene_callback') and callable(self.get_scene_callback):
      self.scene = self.get_scene_callback()
    
    # self.command_interpreter.set_scene(self.scene)

  def on_run_script(self, event):
    dia = wx.FileDialog(self, "Open Script", "", "", "PY file (*.py)|*.py", wx.FD_OPEN | wx.FD_FILE_MUST_EXIST)
    result = dia.ShowModal()

    if result == wx.ID_OK:
      f_path = dia.GetPath().replace("\\", "/")
      try:
        self.command_interpreter.commands = [f'exec(open("{f_path}").read())']
      except Exception as e:
        print(e)
  
      
  def log(self, to_add, timestamp=True, color=wx.WHITE):
    self.Freeze()
    formatted_timestamp = datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S')
    msg = to_add.split('\n')
    
    # attr = wx.TextAttr()
    # attr.SetTextColour(wx.Colour(233, 233, 233))
    self.BeginTextColour(color)

    for line in msg:
      if timestamp:
        self.WriteText("\n" + str(formatted_timestamp) + ": " + line)
      else:
        self.AppendText("\n" + line)

    self.EndTextColour()
    self.Refresh()
    self.Thaw()
    self.scroll_to_end()

  def scroll_to_end(self):
    self.SetInsertionPointEnd()
    self.ShowPosition(self.GetInsertionPoint())

  def on_key_up(self, event):
    s = self.text_command.GetValue()
    curpos = self.text_command.GetInsertionPoint()
    command = s[4:]
    new_ps = sys.ps1 if s.startswith(sys.ps1[:3]) else sys.ps2
    
    key_code = event.GetKeyCode()
    if key_code == wx.WXK_UP and self.command_interpreter.prev_commands:
      command = self.command_interpreter.get_prev_command(-1)
      curpos = len(new_ps) + len(command)
    elif key_code == wx.WXK_DOWN and self.command_interpreter.prev_commands:
      command = self.command_interpreter.get_prev_command(1)
      curpos = len(new_ps) + len(command)
    
    self.text_command.SetValue(new_ps + command)
    self.text_command.SetInsertionPoint(max(curpos, len(new_ps)))

    super().on_key_up(event)

  def on_key_down(self,event):  
    s = self.text_command.GetValue()
    curpos = self.text_command.GetInsertionPoint()

    key_code = event.GetKeyCode()
    if key_code == wx.WXK_HOME:
      # don't let curser go before ps string
      self.text_command.SetInsertionPoint(4)
    elif key_code == wx.WXK_TAB:
      # don't let 'tab' key press change the focus
      s = s[:curpos] + '\t' + s[curpos:]
      self.text_command.SetValue(s)
      self.text_command.SetInsertionPoint(curpos+4)
    elif key_code == wx.WXK_BACK and curpos <= 4:
      # don't let backspace delete ps string
      pass
    else:  
      super().on_key_up(event)
    

  def on_left_up(self, event):
    if self.text_command.GetInsertionPoint() < 4:
      self.text_command.SetInsertionPoint(4)
    else:
      super().on_left_up(event)
  
  def on_command_enter(self, event):
    s = self.text_command.GetValue()
    command = s[4:]
    
    self.log(s, color=wx.BLUE)
    self.command_interpreter.commands.append(command)

    # store command
    self.command_interpreter.prev_commands.append(command)
    self.command_interpreter.prev_index = 0
   
  def SetInteraction(self, flag: bool):
    self.allow_interaction = flag
  
  def on_log_click(self, event):
    if self.allow_interaction:
      event.Skip()