
package de.ivu.elect.business.gruppe.entity;

import java.util.Collection;
import java.util.EnumSet;

import de.ivu.elect.business.gruppe.boundary.GruppeFactory;
import de.ivu.elect.business.gruppe.boundary.GruppenvereinigungFactory;
import de.ivu.elect.business.gruppe.boundary.PolitischeGruppeFactory;

public enum GruppeArt {

  PARTEI {

    @Override
    public Gruppe createGruppeInternal(GruppeFactory gruppeFactory, PolitischeGruppeFactory politischeGruppeFactory, GruppenvereinigungFactory gruppenvereinigungFactory) {
      return politischeGruppeFactory.create();
    }
  },
  WAEHLERGRUPPE {

    @Override
    public Gruppe createGruppeInternal(GruppeFactory gruppeFactory, PolitischeGruppeFactory politischeGruppeFactory, GruppenvereinigungFactory gruppenvereinigungFactory) {
      return politischeGruppeFactory.create();
    }
  },
  VEREINIGUNG {

    @Override
    public Gruppe createGruppeInternal(GruppeFactory gruppeFactory, PolitischeGruppeFactory politischeGruppeFactory, GruppenvereinigungFactory gruppenvereinigungFactory) {
      return politischeGruppeFactory.create();
    }
  },
  EINZELBEWERBER {

    @Override
    public Gruppe createGruppeInternal(GruppeFactory gruppeFactory, PolitischeGruppeFactory politischeGruppeFactory, GruppenvereinigungFactory gruppenvereinigungFactory) {
      return politischeGruppeFactory.create();
    }

    @Override
    public boolean isEinzelbewerber() {
      return true;
    }
  },
  REFERENDUM_VORLAGE {

    @Override
    public Gruppe createGruppeInternal(GruppeFactory gruppeFactory, PolitischeGruppeFactory politischeGruppeFactory, GruppenvereinigungFactory gruppenvereinigungFactory) {
      return politischeGruppeFactory.create();
    }
  },
  SYSTEM_GRUPPE {

    @Override
    public Gruppe createGruppeInternal(GruppeFactory gruppeFactory, PolitischeGruppeFactory politischeGruppeFactory, GruppenvereinigungFactory gruppenvereinigungFactory) {
      return gruppeFactory.create();
    }

    @Override
    public boolean isPolitischeGruppe() {
      return false;
    }
  };

  private static final EnumSet<GruppeArt> GRUPPE_ARTEN_POLITISCHE_GRUPPE = EnumSet.complementOf(EnumSet.of(SYSTEM_GRUPPE));

  private static final EnumSet<GruppeArt> GRUPPE_ARTEN_MIT_LISTENKANDIDATUREN = EnumSet.of(PARTEI, WAEHLERGRUPPE, VEREINIGUNG);

  public boolean isPolitischeGruppe() {
    return true;
  }

  public static Collection<GruppeArt> valuesPolitischeGruppeGruppeArt() {
    return GRUPPE_ARTEN_POLITISCHE_GRUPPE;
  }

  public static Collection<GruppeArt> valuesListenkandidaturGruppeArt() {
    return GRUPPE_ARTEN_MIT_LISTENKANDIDATUREN;
  }

  public static Collection<GruppeArt> getGruppeArtenMitListen() {
    return GRUPPE_ARTEN_MIT_LISTENKANDIDATUREN;
  }

  // TODO ELECT-396, Vererbungshierarchie mit dem Auflösen von Wahlvorschlagsträger noch sinnvoll?
  protected abstract Gruppe createGruppeInternal(GruppeFactory gruppeFactory, PolitischeGruppeFactory politischeGruppeFactory, GruppenvereinigungFactory gruppenvereinigungFactory);

  public Gruppe createGruppe(GruppeFactory gruppeFactory, PolitischeGruppeFactory politischeGruppeFactory, GruppenvereinigungFactory gruppenvereinigungFactory) {
    Gruppe result = createGruppeInternal(gruppeFactory, politischeGruppeFactory, gruppenvereinigungFactory);

    result.setGruppeArt(this);

    return result;
  }

  public boolean isEinzelbewerber() {
    return false;
  }
}
