import wx
from enum import Enum

class States(Enum):
  NORMAL = 0
  HOVER = 1
  PRESSED = 2
  DISABLED = 3
class Button(wx.Panel):

  def __init__(self, label, background, font, radius, color=0, font_color = [0, 0, 0], toggle = False, *args, **kw):
    super().__init__(*args, **kw)

   
    self.size = self.GetSize()
    self.text = label
    self.background_color = background
    self.font = font
    self.radius = radius
    self.color = color
    self.states = Enum('States', ['NORMAL', 'HOVER', 'PRESSED', 'DISABLED'])
    self.current_state = self.states.NORMAL
    self.vert_offset = [2,0,int(self.size[1]/12),0]

    self.init_colors()
    self.font_color = [wx.Colour(font_color[0], font_color[1], font_color[2], 255),
                       wx.Colour(font_color[0], font_color[1], font_color[2], 77)]
    self.toggle = False
    self.is_toggle = toggle

    self.Bind(wx.EVT_PAINT, self.OnPaint)
    self.Bind(wx.EVT_ENTER_WINDOW, self.OnEnterWindow)
    self.Bind(wx.EVT_LEAVE_WINDOW, self.OnLeaveWindow)
    self.Bind(wx.EVT_LEFT_DOWN, self.OnMouseDown)
    self.Bind(wx.EVT_LEFT_UP, self.OnMouseUp)

  def init_colors(self):

    normal_color_y = [wx.Colour(252, 177, 57, 255), wx.Colour(0, 0, 0, 38)]         # Standard Color (Yellow50)
    highlight_color_y = [wx.Colour(253, 193, 97, 255), wx.Colour(0, 0, 0, 77)]      # Highlight color (Yellow60)
    pressed_color_y = [wx.Colour(202, 152, 46, 255), wx.Colour(0, 0, 0, 0)]         # Pressed Color (Yellow40)
    disabled_color_y = [wx.Colour(252, 177, 57, 77), wx.Colour(0, 0, 0, 0)]         # Disabled Color (Yellow50)

    y = [normal_color_y, highlight_color_y, pressed_color_y, disabled_color_y]

    normal_color_gn = [wx.Colour(11, 197, 38, 255), wx.Colour(0, 0, 0, 38)]         # Standard Color (Green50)
    highlight_color_gn = [wx.Colour(60, 209, 81, 255), wx.Colour(0, 0, 0, 77)]      # Highlight color (Green60)
    pressed_color_gn = [wx.Colour(9, 158, 30, 255), wx.Colour(0, 0, 0, 0)]          # Pressed Color (Green40)
    disabled_color_gn = [wx.Colour(11, 197, 38, 77), wx.Colour(0, 0, 0, 0)]         # Disabled Color (Green50)    

    gn = [normal_color_gn, highlight_color_gn, pressed_color_gn, disabled_color_gn]

    normal_color_gy = [wx.Colour(144, 144, 144, 255), wx.Colour(0, 0, 0, 38)]       # Standard Color (Neutral60)
    highlight_color_gy = [wx.Colour(172, 172, 172, 255), wx.Colour(0, 0, 0, 77)]    # Highlight color (Neutral70)
    pressed_color_gy = [wx.Colour(116, 116, 116, 255), wx.Colour(0, 0, 0, 0)]       # Pressed Color (Neutral50)
    disabled_color_gy = [wx.Colour(144, 144, 144, 77), wx.Colour(0, 0, 0, 0)]       # Disabled Color (Neutral60)    

    gy = [normal_color_gy, highlight_color_gy, pressed_color_gy, disabled_color_gy]

    normal_color_r = [wx.Colour(251, 110, 82, 255), wx.Colour(0, 0, 0, 38)]         # Standard Color (Red50)
    highlight_color_r = [wx.Colour(252, 139, 117, 255), wx.Colour(0, 0, 0, 77)]     # Highlight color (Red60)
    pressed_color_r = [wx.Colour(201, 88, 66, 255), wx.Colour(0, 0, 0, 0)]          # Pressed Color (Red40)
    disabled_color_r = [wx.Colour(251, 110, 82, 77), wx.Colour(0, 0, 0, 0)]         # Disabled Color (Red50)    

    r = [normal_color_r, highlight_color_r, pressed_color_r, disabled_color_r]

    normal_color_r = [wx.Colour(80, 123, 200, 255), wx.Colour(0, 0, 0, 38)]         # Standard Color (Blue50)
    highlight_color_r = [wx.Colour(115, 149, 211, 255), wx.Colour(0, 0, 0, 77)]     # Highlight color (Blue60)
    pressed_color_r = [wx.Colour(64, 98, 160, 255), wx.Colour(0, 0, 0, 0)]          # Pressed Color (Blue40)
    disabled_color_r = [wx.Colour(80, 123, 200, 77), wx.Colour(0, 0, 0, 0)]         # Disabled Color (Blue50)    

    b = [normal_color_r, highlight_color_r, pressed_color_r, disabled_color_r]

    self.colors_list = [y, gn, gy, r, b]
    

  def OnPaint(self, event):
    dc = wx.BufferedPaintDC(self)
    gc = wx.GraphicsContext.Create(dc)

    back_color = self.colors_list[self.color][self.current_state.value-1][0]
    shadow_color = self.colors_list[self.color][self.current_state.value-1][1]
    font_color = self.font_color[0]
    vert = self.vert_offset[self.current_state.value-1]
    
    if(self.current_state == self.states.DISABLED):
      font_color = self.font_color[1]
    
    # Draw Background Color
    gc.SetBrush(wx.Brush(self.background_color, wx.BRUSHSTYLE_SOLID))
    gc.DrawRectangle(0, 0, self.size[0],self.size[1])

    # Draw Shadow
    gc.SetBrush(wx.Brush(shadow_color, wx.BRUSHSTYLE_SOLID))
    gc.DrawRoundedRectangle(2, 0+vert, self.size[0]-4,self.size[1], self.radius)
    
    if self.toggle:
      gc.SetBrush(wx.Brush(wx.Colour(255, 255, 0), wx.BRUSHSTYLE_TRANSPARENT))  # Transparent fill
      gc.SetPen(wx.Pen(wx.Colour(255, 255, 0), 4))  # Yellow border with thickness 2
      gc.DrawRoundedRectangle(3, 0 + vert, self.size[0] - 6, self.size[1] - 6, self.radius)

    #Draw Button
    gc.SetBrush(wx.Brush(back_color, wx.BRUSHSTYLE_SOLID))
    gc.DrawRoundedRectangle(3, 0+vert, self.size[0]-6,self.size[1]-6, self.radius)
    
    # Set Font
    font = gc.CreateFont(self.font, font_color)
    gc.SetFont(font)

    # Calculate the text dimensions
    text_width, text_height = gc.GetTextExtent(self.text)

    # Calculate the center position
    text_x = (self.size[0] - text_width) // 2
    text_y = (self.size[1]-6 - text_height) // 2

    # Draw the text at the center position
    gc.DrawText(self.text, text_x, text_y+vert)

  def OnEnterWindow(self, event):
    if self.current_state != self.states.DISABLED:
      self.current_state = self.states.HOVER
      self.Refresh()

  def OnLeaveWindow(self, event):
    if self.current_state != self.states.DISABLED:
      self.current_state = self.states.NORMAL
      self.Refresh()

  def OnMouseDown(self, event):
    if self.current_state != self.states.DISABLED:
      self.current_state = self.states.PRESSED
      self.Refresh()

  def OnMouseUp(self, event):
    if self.current_state != self.states.DISABLED and self.is_toggle:
      self.toggle = not self.toggle
      self.Refresh()
    event.Skip()

  def Disable(self):
    self.current_state = self.states.DISABLED

  def Enable(self):
    self.current_state = self.states.NORMAL

  def IsDisabled(self):
    return self.current_state == self.states.DISABLED
  
  def IsToggled(self):
    return self.toggle

  def set_label(self, label):
    self.text = label

