import random
bold = "\x02"
italic = "\x1D"
underline = "\x1F"
reverse = "\x16" 	# swap background and foreground colors ("reverse video")
reset = "\x0F"
blue = "\x0302"
green = "\x0303"
red = "\x0304"
grey = "\x0314"

class CommandHelpers():
    def disect_command(self, event):
        trigger = event.arguments[0]
        command = trigger[1:].lower()   #Command without prefix.
        
        # Determine command type.
        if trigger.startswith(self.cmdchar):
            cmdtype = "cmd"
        elif trigger.startswith(self.helpchar):
            cmdtype = "help"
        else:
            cmdtype = False
        
        # Determine where to reply to.
        if event.type == "pubmsg":
            replyto = event.target
        elif event.type == "privmsg":
            replyto = event.source.nick
        else:
            replyto = False
            
        return(cmdtype, trigger, command, replyto)
    
    def ccc(self, command, rights=False, event=False):   # Commandlist colour coding and channel rights filter.
        if rights:
            show = False
            
            if rights["homechan"] == "owner":
                if self.channels[self.homechannel].is_owner(event.source.nick):
                    show = True
            if rights["homechan"] == "admin":
                if self.channels[self.homechannel].is_owner(event.source.nick) or self.channels[self.homechannel].is_admin(event.source.nick):
                    show = True
            if rights["homechan"] == "oper":
                if self.channels[self.homechannel].is_owner(event.source.nick) or self.channels[self.homechannel].is_admin(event.source.nick) or self.channels[self.homechannel].is_oper(event.source.nick):
                    show = True
            if not event.target == self.connection.get_nickname():   # Channel message.
                if rights["chan"] == "owner":
                    if self.channels[event.target].is_owner(event.source.nick):
                        show = True
                if rights["chan"] == "admin":
                    if self.channels[event.target].is_owner(event.source.nick) or self.channels[event.target].is_admin(event.source.nick):
                        show = True
                if rights["chan"] == "oper":
                    if self.channels[event.target].is_owner(event.source.nick) or self.channels[event.target].is_admin(event.source.nick) or self.channels[event.target].is_oper(event.source.nick):
                        show = True
            if show:
                return blue + self.cmdchar + command + grey + ", "
        else:
            return blue + self.cmdchar + command + grey + ", "

class AdminHelpers():
    def get_channelfunctions(self, channel):
        channelfunctions = self.db.one("SELECT autojoin, aggressiveness, join_greeting, statistics_commands, games, chat FROM channels WHERE LOWER(name)=LOWER('" + channel + "') AND network='" + self.network + "'")
        if channelfunctions[0]:
            autojoin = "on"
        else:
            autojoin = "off"
        if channelfunctions[2]:
            joingreet = "on"
        else:
            joingreet = "off"
        if channelfunctions[3]:
            statscmds = "on"
        else:
            statscmds = "off"
        if channelfunctions[4]:
            games = "on"
        else:
            games = "off"""
        if channelfunctions[5]:
            chat = "on"
        else:
            chat = "off"""
        return ("autojoin " + green + autojoin + reset + ", aggressiveness " + green + channelfunctions[1] + reset +  ", join_greeting " + green + joingreet + reset + ", statistics_commands " + green + statscmds + reset + ", games " + green + games + reset + ", chat " + green + chat + reset + ".")
        
    def is_channelfunction(value):
        if value.lower() in ["autojoin", "aggressiveness", "join_greeting",  "statistics_commands",  "games", "chat"]:
            return True
        else:
            return False
    
    def describe_channelfunction(function):
        if function == "autojoin":
            message = "Join the channel automaticly after connecting."
        elif function == "aggressiveness":
            message = "How to respond to kick, ban and mode events. Options: " + blue + "passive" + reset + ", " + blue + "defense_only" + reset + ", " + blue + "equal_retalliation" + reset + ", " + blue + "battlebot" + reset + "."
        elif function == "join_greeting":
            message = "Greet users joining the channel on the first few joins, and later on large amounts."
        elif function == "statistics_commands":
            message = "Enable use of statistics commands."
        elif function == "games":
            message = "Enable use of game commands."
        elif function == "chat":
            message = "Respond to and initiate chat."
        else:
            message = "Sorry, this function has no description yet."
        
        return message
    
    def is_aggressiveness(value):
        if value.lower() in ["passive", "defense_only", "equal_retalliation", "battlebot"]:
            return True
        else:
            return False
        

