from Data import Data
from Comparabile import Comparabile
from OperazioneErrata import *

true = lambda : 1
false = lambda : 0

def checkInteger(numero):
    if type(numero) == type(0):
        return true()
    else:
        return false()

class ContoCorrente(Comparabile):

    numerazioneConti = 0
    maxScopertoStandard = 100
    forfaitSpese = 1
    capitaleSocialeBanca = 1000
    totaleSoldiBanca = capitaleSocialeBanca
    tassoStandard = 5
    tassoPassivoStandard = 10
    nomeBanca = "Banca Sella"

    arrayOfContoCorrente = []
    data = Data()

    def __init__(self, nome, saldoIniziale = 0):
        self.nomeCorrentista = nome
        self.saldo = saldoIniziale
        self.numeroConto = ContoCorrente.numerazioneConti
        ContoCorrente.numerazioneConti += 1
        ContoCorrente.totaleSoldiBanca += saldoIniziale
        self.interesseMaturato = 0
        self.giornoUltimoInteresse = Data(ContoCorrente.data.getData())
        (ContoCorrente.arrayOfContoCorrente).append(self)

    def versamento(self, valore):
        if not checkInteger(valore):
            raise OperazioneErrata("Valore non intero")
        if valore < 0:
            raise OperazioneErrata("Valore versamento negativo")
        else:
            self.calcoloInteresseMaturato()
            self.saldo += valore
            ContoCorrente.totaleSoldiBanca += valore

    def prelievo(self, valore):
        saldoTemp = self.saldo - valore
        if not checkInteger(valore):
            raise OperazioneErrata("Valore non intero")
        if valore < 0:
            raise OperazioneErrata("Valore versamento negativo")
        else:
             if saldoTemp < 0:
                  if -saldoTemp < maxScopertoStandard:
                       if valore < totaleSoldiBanca:
                            self.saldo -= valore
                            self.totaleSoldiBanca -= valore
                       else:
                            raise OperazioneErrata("Soldi della banca esauriti")
                  else:
                       raise OperazioneErrata("Scoperto Standard Superato")
             else:
                  self.saldo -= valore
                  self.totaleSoldiBanca -= valore

    def getSaldo(self):
        return self.saldo

    def getNomeCorrentista(self):
        return self.nomeCorrentista

    def getNumeroConto(self):
        return self.numeroConto

    def getInteresseMaturato(self):
        return self.interesseMaturato

    def calcoloInteresseMaturato(self):
        if self.saldo > 0:
            self.interesseMaturato += self.saldo * self.tassoStandard * self.data.diffData(self.giornoUltimoInteresse) / 36000
        else:
            self.interesseMaturato += self.saldo * self.tassoPassivoStandard * self.data.diffData(self.giornoUltimoInteresse) / 36000
        self.giornoUltimoInteresse.setData(self.data.getData())

    def calcolaCompetenze(self):
        return self.interesseMaturato - self.forfaitSpese

    def chiusura(self):
        self.calcoloInteresseMaturato()
        self.saldo += self.calcolaCompetenze()
        self.interesseMaturato = 0

    def compara(self,altroCC):
        if not issubclass(self.__class__, altroCC.__class__) and \
           not issubclass(altroCC.__class__, self.__class__):
            raise OperazioneErrata("Confronto non permesso")
        else:
            if self.getSaldo() < altroCC.getSaldo():
                return -1
            if self.getSaldo() > altroCC.getSaldo():
                return 1
            return 0


    def __str__(self):
        return \
            "\nData                 :" + str(self.data.getData()) +\
            "\nNome del Correntista :" + str(self.getNomeCorrentista()) +\
            "\nNumero del Conto     :" + str(self.getNumeroConto()) +\
            "\nInteressi Maturati   :" + str(self.getInteresseMaturato()) +\
            "\nSaldo                :" + str(self.getSaldo())

class ContoCorrenteConSpese(ContoCorrente):

    costoOperazione = 1
    numOperazioniGratis = 2

    def __init__(self, nome, saldoIniziale = 0):
        ContoCorrente.__init__(self, nome, saldoIniziale)
        self.numeroOperazioni = 0

    def versamento(self, valore):
        ContoCorrente.versamento(self, valore)
        self.numeroOperazioni += 1

    def prelievo(self, valore):
        ContoCorrente.prelievo(self, valore)
        self.numeroOperazioni += 1

    def calcolaCompetenze(self):
        if self.numeroOperazioni <= self.numOperazioniGratis:
            return ContoCorrente.calcolaCompetenze(self)
        else:
            return ContoCorrente.calcolaCompetenze(self) - self.costoOperazione * self.numOperazioni

    def chiusura(self):
        ContoCorrente.chiusura(self)

    def getInteresseMaturato(self):
        ContoCorrente.getInteresseMaturato(self)

    def calcoloInteresseMaturato(self):
        ContoCorrente.calcoloInteresseMaturato(self)

    def __str__(self):
        return ContoCorrente.__str__(self) + \
               "\nNumero operazioni effettuate: " + str(self.numeroOperazioni)