/*This code was generated using the UMPLE modeling language!
 Date of generation: 2008/07/30 12:12:16*/
/*This class drives: Voter, Position, ElectoralDistrict*/

package ElectorialSystem.core;

import java.util.*;
import ElectorialSystem.*;
import ElectorialSystem.json.*;

public class ElectoralDistrict {
  //Class datatypes

  //Class association variables
  private List<Voter> voters;

  private List<Position> positions;

  private List<ElectoralDistrict> subDistricts;

  private ElectoralDistrict electoralDistrict;

  //Registry of our system.
  ElectorialSystemRegistry registry = ElectorialSystemRegistry.getInstance();

  //Constructor
  public ElectoralDistrict(ElectoralDistrict aElectoralDistrict) {
    voters = new ArrayList<Voter>();
    registry.add(voters);

    positions = new ArrayList<Position>();
    registry.add(positions);

    subDistricts = new ArrayList<ElectoralDistrict>();
    registry.add(subDistricts);

    electoralDistrict = aElectoralDistrict;
    electoralDistrict.addSubDistrict(this);

  }

  public List<Voter> getVoters() {
    return voters;
  }

  public List<Position> getPositions() {
    return positions;
  }

  public List<ElectoralDistrict> getSubDistricts() {
    return subDistricts;
  }

  public ElectoralDistrict getElectoralDistrict() {
    return electoralDistrict;
  }

  public Voter addVoter(String aName, String aAddress,
    PollInElection aPollInElection, ElectoralDistrict aElectoralDistrict) {
    Voter newVoter;
    newVoter = new Voter(aName, aAddress, aPollInElection, this);
    if (!voters.contains(newVoter)) {
      registry.add(newVoter);
      voters.add(newVoter);
    }
    return newVoter;
  }

  public Voter addVoter(Voter aVoter) {
    if (!voters.contains(aVoter))
      voters.add(aVoter);
    return aVoter;
  }

  public Position addPosition(String aDescription, ElectedBody aElectedBody) {
    Position newPosition;
    newPosition = new Position(aDescription, aElectedBody);
    if (!positions.contains(newPosition)) {
      registry.add(newPosition);
      positions.add(newPosition);
    }
    return newPosition;
  }

  public Position addPosition(Position aPosition) {
    if (!positions.contains(aPosition))
      positions.add(aPosition);
    return aPosition;
  }

  public ElectoralDistrict addSubDistrict() {
    ElectoralDistrict newElectoralDistrict;
    newElectoralDistrict = new ElectoralDistrict(this);
    if (!subDistricts.contains(newElectoralDistrict)) {
      registry.add(newElectoralDistrict);
      subDistricts.add(newElectoralDistrict);
    }
    return newElectoralDistrict;
  }

  public ElectoralDistrict addSubDistrict(ElectoralDistrict aSubDistrict) {
    if (!subDistricts.contains(aSubDistrict))
      subDistricts.add(aSubDistrict);
    return aSubDistrict;
  }

  /* This class does not drive ElectoralDistrict and therefore sets the association unidirectionally.*/
  public void setElectoralDistrict(ElectoralDistrict aElectoralDistrict) {
    electoralDistrict = aElectoralDistrict;
  }

  public void delete() {
    //Delete all many ends first.
    for (Voter aVoter : voters) {
      aVoter.delete();
    }
    voters.clear();

    //Delete all many ends first.
    for (Position aPosition : positions) {
      aPosition.delete();
    }
    positions.clear();

    //Delete all many ends first.
    for (ElectoralDistrict aElectoralDistrict : subDistricts) {
      aElectoralDistrict.delete();
    }
    subDistricts.clear();

    //Delete all 1 ends.
    electoralDistrict.deleteSubDistrict(this);
  }

  public void deleteVoter(Voter aVoter) {

    if (voters.contains(aVoter)) {
      voters.remove(aVoter);

      //registry.removeObj(registry.getKey(aVoter));
    } else
    //Throw an UmpleException .. to be implemented.
    {
    }
  }

  public void deletePosition(Position aPosition) {

    if (positions.contains(aPosition)) {
      positions.remove(aPosition);

      //registry.removeObj(registry.getKey(aPosition));
    } else
    //Throw an UmpleException .. to be implemented.
    {
    }
  }

  public void deleteSubDistrict(ElectoralDistrict aElectoralDistrict) {

    if (subDistricts.contains(aElectoralDistrict)) {
      subDistricts.remove(aElectoralDistrict);

      //registry.removeObj(registry.getKey(aElectoralDistrict));
    } else
    //Throw an UmpleException .. to be implemented.
    {
    }
  }

  public boolean areManyEndsNull() {
    if (voters.size() == 0 && positions.size() == 0 && subDistricts.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));
    return obj;
  }

}