#!/usr/bin/env python
# -*- coding: utf-8 -*-
 
from Excepciones import * #excepciones predefinidas
import webkit             #logra hacer que el formato de la fecha sea igual a la conf regional.???
from datetime import * 
 
class FechaHora():        
    def GetHoy(self, texto=False):
        """retorna el la fecha actual, si texto=True, la devuelve en modo texto.
        GetHoy(texto=False)
        """
        if texto:
            return self.SetFechaTexto()
        else:
            return datetime.today()
    
    def SetFecha(self, texto=False, *fecha):
        """retorna la fecha indicada como segundo parametro, al formato ideal.
        *fecha = (1988, 05, 07) >>> 07/05/1988, si el valor del parametro 
        *fecha es un string, se asume que la fecha esta en ese formato y se 
        quiere pasar a formato datetime o date (segun haiga una hora o no).
        si el parametro texto = True retorna la fecha en modo texto 
        >>> sabado 07 de Mayo del 1988
         """
        if not fecha:
            raise FechaHoraError("""Debe especificar una fecha en parametro 2 
                  SetFecha(texto=False, *fecha)""")
                  
        if len(fecha) == 1:
            if isinstance(fecha[0], basestring):
                #si hay comas, se remplazan por espacios
                fecha = fecha[0].replace(",", " ")
                #verifica que tipo de divicion tiene (- / )
                buscarbarra = fecha.find("/")
                buscarguion = fecha.find("-")
                
                #si la division es con barras----------------------------------
                if buscarbarra != -1:
                    dia, mes, anoyhora = fecha.split("/")
                    
                    #se verifica si hay una hora indicada
                    if anoyhora.find(":") != -1:
                        #contar los espacios en que esta dividida
                        espacios = anoyhora.count(" ")
                        ano, hora = anoyhora.split(" " * espacios)
                        horas, minutos, segundos = hora.split(":")
                    else:
                        ano = anoyhora
                        horas, minutos, segundos = False, False, False
                
                #si la divicion es con guion-----------------------------------
                elif buscarguion != -1:
                    dia, mes, anoyhora = fecha.split("-")
                    
                    #se verifica si hay una hora indicada
                    if anoyhora.find(":") != -1:
                        #contar los espacios en q esta dividida
                        espacios = anoyhora.count(" ")
                        ano, hora = anoyhora.split(" " * espacios)
                        horas, minutos, segundos = hora.split(":")
                    else:
                        ano = anoyhora
                        horas, minutos, segundos = False, False, False
                else:
                    return None
                   
                #si el dia es mayor a 31, se asume que es el año---------------
                try:
                    if int(dia) > 31:
                        dia2 = ano
                        ano = dia
                        dia = dia2
                except ValueError:
                    raise FechaHoraError(u"""La fecha indicada, no es valida, 
                          el dia, mes, año, hora, minutos, segundos que se 
                          especifiquen, deben ser caracteres numericos 
                          no """+dia+"/"+mes+"/"+ano)
                try:
                    fecha = datetime(int(ano), int(mes), int(dia), 
                                   int(horas), int(minutos), int(segundos))
                    if horas is False:
                        fecha = date(int(ano), int(mes), int(dia))
                except ValueError as e:
                    raise FechaHoraError(e)
 
                if texto:
                    #si no hay hora, no se indica en texto---------------------
                    if horas is False:
                        return self.SetFechaTexto(fecha, False)
                    else:
                        return self.SetFechaTexto(fecha, True)
                else:
                    return fecha
        #-------------------------------------------------------------------------------------------------------------
        else:
            if len(fecha) == 3:
                try:
                    #si hay 3 elementos, se crear un objeto date
                    fecha = date(*fecha)
                except ValueError:
                    #si el dia no es valido, y es mayor a 31, se invierte la tupla convirtiendola en lista
                    if fecha[2] > 31:
                        fecha = list(fecha)
                        fecha.reverse()
                        try:
                            fecha = date(*fecha)
                        except ValueError as e:
                            raise FechaHoraError(e)
                    else:
                        raise FechaHoraError("""Los datos introducidos para 
                        la creacion de la fecha, no son validos. """+str(fecha))
            elif len(fecha) > 3:
                #si hay mas de 3 elementos, se crea un obj datetime
                try:
                    fecha = datetime(*fecha)
                except ValueError:
                    #si el dia no es valido, y es mayor a 31, se cambia este por el año
                    if fecha[2] > 31:
                        dia = fecha[0]
                        ano = fecha[2]
                        fecha = list(fecha)
                        fecha[0] = ano
                        fecha[2] = dia
                        try:
                            fecha = datetime(*fecha)
                        except ValueError as e:
                            raise FechaHoraError(e)
                    else:
                        raise FechaHoraError("""Los datos introducidos para
                        la creacion de la fecha, no son validos. """+str(fecha))
            try: 
                #se formatea la fecha------------------------------------------
                if isinstance(fecha, datetime):
                    fecha_str =datetime.strftime(fecha,"%d/%m/%Y %H:%M:%S")
                    #si el retorno debe ser fecha en texto
                    if texto:
                        return self.SetFechaTexto(fecha, True)
                    else:
                        return fecha_str
                
                elif isinstance(fecha, date):
                    fecha_str =date.strftime(fecha,"%d/%m/%Y")
                    #si el retorno debe ser fecha en texto
                    if texto:
                        return self.SetFechaTexto(fecha, False)
                    else:
                        return fecha_str
            except BaseException as e:
                raise FechaHoraError(str(e))
                
    
        
    def GetHora(self):
        """Devuelve la hora actual en formato string"""
        hora_str = datetime.strftime(datetime.today(), "%H:%M:%S")
        return hora_str
    
    def GetFecha(self, texto=False):
        """Debuelve la fecha actual en formato string. si texto es True, devuelve
        la fecha en formato texto 
        >>> GetFecha()      ->  07/05/1988
        >>> GetFecha(True)  ->  Sábado 7 de mayo del 1988
        """
        fecha_str = datetime.strftime(datetime.today(), "%d/%m/%Y")
        if texto:
            return self.SetFechaTexto(fecha_str, False)
        else:
            return fecha_str
    
    def GetEdad(self, fecha):
        """Devuelve un objeto 'datetime.timedelta' con el tiempo exacto desde la 
        fecha indicada hasta hoy. El parametro 1 'fecha', puede ser un objeto 
        date, datetime, o una cadena de texto, este ultimo debe ser en 
        formato 'dia/mes/año' o 'dia-mes-año'.
        """
        if isinstance(fecha, basestring):
            try:
                fecha = self.SetFecha(False, fecha)
            except FechaHoraError as e:
                raise FechaHoraError(e)
        if isinstance(fecha, datetime):
            print 1
            return datetime.today() - fecha
        elif isinstance(fecha, date):
            print 2
            return date.today() - fecha
        else:
            raise FechaHoraError("""Error calculando la fecha, 
                                 la fecha indicada no es correcta.""")
                
    def SetFechaTexto(self, fecha=None, hora=True):
        """Formatea la fecha a formato texto.
        hoy = datetime.datetime.today()   >> 1988-05-07 10:30:27.548789
        fecha_texto = SetFechaTexto(hoy)  >> sábado 07 de mayo del 1988, 10:30:27
        si el parametro hora = False, devolvera solo la fecha.
        """
        if fecha == None:
            fecha = datetime.today()
        if isinstance(fecha, basestring):
            fecha = self.SetFecha(False, fecha)
        try:
            date_text = datetime.strftime(fecha, "%A %d de %B del %Y") 
            time_text = datetime.strftime(fecha, "%H:%M:%S")
        except BaseException as e:
            raise FechaHoraError(e)
        else:
            if hora == False:
                return date_text
            else:
                return date_text+", "+time_text