
package de.ivu.elect.exchange.veranstaltung;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import de.ivu.elect.business.anschrift.boundary.AnschriftFactory;
import de.ivu.elect.business.gebietsbaum.entity.Gebiet;
import de.ivu.elect.business.person.boundary.PersonendatenFactory;
import de.ivu.elect.business.veranstaltung.boundary.VeranstaltungFactory;
import de.ivu.elect.exchange.EntityMapper;
import de.ivu.elect.exchange.anschrift.mapper.AnschriftMapper;
import de.ivu.elect.exchange.gebietsbaum.mapper.GebietMapper;
import de.ivu.elect.exchange.person.mapper.PersonMapper;
import de.ivu.elect.interfaces.core.GebietReferenz;
import de.ivu.elect.interfaces.core.SchulungArt;
import de.ivu.elect.interfaces.core.Veranstaltung;
import de.ivu.elect.interfaces.core.VeranstaltungArt;
import de.ivu.elect.interfaces.core.VeranstaltungReferenz;
import de.ivu.elect.interfaces.core.VeranstaltungStatus;

public class VeranstaltungMapper {

  @Inject
  protected transient AnschriftMapper anschriftMapper;

  @Inject
  protected transient PersonMapper personMapper;

  @Inject
  protected transient GebietMapper gebietMapper;

  @Inject
  protected transient AnschriftFactory anschriftFactory;

  @Inject
  protected transient PersonendatenFactory personendatenFactory;

  @Inject
  protected transient VeranstaltungFactory veranstaltungFactory;

  public VeranstaltungMapper() {
    super();
  }

  public Collection< ? extends Veranstaltung> mapVeranstaltung(List<de.ivu.elect.business.veranstaltung.entity.Veranstaltung> internList) {
    List<Veranstaltung> externList = new ArrayList<>();

    for (de.ivu.elect.business.veranstaltung.entity.Veranstaltung intern : internList) {
      Veranstaltung extern = new Veranstaltung();

      extern.setVeranstaltungReferenz(mapVeranstaltungReferenz(intern));
      extern.setBeginn(intern.getBeginn());
      extern.setBemerkung(intern.getBemerkung());
      extern.setBezeichnung(intern.getBezeichnung());
      extern.setEnde(intern.getEnde());
      extern.setExterneId(intern.getExterneId());
      extern.setVeranstaltungArt(map(intern.getVeranstaltungArt()));
      extern.setVeranstaltungStatus(map(intern.getVeranstaltungStatus()));
      extern.setSchulungArt(map(intern.getSchulungArt()));
      extern.setVerknuepfteVeranstaltungReferenz(mapVeranstaltungReferenz(intern.getVerknuepfteVeranstaltung()));
      extern.setGebietReferenz(mapGebietReferenz(intern.getGebiet()));
      extern.setCustomData(intern.getCustomDataXml());
      extern.setVeranstaltungOrt(intern.getVeranstaltungOrt());
      extern.setRaumBezeichnung(intern.getRaumBezeichnung());

      anschriftMapper.extern(intern.getAnschrift(), extern.getAnschrift());
      personMapper.extern(intern.getAnsprechpartner(), extern.getAnsprechpartner());

      externList.add(extern);
    }

    return externList;
  }

  public Map<VeranstaltungReferenz, de.ivu.elect.business.veranstaltung.entity.Veranstaltung> mapVeranstaltungen(List<Veranstaltung> externList, Map<GebietReferenz, Gebiet> gebieteNachReferenz) {
    Map<VeranstaltungReferenz, de.ivu.elect.business.veranstaltung.entity.Veranstaltung> internByReferenz = new HashMap<>();

    for (Veranstaltung extern : externList) {
      de.ivu.elect.business.veranstaltung.entity.Veranstaltung intern = veranstaltungFactory.create();

      intern.setBeginn(extern.getBeginn());
      intern.setBemerkung(extern.getBemerkung());
      intern.setBezeichnung(extern.getBezeichnung());
      intern.setEnde(extern.getEnde());
      intern.setExterneId(extern.getExterneId());
      intern.setVeranstaltungArt(map(extern.getVeranstaltungArt()));
      intern.setVeranstaltungStatus(map(extern.getVeranstaltungStatus()));
      intern.setSchulungArt(map(extern.getSchulungArt()));
      intern.setGebiet(gebietMapper.mapGebietReferenz(extern.getGebietReferenz(), gebieteNachReferenz));
      intern.setVeranstaltungOrt(extern.getVeranstaltungOrt());
      intern.setRaumBezeichnung(extern.getRaumBezeichnung());

      intern.setAnschrift(anschriftFactory.create());
      anschriftMapper.intern(extern.getAnschrift(), intern.getAnschrift());

      intern.setAnsprechpartner(personendatenFactory.create());
      personMapper.intern(extern.getAnsprechpartner(), intern.getAnsprechpartner());

      internByReferenz.put(extern.getVeranstaltungReferenz(), intern);
    }

    for (Veranstaltung extern : externList) {
      if (extern.getVerknuepfteVeranstaltungReferenz() != null) {
        de.ivu.elect.business.veranstaltung.entity.Veranstaltung intern = internByReferenz.get(extern.getVeranstaltungReferenz());
        de.ivu.elect.business.veranstaltung.entity.Veranstaltung internVerknuepft = internByReferenz.get(extern.getVerknuepfteVeranstaltungReferenz());

        intern.setVerknuepfteVeranstaltung(internVerknuepft);
      }
    }

    return internByReferenz;
  }

  private VeranstaltungReferenz mapVeranstaltungReferenz(de.ivu.elect.business.veranstaltung.entity.Veranstaltung intern) {
    if (intern != null) {
      VeranstaltungReferenz extern = new VeranstaltungReferenz();
      extern.setId(EntityMapper.createIdInDatei(intern));

      return extern;
    }

    return null;
  }

  private GebietReferenz mapGebietReferenz(Gebiet intern) {
    if (intern != null) {
      return gebietMapper.mapGebietReferenz(intern);
    }

    return null;
  }

  public SchulungArt map(de.ivu.elect.business.veranstaltung.entity.SchulungArt intern) {
    if (intern != null) {
      return SchulungArt.valueOf(intern.name());
    }

    return null;
  }

  VeranstaltungArt map(de.ivu.elect.business.veranstaltung.entity.VeranstaltungArt intern) {
    return VeranstaltungArt.valueOf(intern.name());
  }

  VeranstaltungStatus map(de.ivu.elect.business.veranstaltung.entity.VeranstaltungStatus intern) {
    return VeranstaltungStatus.valueOf(intern.name());
  }

  public de.ivu.elect.business.veranstaltung.entity.SchulungArt map(de.ivu.elect.interfaces.core.SchulungArt extern) {
    if (extern != null) {
      return de.ivu.elect.business.veranstaltung.entity.SchulungArt.valueOf(extern.name());
    }

    return null;
  }

  de.ivu.elect.business.veranstaltung.entity.VeranstaltungArt map(de.ivu.elect.interfaces.core.VeranstaltungArt extern) {
    return de.ivu.elect.business.veranstaltung.entity.VeranstaltungArt.valueOf(extern.name());
  }

  de.ivu.elect.business.veranstaltung.entity.VeranstaltungStatus map(de.ivu.elect.interfaces.core.VeranstaltungStatus extern) {
    return de.ivu.elect.business.veranstaltung.entity.VeranstaltungStatus.valueOf(extern.name());
  }
}
