import ui
import chr
import dbg
import app
import background
import math
import time
import sys

def FindModuleByAttributes(attributes, fallback_name=None):
    for mod_name, mod in sys.modules.items():
        if mod is None:
            continue
        if all(hasattr(mod, attr) for attr in attributes):
            return mod
    if fallback_name:
        try:
            return __import__(fallback_name)
        except ImportError:
            pass
    return None

GLHelper              = FindModuleByAttributes(['GetTime', 'AppendChat'], 'GLHelper')
GLList                = FindModuleByAttributes(['GetObjectList'], 'GLList')
GLPlayer              = FindModuleByAttributes(['GetName', 'IsOnline'], 'GLPlayer')
net                   = FindModuleByAttributes(['SendWhisperPacket', 'SendChatPacket'], 'YIpHBGRm')

def SafeImport(name):
    try: return __import__(name)
    except: return None

GLPythonNetworkStream = SafeImport('GLPythonNetworkStream')
GLPythonPlayer        = SafeImport('GLPythonPlayer')
GLPythonShop          = SafeImport('GLPythonShop')
GLPythonSafeBox       = SafeImport('GLPythonSafeBox')

MESSAGE = "Hi, can i have 10kk???"
DELAY = 1000
DELAY_CHAT = 1000
DELAY_ALL_CHAT = 15000
PLAYER_LIST = []

class WhisperBotGui(ui.BoardWithTitleBar):
    def __init__(self):
        ui.BoardWithTitleBar.__init__(self)
        self.AddFlag("movable")
        self.AddFlag("float")
        self.SetPosition(200, 150)
        self.SetSize(520, 160)
        self.SetTitleName("Whisper Bot - Powered by GLBot++")
        self.UI = UI()

        # Left Panel - Settings
        self.WhisperBotStateLabe2 = self.UI.Label(self, 20, 30, "Message")
        self.WhisperBotMessageText = self.UI.EditLine(self, MESSAGE, 20, 50, 200, 17, 70)
        self.WhisperBotButton = self.UI.Button(self, 'Start', '', 230, 50, self.WhisperBotButtonFunction, "large")

        self.SendChatPacketStatus = False
        self.SendChatPacketCheckbox = self.UI.CheckBox(self, "Send this message on chat", 20, 85, self.ToggleSendChatPacket)

        self.WhisperBotStateLabel = self.UI.Label(self, 20, 125, "State : Ready")

        # Right Panel - Dynamic Target List
        self.ListTitle = self.UI.Label(self, 350, 30, "Target Players List")
        self.ListTitle.SetPackedFontColor(0xfffcc419)

        self.ListBar, self.PlayerListBox = self.UI.ListBoxEx(self, 350, 50, 150, 95)

        self.GetPlayerList()

        current_time = GLHelper.GetTime() if GLHelper else 0
        self.Tick = current_time
        self.Tick2 = current_time
        self.Tick3 = current_time
        self.State = False
        self.Show()

    def WhisperBotButtonFunction(self):
        if not self.State:
            self.State = True
            self.WhisperBotButton.SetText("Stop")
            self.Log("Whisper Bot Started.")
        else:
            self.State = False
            self.WhisperBotButton.SetText("Start")
            self.WhisperBotStateLabel.SetText("State : Stopped")
            self.Log("Whisper Bot Stopped.")

    def ToggleSendChatPacket(self):
        self.SendChatPacketStatus = not self.SendChatPacketStatus

    def Log(self, message):
        if GLHelper:
            GLHelper.AppendChat(7, "|cffDA70D6[Whisper Bot - Log] - |cff00C78C" + str(message))

    def UpdatePlayerListBox(self):
        self.PlayerListBox.RemoveAllItems()
        for name in PLAYER_LIST:
            txt = ui.TextLine()
            txt.SetText(name)
            self.PlayerListBox.AppendItem(txt)

    def GetPlayerList(self):
        if not GLList or not GLPlayer:
            return
        objectList = GLList.GetObjectList(300)
        myName = GLPlayer.GetName()

        eklenen_var_mi = False
        for obj in objectList:
            if obj['InstanceType'] == 6 and obj['Name'] != myName:
                if obj['Name'] not in PLAYER_LIST:
                    PLAYER_LIST.append(obj['Name'])
                    eklenen_var_mi = True

        if eklenen_var_mi:
            self.UpdatePlayerListBox()

    def OnUpdate(self):
        if not GLPlayer or not GLHelper or not net:
            return

        if GLPlayer.IsOnline() and self.State:
            current_time = GLHelper.GetTime()

            if current_time - self.Tick >= DELAY:
                self.Tick = current_time
                if len(PLAYER_LIST) <= 0:
                    self.GetPlayerList()
                    if len(PLAYER_LIST) <= 0:
                        self.WhisperBotStateLabel.SetText("State : No players found around!")
                        self.PlayerListBox.RemoveAllItems()
                else:
                    name = PLAYER_LIST[0]
                    self.WhisperBotStateLabel.SetText("Sending -> " + str(name) + " (%d left)" % len(PLAYER_LIST))

                    msg = self.WhisperBotMessageText[1].GetText()
                    try:
                        msg = msg.encode("utf-8").decode("cp1254")
                    except:
                        pass

                    net.SendWhisperPacket(name, msg, 31)
                    PLAYER_LIST.pop(0)

                    self.UpdatePlayerListBox()

            if self.SendChatPacketStatus:
                if current_time - self.Tick2 >= DELAY_CHAT:
                    self.Tick2 = current_time
                    net.SendChatPacket(MESSAGE, 0, 31)

                if current_time - self.Tick3 >= DELAY_ALL_CHAT:
                    self.Tick3 = current_time
                    net.SendChatPacket(MESSAGE, 6, 31)

