Public MustInherit Class Building
  ' This is the base class, from which we derive the
  ' apartment, commercial, and home classes.

  ' =============== Symbolic Constants ================
  Private Const APARTMENT As Integer = 0
  Private Const COMMERCIAL As Integer = 1
  Private Const HOME As Integer = 2

  ' Default snow removal phone numbers
  Public Const APTPHONE As String = "555-1000"
  Public Const COMPHONE As String = "555-2000"
  Public Const HOMPHONE As String = "555-3000"

  ' ================== Data Members ==================

  Private mAddress As String          ' Street address
  Private mPrice As Double            ' Purchase price
  Private mMonthlyPayment As Double   ' Monthly payment
  Private mTaxes As Double            ' Annual taxes
  Private mType As Integer            ' Building type
  Private mSnowPhone As String        ' Who to call for snow removal

  ' ================== Constructor ==================
  Public Sub New()
    Address = "Empty building"
  End Sub


  ' ==================== Properties ======================
  Public Property Address() As String            ' Address Property
    Get
      Return mAddress
    End Get

    Set(ByVal Value As String)
      mAddress = Value
    End Set
  End Property

  Public Property PurchasePrice() As Double    ' Purchase Price Property
    Get
      Return mPrice
    End Get

    Set(ByVal Value As Double)
      mPrice = Value
    End Set
  End Property

  Public Property MonthlyPayment() As Double   ' Monthly Payment Property
    Get
      Return mMonthlyPayment
    End Get

    Set(ByVal Value As Double)
      mMonthlyPayment = Value
    End Set
  End Property

  Public Property Taxes() As Double            ' Property Taxes Property
    Get
      Return mTaxes
    End Get

    Set(ByVal Value As Double)
      mTaxes = Value
    End Set
  End Property

  Public Property BuildingType() As Integer     ' Building Type Property
    Get
      Return mType
    End Get

    Set(ByVal Value As Integer)
      If Value < APARTMENT Or Value > HOME Then
        mType = -1    ' an error
      Else
        mType = Value
      End If
    End Set
  End Property

  Public Property SnowRemoval() As String       ' Call for snow removal
    Get
      Return mSnowPhone
    End Get
    Set(ByVal Value As String)
      mSnowPhone = Value
    End Set
  End Property

  ' ========================== Methods ========================

  ' Force the derived classes to figure out who to call.
  Public MustOverride Function CallSnowRemoval() As String

  Protected Sub DisplayBaseInfo()
    Dim BldType As String

    ' Purpose:  To display the base member data
    Select Case mType             ' Which type of building?
      Case APARTMENT
        BldType = "Apartment"
      Case COMMERCIAL
        BldType = "Commercial"
      Case HOME
        BldType = "Home"
    End Select
    Console.WriteLine()
    Console.WriteLine("----------  " & BldType & "  -----------")
    Console.WriteLine("Address: " & mAddress)
    Console.WriteLine("Purchase Price: " & FormatMoney(mPrice))
    Console.WriteLine("Monthly Payment: " & FormatMoney(mMonthlyPayment))
    Console.WriteLine("Property Taxes: " & FormatMoney(mTaxes))
    Console.WriteLine("Building Type: " & BldType)
    Console.WriteLine("Snow removal Phone: " & mSnowPhone)
    Console.WriteLine()
  End Sub

  ' =========================== Helpers =========================
  Protected Function FormatMoney(ByVal num As Double) As String
    ' Purpose:  To format a dollar value
    '
    ' Argument list:
    '   num         A double that is the dollar value to format
    '
    ' Return value:
    '   string      A format dollar value string

    Return Format(num, "$#,###,###,###.00")
  End Function
End Class

' ++++++++++++++++++++++++++++ Apartment Class ++++++++++++++++++++++++
Public Class Apartment
  Inherits Building

  Private mUnits As Integer     ' The number of apartments
  Private mRent As Double       ' Rent per unit
  Private mOccupRate As Double  ' Occupance rate for building

  Public Sub New()

  End Sub

  ' Constructor with initializer list of arguments
  Public Sub New(ByVal Addr As String, ByVal Price As Double, ByVal Payment As Double, ByVal Taxes As Double, ByVal Bldg As Integer, ByVal SnowPhone As String)
    MyBase.Address = Addr
    MyBase.PurchasePrice = Price
    MyBase.MonthlyPayment = Payment
    MyBase.Taxes = Taxes
    MyBase.BuildingType = Bldg
    If SnowPhone = "" Then
      MyBase.SnowRemoval = APTPHONE
    Else
      MyBase.SnowRemoval = SnowPhone
    End If
  End Sub

  ' ==================== Properties ======================

  Public Property Units()       ' Units
    Get
      Return mUnits
    End Get
    Set(ByVal Value)
      mUnits = Value
    End Set
  End Property

  Public Property Rents()       ' Rents
    Get
      Return mRent
    End Get
    Set(ByVal Value)
      mRent = Value
    End Set
  End Property

  Public Property OccupancyRate() As Double ' Occupancy rate
    Get
      Return mOccupRate
    End Get
    Set(ByVal Value As Double)
      mOccupRate = Value
    End Set
  End Property

  ' ============== Methods ==================
  Public Overrides Function CallSnowRemoval() As String
    ' Purpose:  This routine is called to remove snow for an Apartment.
    '        
    Return "Apartment snow removal: " & MyBase.SnowRemoval
  End Function

  Public Sub DisplayBuilding()

    DisplayBaseInfo()
    Console.WriteLine("           Apartment members:")
    Console.WriteLine("Number of Units: " & mUnits)
    Console.WriteLine("Rent per Unit: " & FormatMoney(mRent))
    Console.WriteLine("Occupancy Rate: " & mOccupRate)
  End Sub