class GameHelpers():
    def roll_dice(amount, type):
        rolls = []
        for iterations in range(amount):
            rolls.append(random.randint(1, type))
        return rolls
    
    def get_info(self, user):
        user = user.lower()
        all_joins = self.db.all("SELECT joins FROM joins WHERE LOWER(\"user\")=%s AND user_network='" + self.network + "'", (user, ))
        all_kicks = self.db.all("SELECT given, received FROM kicks WHERE LOWER(\"user\")=%s AND user_network='" + self.network + "'", (user, ))
        all_messages = self.db.all("SELECT messages, messages_words, messages_characters, actions, actions_words, actions_characters, notices, notices_words, notices_characters FROM messages WHERE LOWER(\"user\")=%s AND user_network='" + self.network + "'", (user, ))
        joins =0
        for record in all_joins:
            joins += record
        given = 0
        received = 0
        for record in all_kicks:
            given += int(record[0])
            received += int(record[1])
        messages = 0
        messages_words = 0
        messages_characters = 0
        actions = 0
        actions_words = 0
        actions_characters = 0
        notices = 0
        notices_words = 0
        notices_characters = 0
        for record in all_messages:
            messages += int(record[0])
            messages_words += int(record[1])
            messages_characters += int(record[2])
            actions += int(record[3])
            actions_words += int(record[4])
            actions_characters += int(record[5])
            notices += int(record[6])
            notices_words += int(record[7])
            notices_characters += int(record[8])
        userrecord = self.db.one("SELECT xp_spent, level, coin, coin_given, coin_spent, ap_spent FROM users WHERE LOWER(name)=%s AND network='" + self.network + "'", (user, ))
        xp_spent = userrecord[0]
        level = userrecord[1]
        coin = userrecord[2]
        coin_given = userrecord[3]
        coin_spent = userrecord[4]
        ap_spent = userrecord[5]
        total_xp = ((level + joins + (given * received) + messages + (messages_words / 4) + (messages_characters / 10) + ((actions + (actions_words / 4) + (actions_characters / 10)) * 2) + ((notices + (notices_words / 4) + (notices_characters / 10)) / 2)) / 120) - (level * 5) + float(coin_spent) + float(ap_spent / 4)
        xp = total_xp - xp_spent
        total_messages = messages + actions + notices
        total_words = messages_words + actions_words + notices_words
        total_characters = messages_characters + actions_characters + notices_characters
        if total_xp < 1:
            total_xp = 1
        joinkarma = (((messages / 19) - joins) / total_xp) /10
        print("Joinkarma: (" + str(messages) + " / 20) - " + str(joins) + " = " + str(joinkarma))
        words_per_message = (total_words / 6) - total_messages
        print("Words per message: = (" + str(total_words) + " / 6) - " + str(total_messages) + " = " + str(words_per_message))
        characters_per_message = (total_characters / 20) - total_messages
        print("Characters per message: (" + str(total_characters) + " / 20) - " + str(total_messages) + " = " + str(characters_per_message))
        characters_per_word = (total_characters / 6) - total_words
        print("Characters per word: (" + str(total_characters) + " / 6) - " + str(total_words) + ") = " + str(characters_per_word))
        chatkarma = ((words_per_message + characters_per_message + characters_per_message + characters_per_word) / total_xp) / 100
        print("Chat karma: ((" + str(words_per_message) + " + " + str(characters_per_message) + " + " + str(characters_per_word) + ") / " + str(total_xp) + ") / 100 = " + str(chatkarma))
        kickkarma = ((given * received) / total_xp) / 2
        print("Kick karma: (" + str(given) + " * " + str(received) + ") / "+ str(total_xp) + " = " + str(kickkarma))
        xpkarma = xp / 25
        print("XP Karma: " + str(xp) + " /  25 = " + str(xpkarma))
        coinkarma = (coin - coin_given / (xp_spent + 1)) / 99
        print("Coin karma: (" + str(coin) + " / (" + str(xp_spent + 1) + ")) / 99 = " + str(coinkarma))
        karma = float(joinkarma) + float(chatkarma) - float(kickkarma) + float(xpkarma) - float(coinkarma)
        print("karma: " + str(joinkarma) + " + "+ str(chatkarma) + " - " + str(kickkarma) + " + " + str(xpkarma) + " - " + str(coinkarma) + " = " + str(karma))
        
        return level, xp, xp_spent, total_xp, karma, coin, coin_spent, coin_given, ap_spent
    
    def list_top_players(self, sort):
        result = self.db.all("SELECT name, level, xp_spent, coin FROM users WHERE network=%s ORDER BY " + sort + " DESC LIMIT 3 ", (self.network, ))
        if sort == "level":
            column = 1
            threshold = 0
        if sort == "xp_spent":
            column = 2
            threshold = 0
        if sort == "coin":
            column = 3
            threshold = 10
        message = ""
        for record in result:
            if not record[column] <= threshold:
                level, xp, xpspent, totalxp, karma, coin, coinspent, coingiven, apspent = GameHelpers.get_info(self, record[0])
                ap = xp + xpspent
                if ap < 0:
                    ap = 0
                if sort == "level":
                    message += red + str(record[0]) + reset + " [" + blue + "L " + green + str(level) + reset + ", X " + grey + str(xpspent) + "/" + green + str(int(xp + xpspent)) + reset + ", A " + str(int(ap - float(apspent))) + ", C " + green + str(coin) + reset + ", K " + green + str(round(karma, 2)) + reset + "], "
                if sort == "xp_spent":
                    message += red + str(record[0]) + reset + " [L " + green + str(level) + reset + ", " + blue + "X " + grey + str(xpspent) + "/" + green + str(int(xp + xpspent)) + reset + ", A " + str(int(ap - float(apspent))) + ", C " + green + str(coin) + reset + ", K " + green + str(round(karma, 2)) + reset + "], "
                if sort == "coin":
                    message += red + str(record[0]) + reset + " [L " + green + str(level) + reset + ", X " + grey + str(xpspent) + "/" + green + str(int(xp + xpspent)) + reset + ", " + reset + "A " + str(int(ap - float(apspent))) + ", " + blue + "C " + green + str(coin) + reset + ", K " + green + str(round(karma, 2)) + reset + "], "
        return message[:-2]

class StatisticsHelpers():
    def add_message_stats(stats):
        messages = 0
        words = 0
        characters = 0
        for record in stats:
            messages += record[0]
            words += record[1]
            characters += record[2]
        return messages, words, characters
