#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-

""" Collection de fonction/classe pour avoir un bel affichage 

Copyright (C) Frédéric Pauget
Licence : GPLv2
"""

import sys, sre, os, tempfile

if 'TERM' in os.environ:
    el = os.popen('tput  cr ; tput el').read()
else:
    el = os.popen('tput -Tvt100 cr ; tput -Tvt100 el').read()

def dialog(backtitle,arg) :
    """ Affiche la boite de dialogue défine avec les arguments fournis
    (cf man dialog) 
    si tout se déroule bien retourne :
	[ 0,  [ reponse(s) ] ]
    si annulatin retourne :
	[ 1, [] ]
    si appui sur ESC demande confirmation de l'abandon et exécute sys.exit(0)
    si erreur dans les arguments raise RuntimeError
    """
    f = tempfile.NamedTemporaryFile()
    cmd = u'/usr/bin/dialog --backtitle "%s" --cancel-label "Retour" %s 2>%s' % (backtitle,arg,f.name)
    res = os.system(cmd.encode('iso-8859-15','ignore'))

    if res == 256 :
	# Annuler
	f.close()
	return [ 1, [] ]
		    
    # Lecture du fichier de résultat et effacement
    try: 
	result=f.readlines()
	f.close()
    except :
	result = [ "n'importe quoi", '']
	res = 65280
    
    # Traitement
    if res==65280 and result:
	# Erreur dans les arguments
	raise RuntimeError( arg, result[1].strip() )
    elif res==65280 :
	# Appui sur ESC
	arg1 = u'--title "Annulation" --yesno "Quitter ?\nLes dernières modifications seront perdues." 6 48'
	print backtitle
	cmd = u'/usr/bin/dialog --backtitle "%s" %s' % (backtitle,arg1)
	res = os.system(cmd.encode('iso-8859-15','ignore') )
	if res==0 : sys.exit(0)
	else : return dialog(backtitle,arg)
    elif not result : result=['']
    
    return [ 0, result ]

def coul(txt,col):
    """
    Retourne la chaine donnée encadrée des séquences qui 
    vont bien pour obtenir la couleur souhaitée
    Les couleur sont celles de codecol
    Il est possible de changer la couleur de fond grace aux couleur f_<couleur>
    """
    codecol={'rouge' : 31 , 'vert' : 32 , 'jaune' : 33 , 'bleu': 34 , 'violet' : 35 , 'cyan' : 36 , 'gras' : 50}
    try :
	if col[:2]=='f_' : add=10; col=col[2:]
	else : add=0
	txt = "\033[1;%sm%s\033[1;0m" % (codecol[col]+add,txt)
    finally :
	return txt

OK = coul('OK','vert')
WARNING = coul('WARNING','jaune')
ERREUR = coul('ERREUR','rouge')
    
def cprint(txt,col):
    print coul(txt,col)

def tableau(largeurs,data) :
    """
    retourne une chaine formatée repésentant un tableau
    largeur est la liste des largeurs des colones
    data est une liste de tuples :
	[ ( données entète), (données ligne1), .... ]
    """
    sep_col = u'|'

    # Si l'une des largeurs est '*', alors on la met la plus grande possible
    if '*' in largeurs:
        rows, cols = get_screen_size()
        nlargeurs = []
        for n in largeurs:
            if n != '*':
                nlargeurs.append(n)
            else:
                nlargeurs.append(max(cols - sum(filter(lambda x:x!='*',largeurs)) - len(largeurs) - 1, 3))
        largeurs = nlargeurs
    
    # Ligne de séparation entète corps
    s=u'\n'
    for l in largeurs :
	s+= sep_col + u'-'*l
    s += sep_col + u'\n'
	    
    nb_cols = len(largeurs)
    
    # Remplissage tableau
    f=u''
    for ligne in data :
	for i in range(0, nb_cols) :
	    f+= sep_col
	    # Centrage
	    l = len(sre.sub('\x1b\[1;([0-9]|[0-9][0-9])m','',ligne[i])) # Longeur sans les chaines de formatage
	    if l >= largeurs[i] :
		f += ligne[i]
	    else :
		n = largeurs[i] - l
		f += u' '*(n/2) + ligne[i] + u' '*(n/2 + n%2)
	f+= sep_col + u'\n'
	
    # Final
    f = f.replace(u'\n',s,1) # Insertion du séparateur entète - corps
    return f[:-1] # Supression du \n final

def get_screen_size():
    """Retourne la taille de l'écran.

    Sous la forme d'un tuble (colonnes, lignes)"""
    try:
        from termios import TIOCGWINSZ
        from struct import pack, unpack
        from fcntl import ioctl
        s = pack("HHHH", 0, 0, 0, 0)
        rows, cols = unpack("HHHH", ioctl(sys.stdout.fileno(), TIOCGWINSZ, s))[:2]
        return (rows, cols)
    except:
        return (80, 24)

def prompt(prompt, defaut=''):
    """ Pose la question prompt, retourne la réponse """
    sys.stdout.write(coul(prompt,'gras'))
    if defaut :
        sys.stdout.write(" ["+defaut+"]")
    sys.stdout.write(" ")
    v=sys.stdin.readline().strip()
    if not v : v = defaut
    return v

class anim :
    """ Permet de créer une animation :
	truc................./
	truc.................-
	truc.................\
	truc.................|
	ou une barre de progression si le nombre total d'itérations est founi.
	"""
    def __init__(self,truc,iter=0) :
	""" Affichage de :
	    truc................."""
	self.txt = truc + '.'*(50-len(truc))
	self.c = 1
	self.iter = iter
	sys.stdout.write(self.txt)
	sys.stdout.flush()
	
    def reinit(self) :
	""" Efface la ligne courrante et 
	affiche  : 	truc................. """
	sys.stdout.write(el + self.txt)
	if self.iter :
	    sys.stdout.write(' '*28)
	    sys.stdout.write(el + self.txt)
	sys.stdout.flush()
    
    def cycle(self) :
	""" Efface la ligne courrante et 
	affiche  : 	truc..................?
	? caratère variant à chaque appel """
	sys.stdout.write(el + self.txt)
	if self.iter!=0 :
	    sys.stdout.write('[')
	    av = float(self.c) / float(self.iter)
	    n = int(20 * av)
	    sys.stdout.write('='*n)
	    sys.stdout.write('>')
	    sys.stdout.write(' '*(20 - n))
	    sys.stdout.write('] %3i%%' % int(100 * av) )
	else :
	    sys.stdout.write('/-\|'[self.c%4])
	sys.stdout.flush()
	self.c += 1
