# -*- coding:Utf-8 -*-


# ==================================================
# >> IMPORTATIONS
# ==================================================


import es
import langlib
import usermsg
import popuplib

import os
import re
import shelve
import random
import datetime

import psyco
psyco.full()


# ==================================================
# >> INFORMATIONS
# ==================================================


g_informations = es.AddonInfo()
g_informations["name"] = "PaintBalls by L'In20Cible"
g_informations["version"] = "2.0"
g_informations["date"] = "2010-05-16"
g_informations["author"] = "L\'in20Cible"
g_informations["url"] = "http://addons.eventscripts.com/addons/view/paintballs/"
g_informations["basename"] = "paintballs"

es.ServerVar("pb_version", (g_informations["version"] + " by " + g_informations["author"])).makepublic()


# ==================================================
# >> GLOBALES
# ==================================================


g_popups = list()

g_options = {
   "enable": ("1", "pb_enable <1/0> -- Active/Désactive le PaintBalls."),
   "advert": ("1", "pb_advert <1/0> -- Active/désactive les annonces au début de chaque round.")
   }
for option in g_options:
   g_options[option] = es.ServerVar(("pb_" + option), g_options[option][0], g_options[option][1])
   
eventscripts_noisy = es.ServerVar("eventscripts_noisy")
eventscripts_gamedir = str(es.ServerVar("eventscripts_gamedir"))


# ==================================================
# >> INITIALISATION
# ==================================================


def load():
   Initialization()
   if not int(eventscripts_noisy):
      eventscripts_noisy.set("1")
   es.flags("add", "notify", "eventscripts_noisy")
   
   
def Initialization():
   global g_textures, g_translations, g_settings
   path = GetConfigurationFilePath("")
   if not os.path.isdir(path):
      os.mkdir(path)
   path = GetConfigurationFilePath("configuration.cfg")
   if os.path.isfile(path):
      es.mexec(path.replace(eventscripts_gamedir, ".."))
   g_textures = dict()
   for line in GetConfigurationFileParsed(GetConfigurationFilePath("textures.txt")):
      line = re.search("[^\"]+\"\s*\"[^\"]+", line)
      if not line:
         continue
      line = line.group().split("\"")
      for index in range(len(line)):
         line[index] = line[index].strip()
      g_textures[line[0]] = line[2]
   if int(g_options["enable"]) and str(es.ServerVar("eventscripts_currentmap")):
      for line in GetConfigurationFileParsed(GetConfigurationFilePath("downloads.txt")):
         if not os.path.isfile(os.path.join(eventscripts_gamedir, line)):
            continue
         es.stringtable("downloadables", line)
   path = GetConfigurationFilePath("translations.ini")
   if os.path.isfile(path):
      g_translations = langlib.Strings(path)
   else:
      g_translations = TranslationFileIsMissingCallBack
   g_settings = shelve.open(GetConfigurationFilePath("settings.db"), "c", None, writeback = True)
   
   
def unload():
   g_settings.close()
   for popup in g_popups:
      if not popuplib.exists(popup):
         continue
      for player in es.getUseridList():
         if not popuplib.isqueued(popup, player):
            continue
         popuplib.close(popup, player)
      popuplib.delete(popup)
   es.flags("remove", "notify", "eventscripts_noisy")
   
   
# ==================================================
# >> UTILITAIRES
# ==================================================


def GetConfigurationFileParsed(path):
   lines = list()
   if not os.path.isfile(path):
      return lines
   regex = re.compile("//.*|^(( |\t)+)|(( |\t)+)$|(\r)+|(\n)+")
   for line in open(path):
      line = regex.sub("", line).strip()
      if not line:
         continue
      lines.append(line)
   return lines
   
   
def GetConfigurationFilePath(file):
   return os.path.join(str(es.ServerVar("eventscripts_addondir")), g_informations["basename"], "configuration", file).replace(os.sep, "/")
   
   
def GetPlayerLanguage(userid):
   return langlib.getLangAbbreviation(es.getclientvar(userid, "cl_language"))
   
   
# ==================================================
# >> FONCTIONS D'APPEL
# ==================================================


def TranslationFileIsMissingCallBack(string, tokens, language):
   return "Sorry, the translation file is missing."
   
   
def MenuSelectCallBack(userid, choice, popupname):
   popuplib.delete(popupname)
   g_popups.remove(popupname)
   steamid = es.getplayersteamid(userid)
   if (steamid not in g_settings):
      g_settings[steamid] = {
         "texture": choice,
         "datetime": datetime.date.today()
         }
   else:
      g_settings[steamid]["texture"] = choice
   player = es.createplayerlist(userid)[userid]
   for userid in es.getUseridList():
      if es.isbot(userid):
         continue
      language = GetPlayerLanguage(userid)
      usermsg.saytext2(userid, player["index"], ("[PaintBalls] " + g_translations("selected", {"username": player["name"], "color": choice if (choice != "random") else g_translations("random", dict(), language)}, language)))
      
      
# ==================================================
# >> ÉVÉNEMENTS
# ==================================================


def es_map_start(event_var):
   Initialization()
   for player in g_settings:
      if not ((datetime.date.today() - g_settings[player]['datetime']).days >= 7):
         continue
      del g_settings[player]
      
      
def server_cvar(event_var):
   if (event_var["cvarname"].lower() != "eventscripts_noisy"):
      return
   eventscripts_noisy.set("1")
   
   
def bullet_impact(event_var):
   if not int(g_options["enable"]) or not len(g_textures):
      return
   steamid = es.getplayersteamid(event_var["userid"])
   texture = g_textures[random.choice(g_textures.keys())]
   if (steamid in g_settings) and (g_settings[steamid]["texture"] != "random"):
      texture = g_textures[g_settings[steamid]["texture"]]
   es.server.queuecmd("est_effect_35 #h 0 %s \"%s %s %s\"" % (texture, event_var["x"], event_var["y"], event_var["z"]))
      
      
def player_say(event_var):
   userid = int(event_var["userid"])
   if not int(g_options["enable"]) or es.isbot(userid) or (event_var["text"].lower() != "!paintballs"):
      return
   popupname = ("paintballs_menu_" + str(userid))
   if not popuplib.exists(popupname):
      popup = popuplib.easymenu(popupname, "_popup_choice", MenuSelectCallBack)
      language = GetPlayerLanguage(userid)
      popup.settitle(g_translations("title", dict(), language))
      steamid = es.getplayersteamid(userid)
      if (steamid in g_settings) and (g_settings[steamid] != "random"):
         popup.addoption("random", g_translations("random", dict(), language))
      for texture in g_textures:
         if (steamid in g_settings) and (g_settings[steamid]["texture"] == texture):
            continue
         popup.addoption(texture, texture)
      g_popups.append(popupname)
   if not popuplib.isqueued(popupname, userid):
      popuplib.send(popupname, userid)
      
      
def round_freeze_end(event_var):
   if not int(g_options["enable"]) or not (g_options["advert"]):
      return
   for player in es.getUseridList():
      if es.isbot(player):
         continue
      es.tell(player, "#multi", ("#green[PaintBalls] #default" + g_translations("advert", dict(), GetPlayerLanguage(player))))
      
      
def player_spawn(event_var):
   steamid = es.getplayersteamid(event_var["userid"])
   if (steamid not in g_settings):
      return
   g_settings[steamid]["datetime"] = datetime.date.today()