class Equipment(models.Model):
    state = models.ForeignKey(EquipmentState,null=True)
    equipment_name = models.CharField(max_length=30,default="blank")
    date_danation = models.DateField(auto_now=True)

    def register_equipment(self, name_equipment):
        available = AvailableEquipment()
        available.save()
        self.state = available
        self.equipment_name = name_equipment
        super(Equipment, self).save()

    def start_state(self):
        available = AvailableEquipment()
        available.save()
        self.state = available
        super(Equipment,self).save()

    def fix_equipment(self):
        try:
            previous_state = self.state.fix_equipment()
            (self.state).delete()
            self.state = previous_state
        except TypeError:
            pass

    def borrow_equipment(self, partner):
        try:
            # previous_state = self.state.borrow_equipment()
            # self.state.delete()
            previous_state = self.state.borrow_equipment(partner)
            (self.state).delete()

            self.state = previous_state
        except TypeError:
            pass

    def take_back_equipment(self):
        try:
            previous_state = self.state.take_back_equipment()
            (self.state).delete()
            self.state = previous_state
        except TypeError:
            pass

    def disable_equipment(self):
        try:
            previous_state = self.state.disable_equipment()
            (self.state).delete()
            self.state = previous_state
            pass
        except TypeError:
            pass

    def __str__(self):
        return self.equipment_name class AvailableEquipment(EquipmentState):

    def borrow_equipment(self,partner):
        borrowed_equipment = BorrowedEquipment(partner=partner)
        borrowed_equipment.save()
        return borrowed_equipment

    def disable_equipment(self):
        broken_equipment = BrokenEquipment()
        broken_equipment.save()
        return broken_equipment

    def __str__(self):
        return "Available" class BorrowedEquipment(EquipmentState):
    borrow_date = models.DateField(auto_now=True)
    partner = models.ForeignKey(Partner)

    def take_back_equipment(self):
        available_equipment = AvailableEquipment()
        available_equipment.save()
        return available_equipment

    def disable_equipment(self):
        broken_equipment = BrokenEquipment()
        broken_equipment.save()
        return broken_equipment

    def __str__(self):
        return "Borrowed" class BrokenEquipment(EquipmentState):
    broken_date = models.DateField(auto_now=True)
    price_repair = models.FloatField(blank=True,null=True)

    def fix_equipment(self):
        available_equipment = AvailableEquipment()
        available_equipment.save()
        return available_equipment

    def __str__(self):
        return "Broken" class EquipmentState(PolymorphicModel):

    class meta:
        abstract =True

    def fix_equipment(self):
        raise TypeError("Not possible to fix because the equipment is " + self)

    def borrow_equipment(self,partner):
        raise TypeError("Not passible to borrow because the equipment is " + self)

    def take_back_equipment(self):
        raise TypeError("Not possible to take back because the equipment is "+ self)

    def disable_equipment(self):
        raise TypeError("Not possible to take back because the equipment is "+ self) class Employee(models.Model):
    class Meta:
        abstract = True

    phone_number = models.CharField(max_length = 12)
    user = models.OneToOneField(User,on_delete=models.CASCADE)

    def register_donor(self, name, phone_number, address, address_reference, observations, email,donation_date):
        user = self.generate_user(self, name, email, '')
        donor = Donor (user=user,
                    name=name,
                    email = email,
                    phone_number=phone_number,
                    address = address,
                    address_reference = address_reference,
                    observations = observations,
                    donation_date=donation_date)
        donor.save()

    def confirm_scheduling(self):
        pass

    def edit_donor(self):
        pass

    def update_donation_date(self, newDonationDate, donor):
        donor.donation_date = newDonationDate
        donor.save()

    def __str__(self):
        return self.user.username class Donor (models.Model):
    name = models.CharField(max_length = 50, blank = False)
    phone_number = models.CharField(max_length = 12)
    email = models.CharField(max_length = 30, blank = True)
    address = models.CharField(max_length = 200)
    address_reference = models.CharField(max_length = 200, blank = True)
    observations = models.TextField(blank = True)
    donation_date = models.DateField()
    user = models.OneToOneField(User,on_delete=models.CASCADE) class Secretary (Employee, Observable):
    is_superuser = False
    activate =  models.BooleanField(default=False)
    release_activate_at = models.DateTimeField(null=True, blank=True)
    observers_in_secretary = []

    def listAllSecretaries(self):
        secretaries = Secretary.objects.all()
        return secretaries

    def add_observers(self):
        self.observers_in_secretary = Administrator.objects.all()
        
    def remove_observers(self, input):
        return

    def notify_observers(self, input):
        for observer in self.observers_in_secretary:
            observer.update(input)


    def date_time_release(self):
        date_now = datetime.now()

        if self.release_activate_at.date() == date_now.date():
           if self.release_activate_at.hour - date_now.hour >= 6:
                self.add_observers()
                self.notify_observers(self.user.email) 

        else:
            self.add_observers()
            self.notify_observers(self.user.email) class Administrator(Employee, Observer):

    is_superuser = True

    def register_employee(self,employee_type, name, phone_number, email, password):
        if employee_type == 'secretary':
            self.create_secretary(name, phone_number, email, password)
        else:
            self.create_administrator(name, phone_number, email, password)

    def remove_employee(self):
        pass

    def release_login(self, id_Secretary):
        try:
            secretary = Secretary.objects.get(id=id_Secretary)
        except ObjectDoesNotExist:
            secretary = None    

        if secretary is not None:
            if secretary.activate == False:
                secretary.activate = True
                secretary.release_activate_at = datetime.now()
                secretary.save()
                release = True
            else:
                release = False
        else:
            release = False
        
        return release                    


    def block_login(self, id_Secretary):

        try:
            secretary = Secretary.objects.get(id=id_Secretary)
        except ObjectDoesNotExist:
            secretary = None    

        if secretary is not None:
            if secretary.activate == True:
                secretary.activate = False
                secretary.release_activate_at = None
                secretary.save()
                release = True
            else:
                release = False
        else:
            release = False
        
        return release

    def generate_superuser(self, name, phone_number, email, password):
        user = User(first_name=name,username=email,email=email)
        user.set_password(password)
        user.is_superuser = True
        user.save()
        return user

    def generate_user(self, name, phone_number, email, password):
        user = User(first_name=name,username=email,email=email)
        user.set_password(password)
        user.save()
        return user

    def create_secretary(self, name, phone_number, email, password):
        user = self.generate_user(self, name, email, password)
        secretary = Secretary (user=user,
                               phone_number=phone_number
        )
        secretary.save()

        return secretary

    def create_administrator(self, name, phone_number, email, password):
        user = self.generate_superuser(self, name, email, password)
        admin = Administrator (user=user,
                              phone_number=phone_number
        )
        admin.save()

        return admin

    def update(self, input):
        subject = "Login suspeito"
        message = "O Secretario dolo do email: " + input + " realizou um login agora, este email eh informativo"
        email_destination = self.user.email
        email = Email()
        email.send_email(subject, message, email_destination)
        print(email_destination) class Equipment(models.Model):
    state = models.ForeignKey(EquipmentState,null=True)
    equipment_name = models.CharField(max_length=30,default="blank")
    date_danation = models.DateField(auto_now=True)

    def register_equipment(self, name_equipment):
        available = AvailableEquipment()
        available.save()
        self.state = available
        self.equipment_name = name_equipment
        super(Equipment, self).save()

    def start_state(self):
        available = AvailableEquipment()
        available.save()
        self.state = available
        super(Equipment,self).save()

    def fix_equipment(self):
        try:
            previous_state = self.state.fix_equipment()
            (self.state).delete()
            self.state = previous_state
        except TypeError:
            pass

    def borrow_equipment(self, partner):
        try:
            # previous_state = self.state.borrow_equipment()
            # self.state.delete()
            previous_state = self.state.borrow_equipment(partner)
            (self.state).delete()

            self.state = previous_state
        except TypeError:
            pass

    def take_back_equipment(self):
        try:
            previous_state = self.state.take_back_equipment()
            (self.state).delete()
            self.state = previous_state
        except TypeError:
            pass

    def disable_equipment(self):
        try:
            previous_state = self.state.disable_equipment()
            (self.state).delete()
            self.state = previous_state
            pass
        except TypeError:
            pass

    def __str__(self):
        return self.equipment_name class AvailableEquipment(EquipmentState):

    def borrow_equipment(self,partner):
        borrowed_equipment = BorrowedEquipment(partner=partner)
        borrowed_equipment.save()
        return borrowed_equipment

    def disable_equipment(self):
        broken_equipment = BrokenEquipment()
        broken_equipment.save()
        return broken_equipment

    def __str__(self):
        return "Available" class BorrowedEquipment(EquipmentState):
    borrow_date = models.DateField(auto_now=True)
    partner = models.ForeignKey(Partner)

    def take_back_equipment(self):
        available_equipment = AvailableEquipment()
        available_equipment.save()
        return available_equipment

    def disable_equipment(self):
        broken_equipment = BrokenEquipment()
        broken_equipment.save()
        return broken_equipment

    def __str__(self):
        return "Borrowed" class BrokenEquipment(EquipmentState):
    broken_date = models.DateField(auto_now=True)
    price_repair = models.FloatField(blank=True,null=True)

    def fix_equipment(self):
        available_equipment = AvailableEquipment()
        available_equipment.save()
        return available_equipment

    def __str__(self):
        return "Broken" class Partner(models.Model):
	
	name = models.CharField(max_length=100)
	description = models.TextField()
	address = models.TextField()
	fone = models.CharField(max_length=12)

	def save_patners(self, partner_name, partner_description, partner_address, partner_fone):
		partner = Partner(name=partner_name, description = partner_description, address = partner_address, fone = partner_fone)
		partner.save()
		
	
	def __str__(self):
                return self.name
