import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* A class that represents a smart phone card for Australia, New Zealand, and
* Asia. For SmartANZAsia10 phone cards, only calls to Australia, New Zealand,
* and Asia. are allowed. For calls to Australia and New Zealand the cost per
* minute is $0.25, and for calls to Asia the cost per minute is $0.20. The
* initial balance on the card is $10.00. The weekly fees are $0.50.
*
*
* Each card also keeps track of the history of the charges made to the card. As
* an example, a brand new card would have a empty charge history of { }. If the
* card was used to call Australia for 10 minutes, its charge history would be {
* 2.50 }. If the card was then used to call Asia for 20 minutes, its charge
* history would be { 2.50, 4.00 }. Finally, after deducting the first week of
* fees, its charge history would be { 2.50, 4.00, 0.50 }.
*
* @author CSE1030
*
*/
public class SmartANZAsia10Card extends PhoneCard
{
/**
* The initial balance for SmartANZAsia10 cards.
*/
public static final double INITIAL_BALANCE = 10.0;
/**
* The weekly fee for SmartANZAsia10 cards.
*/
public static final double WEEKLY_FEES = 0.5;
/**
* The cost per minute for calls to Australia and New Zealand for
* SmartANZAsia10 cards.
*/
public static final double COST_PER_MIN_TO_ANZ = 0.25;
/**
* The cost per minute for calls to Asia for SmartANZAsia10 cards.
*/
public static final double COST_PER_MIN_TO_ASIA = 0.20;
private List chargeHistory;
/**
* Create a SmartANZAsia10Card phone card with the given number and
* password. Sets the charge history of the card to empty.
*
* @param number
* The phone card's number.
* @param password
* The phone card's password.
* @pre. number and password are positive
*/
public SmartANZAsia10Card(long number, int password)
{
super(number, password, SmartANZAsia10Card.INITIAL_BALANCE);
this.chargeHistory = new ArrayList();
}
/**
* Create a copy of the given SmartANZAsia10Card.
* A deep copy is returned.
*
* @param card the card to make a copy of.
*/
public SmartANZAsia10Card(SmartANZAsia10Card card)
{
this(card.getNumber(), card.getPassword());
this.setBalance(card.getBalance());
this.chargeHistory = card.getChargeHistory();
}
/**
* Get the history of charges as a List. The client can modify the returned
* List without changing the state of the card.
*
* @return A List containing the charge history of the card.
*/
public List getChargeHistory()
{
return new ArrayList(this.chargeHistory);
}
/**
* Get the set of call zones that can be called on this phone card. For
* SmartANZAsia10 phone cards, only calls to Australia, New Zealand, and
* Asia are allowed.
*
* @return the set of call zones.
*/
@Override
public Set allowedZones()
{
Set allowedZonesSet = new HashSet();
allowedZonesSet.add(CallZone.ANZ);
allowedZonesSet.add(CallZone.ASIA);
return allowedZonesSet;
}
/**
* Get the cost per minute of a call to the argument zone on this phone
* card.
*
* @param zone
* The call zone to find the cost for.
* @return The cost per minute to call the given call zone.
* @pre. a call to zone is allowed for this card.
*
*/
@Override
public double costPerMin(CallZone zone)
{
assert this.isAllowed(zone);
if (zone == CallZone.ANZ)
{
return SmartANZAsia10Card.COST_PER_MIN_TO_ANZ;
}
else
{
return SmartANZAsia10Card.COST_PER_MIN_TO_ASIA;
}
}
/**
* Deduct the appropriate weekly fees from the card's balance. If the
* balance is insufficient, the balance becomes 0. Updates the charge
* history with the amount deducted from the card's balance.
*
*/
@Override
public void deductWeeklyFee()
{
double theCharge = SmartANZAsia10Card.WEEKLY_FEES;
if (theCharge > this.getBalance())
{
theCharge = this.getBalance();
}
this.setBalance(this.getBalance() - theCharge);
this.chargeHistory.add(theCharge);
}
/**
* Check whether a call to the argument zone is allowed for this phone card.
* For SmartANZAsia10 phone cards, only calls to Australia, New Zealand, and
* Asia are allowed.
*
* @param zone
* the call zone to check.
* @return true if the card supports the call zone; false otherwise.
*/
@Override
public boolean isAllowed(CallZone zone)
{
return zone.equals(CallZone.ANZ) || zone.equals(CallZone.ASIA);
}
/**
* Charge a call of the given number of minutes to the zone.
* This method tries to charge a
* call to zone with the given number of minutes to the card; if the balance
* is sufficient to cover it, it returns true and if the balance is not
* sufficient, it leaves it unchanged and returns false. When a call is charged
* to the balance, the charge is recorded in the charge history of the card.
*
* @param minutes
* the number of minutes to charge.
* @param zone
* the zone that the call is going to.
* @return true if the balance was sufficient to pay for the call, and false
* otherwise.
* @pre. minutes is positive and a call to zone is allowed for this card.
*/
@Override
public boolean charge(int minutes, CallZone zone)
{
assert minutes > 0 && this.isAllowed(zone);
final double theCharge = minutes * this.costPerMin(zone);
if (theCharge > this.getBalance())
{
return false;
}
else
{
this.setBalance(this.getBalance() - theCharge);
this.chargeHistory.add(theCharge);
return true;
}
}
/**
* Compares the card with another object for equality. Two cards are equal
* if and only if their PhoneCard sub-objects are equal and their charge
* histories are equal.
*
* @param obj
* the object to compare with for equality.
* @return true if the card and object are equal; false otherwise.
*
*/
@Override
public boolean equals(Object obj)
{
boolean eq = super.equals(obj);
if (eq)
{
SmartANZAsia10Card other = (SmartANZAsia10Card) obj;
if (!this.getChargeHistory().equals(other.getChargeHistory()))
{
eq = false;
}
}
return eq;
}
}