End Class

' ++++++++++++++++++++++++++++ Commercial Class ++++++++++++++++++++++++++++

Public Class Commercial
  Inherits Building

  Private mSquareFeet As Integer    ' Rentable square feet
  Private mRentPerSF As Double      ' Rent per square foot
  Private mParking As Integer       ' Parking spots

  Public Sub New()    ' Constructor with no arguments

  End Sub

  Public Sub New(ByVal Addr As String, ByVal Price As Double, ByVal Payment As Double, ByVal Taxes As Double, ByVal Bldg As Integer, ByVal SnowPhone As String)
    MyBase.Address = Addr
    MyBase.PurchasePrice = Price
    MyBase.MonthlyPayment = Payment
    MyBase.Taxes = Taxes
    MyBase.BuildingType = Bldg
    If SnowPhone = "" Then
      MyBase.SnowRemoval = COMPHONE
    Else
      MyBase.SnowRemoval = SnowPhone
    End If
  End Sub
  ' ==================== Properties ======================
  Public Property SquareFeet()      ' Square feet
    Get
      Return mSquareFeet
    End Get
    Set(ByVal Value)
      mSquareFeet = Value
    End Set
  End Property

  Public Property RentPerSF()       ' Rent per square foot
    Get
      Return mRentPerSF
    End Get
    Set(ByVal Value)
      mRentPerSF = Value
    End Set
  End Property

  Public Property ParkingSpots()    ' Parking spots
    Get
      Return mParking
    End Get
    Set(ByVal Value)
      mParking = Value
    End Set
  End Property

  ' ============== Methods ==================
  Public Overrides Function CallSnowRemoval() As String
    ' Purpose:  This routine is called to remove snow for a Commercial building.
    '           
    Return "Commercial snow removal: " & MyBase.SnowRemoval
  End Function

  Public Sub DisplayBuilding()
    DisplayBaseInfo()               ' Call base class
    Console.WriteLine("           Commercial members:")
    Console.WriteLine("Square Feet: " & mSquareFeet)
    Console.WriteLine("Rent per SF: " & FormatMoney(mRentPerSF))
    Console.WriteLine("Parking Spots: " & mParking)
  End Sub
End Class

' ++++++++++++++++++++++++++++ Home Class ++++++++++++++++++++++++++++

Public NotInheritable Class Home
  Inherits Building

  Private mSquareFeet As Integer      ' Home's square feet
  Private mRentPerMonth As Double     ' Rent per month
  Private mBedrooms As Integer        ' Number of bedrooms
  Private mBaths As Integer           ' Number of bathrooms

  ' ==================== Properties ======================
  Public Sub New()    ' Constructor with no arguments

  End Sub

  Public Sub New(ByVal Addr As String, ByVal Price As Double, ByVal Payment As Double, ByVal Taxes As Double, ByVal Bldg As Integer, ByVal SnowPhone As String)
    MyBase.Address = Addr
    MyBase.PurchasePrice = Price
    MyBase.MonthlyPayment = Payment
    MyBase.Taxes = Taxes
    MyBase.BuildingType = Bldg
    If SnowPhone = "" Then
      MyBase.SnowRemoval = HOMPHONE
    Else
      MyBase.SnowRemoval = SnowPhone
    End If

  End Sub

  Public Property SquareFeet()        ' Square feet
    Get
      Return mSquareFeet
    End Get
    Set(ByVal Value)
      mSquareFeet = Value
    End Set
  End Property

  Public Property Rent()              ' Rent
    Get
      Return mRentPerMonth
    End Get
    Set(ByVal Value)
      mRentPerMonth = Value
    End Set
  End Property

  Public Property Bedrooms()          ' Bedrooms
    Get
      Return mBedrooms
    End Get
    Set(ByVal Value)
      mBedrooms = Value
    End Set
  End Property

  Public Property Baths()             ' Baths
    Get
      Return mBaths
    End Get
    Set(ByVal Value)
      mBaths = Value
    End Set
  End Property

  ' ============== Methods ==================
  Public Overrides Function CallSnowRemoval() As String
    ' Purpose:  This routine is called to remove snow for an apartment.
    '           
    Return "Home snow removal: " & MyBase.SnowRemoval
  End Function

  Public Sub DisplayBuilding()

    MyBase.DisplayBaseInfo()               ' Call base class
    '    Console.WriteLine("Building Type: Home")
    Console.WriteLine("           Home members:")
    Console.WriteLine("Square Feet: " & mSquareFeet)
    Console.WriteLine("Rent per Month: " & FormatMoney(mRentPerMonth))
    Console.WriteLine("Bedrooms: " & mBedrooms)
    Console.WriteLine("Baths: " & mBaths)
  End Sub
End Class