from django.shortcuts import render
from equipments.models import Equipment, AvailableEquipment, BorrowedEquipment
from equipments.models import  BrokenEquipment, EquipmentState
from users.models import Employee, Donor, Secretary, Administrator
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from equipments.models import Equipment
from equipments.models import AvailableEquipment
from equipments.models import BorrowedEquipment
from equipments.models import BrokenEquipment
from partners.models import Partner

def register_equipment(request):

    if request.method == 'GET':
        return render(request, "form_equipment.html")

    else:
        form = request.POST
        equipment_name = form.get('equipment_name')
        equipment = Equipment()
        equipment.register_equipment(equipment_name)
        return HttpResponseRedirect(reverse('equipments:list_equipment'))

def borrow_equipment(request):
    context = {}
    if request.method == 'GET':

        all_equipments = Equipment.objects.all()
        context['all_available'] = filter(is_avalible,all_equipments)
        context['all_partners'] = Partner.objects.all()
        return render(request,'borrow_equipment/borrow_equipment.html',context)

    elif request.method == 'POST':
        form = request.POST
        equipment = form.get('equipment')
        partner = form.get('partner')

        if make_borrow(equipment,partner):
            return HttpResponseRedirect(reverse('equipments:list_equipment'))
        else:
            return render(request,'borrow_equipment/borrow_equipment_fail.html',context)

def is_avalible(Equipment):
    if type(Equipment.state) == type(AvailableEquipment()):
        return True
    else:
        return False

def is_borrow(Equipment):
    if type(Equipment.state) == type(BorrowedEquipment()):
        return True
    else:
        return False

def is_broken(Equipment):

    if type(Equipment.state) == type(BrokenEquipment()):