@startuml
@startuml


ScheduleVisitUI .-> ScheduleVisitController

ScheduleVisitController.---> Repositories
ScheduleVisitController .----> Date
ScheduleVisitController .----> Property
ScheduleVisitController .----> Client

Repositories -> Repositories : instance

Repositories ---> PropertyRepository : propertyRepository
Repositories --> ScheduleVisitRepository : scheduleVisitRepository

PropertyRepository "1" ---> "0..*" Property
ScheduleVisitRepository "1" --> "0...*" ScheduleVisit


Agent "1" ------ "0...*" Property : > creates
Agent "1" -----|> "1" Employee : is a >

Property "1" <|----- "1" Land : is a <
Property "1" <|----- "1" Habitable : is a <
Property "1" ----- "1" Address : Has a >
Property "1" -------  "1...*" Photograph : Has >
Property "1" ----- "1" Date : has  >

PropertyOwner "1" --- "1" Client: has >
PropertyOwner "1" -- "1...*" Property : > has

Request "0...*" ---- "1" Agent : has >
Request "1" <|--- "1" RequestRent : is a <
Request "1" <|--- "1" RequestSale : is a <

Person "1" <|---- "1" Employee : < is a
Person "1" <|--- "1" Client : < is a


Date "1" -- "1" Request : has <


Habitable "1" <|--- "1" Residence : is a <
Habitable "1" <|--- "1" Apartment : is a <

ScheduleVisit "1" ---> "2" Date : has >
ScheduleVisit "1" ---> "1" Client : has >
ScheduleVisit "1" ---> "2" Property : has >

Employee "1" -- "1" Store : has a >


class ScheduleVisit{
   - property
    -startDate
   - client
    -endDate

   + checkOverlap(ScheduleVisit other) : boolean
}

class Repositories{
    -Repositories()
    +getInstance() : Repositories
    +getAdvertisementRepository()
}

 class PropertyRepository{
    -  ArrayList<Property> propertyList
    -  ArrayList<Land> landList
    -  ArrayList<Residence> residenceList
    -  ArrayList<Apartment> apartmentsList
    -  ArrayList<Habitable> habitableList
    -  ArrayList<Property> propertySale
    -  ArrayList<Property> propertyLease

   +  boolean propertyArrayNotNull()
   +  void displayProperties()
   +  boolean checkIfParishExists(String parish)
   +  void displayPropertiesByParish(String parish)
   +  boolean checkIfTypeValid(String type)
   +  void displayPropertiesByType(String type)
   +  void displayPropertiesByAscDescOrderPrice(int order)
   +  void displayPropertiesByAscDescOrderState(int order)
   +  void displayPropertiesByAscDescOrderCity(int order)
   +  void displayPropertiesByAscDescOrderParish(int order)
   +  void displayPropertiesByAscDescOrderParish(int order)
   +  boolean checkIfHabitableListArrayNotNull()
   +  boolean checkIfNumberOfBedroomsExists(int numberOfBedrooms)

 }

class ScheduleVisitRepository{
    -ArrayList<ScheduleVisit> scheduleVisits
    -ArrayList<ScheduleVisit> scheduleVisitsRequest

    +displayScheduleByIndex(int index) : void
    +addNewScheduleVisitRequest(Date startDate, Date endDate, Property property, Client client) : void
    +checkIfOverlapSchedule(ScheduleVisit scheduleVisit1) : boolean
    +displayScheduleVisitRequestByIndex(int index) : void
    +displayScheduleVisitRequestByIndex(int index, Client client) : void
    +displayScheduleVisitAccepted(ArrayList<ScheduleVisit> novo) : void
    +getScheduleVisitsRequestByClient(Client client) : ArrayList<ScheduleVisit>
    +getScheduleVisitsByClient(Client client) : ArrayList<ScheduleVisit>
    +acceptRequestVisit(int index) : void
    +removeRequestVisit(int index) : void

}

abstract class Property {
   - totalArea
   - commission
   - parkingSpotsNumber
   - photographs
    -salePrice
    -address
    -agent
   - rentPrice
   - owner
   - date
}
class Residence{
   - sunExposition
   - loftExistence
   - basementExistence
}

class Date{
    -int day
    -int month
    -int year
    -int hour
    -int minute
    -int[] maxDiasNumMes

    +static checkDateNewer(Date d1,Date d2 ) : boolean
    +static checkDateEqual(Date d1,Date d2 ) : boolean
    +static dateOnDuration(Date date, int duration) : Date
    +static boolean isAnoBissexto(int year) : boolean
}

abstract class Request{
    -totalArea
    -price
    -commission
    -address
    -agent
    -roomNumber
    -bathroomNumber
    -heatingExistence
    -airConditioningExistence
    -owner
   - date
   - sunExposition
    -loftExistence
   - basementExistence
   - tipoPropriedade
}

class RequestRent{

}
class RequestSale{

}

class Client{}

abstract class Person{
   - name
    -taxNumber
    -CCnumber
    -address
   - email
    -phoneNumber

}

class PropertyOwner{
    -client
}

class Address{
        -parish
       - postalCode
       - city
       - state
}

class Agent{}

class Store{
    -name
    -id
    -phoneNumber
   - email
    -address
}
class Employee{
    -agency
    -role
}

class Land {

}

class Apartment {
}

abstract class Habitable{
    -roomNumber
    -bathroomNumber
    -heatingExistence
    -airConditioningExistence
}

class Photograph{
    -uri
}

class ScheduleVisitController{
    +setStartDate() : Date
    +setStartDate() : Date
    +addNewScheduleVisitRequest() : boolean
    + requestYearMonthDayHourMin() : Date
}
class ScheduleVisitUI{
    +displayConfirmationMessage() : void
    + displayOptions() : void
    + askVisitDuration() : int
}




@enduml