class UI:
    def Button(self, parent, buttonName, tooltipText, x, y, func, str):
        button = ui.Button()
        button.SetParent(parent)
        button.SetPosition(x, y)
        if str == "big":
            button.SetUpVisual("d:/ymir work/ui/public/Big_Button_01.sub")
            button.SetOverVisual("d:/ymir work/ui/public/Big_Button_02.sub")
            button.SetDownVisual("d:/ymir work/ui/public/Big_Button_03.sub")
        elif str == "large":
            button.SetUpVisual("d:/ymir work/ui/public/large_Button_01.sub")
            button.SetOverVisual("d:/ymir work/ui/public/large_Button_02.sub")
            button.SetDownVisual("d:/ymir work/ui/public/large_Button_03.sub")
        elif str == "small":
            button.SetUpVisual("d:/ymir work/ui/public/Small_Button_01.sub")
            button.SetOverVisual("d:/ymir work/ui/public/Small_Button_02.sub")
            button.SetDownVisual("d:/ymir work/ui/public/Small_Button_03.sub")
        button.SetText(buttonName)
        button.SetToolTipText(tooltipText)
        button.Show()
        button.SetEvent(func)
        return button

    def ToggleButton(self, parent, buttonName, tooltipText, x, y, funcUp, funcDown, str):
        button = ui.ToggleButton()
        button.SetParent(parent)
        button.SetPosition(x, y)
        if str == "big":
            button.SetUpVisual("d:/ymir work/ui/public/Big_Button_01.sub")
            button.SetOverVisual("d:/ymir work/ui/public/Big_Button_02.sub")
            button.SetDownVisual("d:/ymir work/ui/public/Big_Button_03.sub")
        elif str == "large":
            button.SetUpVisual("d:/ymir work/ui/public/large_Button_01.sub")
            button.SetOverVisual("d:/ymir work/ui/public/large_Button_02.sub")
            button.SetDownVisual("d:/ymir work/ui/public/large_Button_03.sub")
        elif str == "middle":
            button.SetUpVisual("d:/ymir work/ui/public/middle_Button_01.sub")
            button.SetOverVisual("d:/ymir work/ui/public/middle_Button_02.sub")
            button.SetDownVisual("d:/ymir work/ui/public/middle_Button_03.sub")
        elif str == "small":
            button.SetUpVisual("d:/ymir work/ui/public/Small_Button_01.sub")
            button.SetOverVisual("d:/ymir work/ui/public/Small_Button_02.sub")
            button.SetDownVisual("d:/ymir work/ui/public/Small_Button_03.sub")
        button.SetText(buttonName)
        button.SetToolTipText(tooltipText)
        button.Show()
        button.SetToggleUpEvent(funcUp)
        button.SetToggleDownEvent(funcDown)
        return button

    def EditLine(self, parent, editlineText, x, y, width, heigh, max):
        SlotBar = ui.SlotBar()
        SlotBar.SetParent(parent)
        SlotBar.SetSize(width, heigh)
        SlotBar.SetPosition(x, y)
        SlotBar.Show()
        Value = ui.EditLine()
        Value.SetParent(SlotBar)
        Value.SetSize(width, heigh)
        Value.SetPosition(5, 1)
        Value.SetMax(max)
        Value.SetText(editlineText)
        Value.Show()
        return SlotBar, Value

    def Label(self, parent, x, y, text):
        Label = ui.TextLine()
        Label.SetParent(parent)
        Label.SetPosition(x, y)
        Label.SetText(text)
        Label.Show()
        return Label

    def SliderBar(self, parent, sliderPos, func, x, y):
        Slider = ui.SliderBar()
        if parent != None:
            Slider.SetParent(parent)
        Slider.SetPosition(x, y)
        Slider.SetSliderPos(sliderPos / 100)
        Slider.Show()
        Slider.SetEvent(func)
        return Slider

    def ListBoxEx(self, parent, x, y, width, heigh):
        bar = ui.Bar()
        if parent != None:
            bar.SetParent(parent)
        bar.SetPosition(x, y)
        bar.SetSize(width, heigh)
        bar.SetColor(1996488704)
        bar.Show()
        ListBox = ui.ListBoxEx()
        ListBox.SetParent(bar)
        ListBox.SetPosition(0, 0)
        ListBox.SetSize(width, heigh)
        ListBox.SetViewItemCount(heigh / 20)
        ListBox.Show()
        scroll = ui.ScrollBar()
        scroll.SetParent(bar)
        scroll.SetPosition(width - 15, 0)
        scroll.SetScrollBarSize(heigh)
        scroll.Show()
        ListBox.SetScrollBar(scroll)
        return (bar, ListBox)

    def CheckBox(self, parent, text, x, y, func):
        checkBox = ui.ToggleButton()
        checkBox.SetParent(parent)
        checkBox.SetPosition(x, y)
        checkBox.SetUpVisual("d:/ymir work/ui/public/middle_Button_01.sub")
        checkBox.SetOverVisual("d:/ymir work/ui/public/middle_Button_02.sub")
        checkBox.SetDownVisual("d:/ymir work/ui/public/middle_Button_03.sub")
        checkBox.SetText(text)
        checkBox.Show()
        checkBox.SetToggleUpEvent(func)
        checkBox.SetToggleDownEvent(func)
        return checkBox

try: whisperBot.Close()
except: pass
whisperBot = WhisperBotGui()
