/*This code was generated using the UMPLE modeling language!
 Date of generation: 2008/07/30 12:41:46*/
/*This class drives: DebitCard, Cheque*/

package BankingSystem.core;

import java.util.*;
import java.sql.Date;
import BankingSystem.*;
import BankingSystem.json.*;

public class BankAccount extends FinancialInstrument {
  //Class datatypes
  private String accountNumber;

  private String balance;

  private Float overdraftOrCreditLimit;

  //Class association variables
  private List<DebitCard> debitCards;

  private List<Cheque> cheques;

  private Branch branch;

  //Registry of our system.
  BankingSystemRegistry registry = BankingSystemRegistry.getInstance();

  //Constructor
  public BankAccount(String aAccountNumber, String aBalance,
    Float aOverdraftOrCreditLimit, Branch aBranch) {
    super();
    accountNumber = aAccountNumber;
    balance = aBalance;
    overdraftOrCreditLimit = aOverdraftOrCreditLimit;
    debitCards = new ArrayList<DebitCard>();
    registry.add(debitCards);

    cheques = new ArrayList<Cheque>();
    registry.add(cheques);

    branch = aBranch;
    branch.addBankAccount(this);

  }

  public boolean setAccountNumber(String aAccountNumber) {
    accountNumber = aAccountNumber;
    return true;
  }

  public boolean setBalance(String aBalance) {
    balance = aBalance;
    return true;
  }

  public boolean setOverdraftOrCreditLimit(Float aOverdraftOrCreditLimit) {
    overdraftOrCreditLimit = aOverdraftOrCreditLimit;
    return true;
  }

  public String getAccountNumber() {
    return accountNumber;
  }

  public String getBalance() {
    return balance;
  }

  public Float getOverdraftOrCreditLimit() {
    return overdraftOrCreditLimit;
  }

  public List<DebitCard> getDebitCards() {
    return debitCards;
  }

  public List<Cheque> getCheques() {
    return cheques;
  }

  public Branch getBranch() {
    return branch;
  }

  public DebitCard addDebitCard(String aNumber, String aPIN,
    FinancialInstitution aFinancialInstitution, Currency aCurrency,
    ArrayList<BankAccount> bankAccounts) {
    DebitCard newDebitCard;
    newDebitCard =
      new DebitCard(aNumber, aPIN, aFinancialInstitution, aCurrency,
        bankAccounts);
    if (!debitCards.contains(newDebitCard)) {
      registry.add(newDebitCard);
      debitCards.add(newDebitCard);
    }
    return newDebitCard;
  }

  public DebitCard addDebitCard(DebitCard aDebitCard) {
    if (!debitCards.contains(aDebitCard))
      debitCards.add(aDebitCard);
    return aDebitCard;
  }

  public Cheque addCheque(String aAmount, Date aDate, String aSequenceNumber,
    BankAccount aBankAccount) {
    Cheque newCheque;
    newCheque = new Cheque(aAmount, aDate, aSequenceNumber, this);
    if (!cheques.contains(newCheque)) {
      registry.add(newCheque);
      cheques.add(newCheque);
    }
    return newCheque;
  }

  public Cheque addCheque(Cheque aCheque) {
    if (!cheques.contains(aCheque))
      cheques.add(aCheque);
    return aCheque;
  }

  /* This class does not drive Branch and therefore sets the association unidirectionally.*/
  public void setBranch(Branch aBranch) {
    branch = aBranch;
  }

  public void delete() {
    //Delete all many ends first.
    for (DebitCard aDebitCard : debitCards) {
      aDebitCard.delete();
    }
    debitCards.clear();

    //Delete all many ends first.
    for (Cheque aCheque : cheques) {
      aCheque.delete();
    }
    cheques.clear();

    //Delete all 1 ends.
    branch.deleteBankAccount(this);
  }

  public void deleteDebitCard(DebitCard aDebitCard) {

    if (debitCards.contains(aDebitCard)) {
      debitCards.remove(aDebitCard);

      //registry.removeObj(registry.getKey(aDebitCard));
    } else
    //Throw an UmpleException .. to be implemented.
    {
    }
  }

  public void deleteCheque(Cheque aCheque) {

    if (cheques.contains(aCheque)) {
      cheques.remove(aCheque);

      //registry.removeObj(registry.getKey(aCheque));
    } else
    //Throw an UmpleException .. to be implemented.
    {
    }
  }

  public boolean areManyEndsNull() {
    if (debitCards.size() == 0 && cheques.size() == 0) {
      return true;
    } else
      return false;
  }

  /***********************************
   * Returns the attribute list along with the  
   * class ID in JSON format.
   ***********************************/
  public JSONObject getAttributes() throws JSONException {
    JSONObject obj = new JSONObject();
    obj.put("CLASS_ID", registry.getKey(this));
    obj.put("accountNumber", getAccountNumber());
    obj.put("balance", getBalance());
    obj.put("overdraftOrCreditLimit", getOverdraftOrCreditLimit());
    return obj;
  }

}