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

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

public class GebietPolygone implements Serializable {

  private Gebiet gebiet;

  private GebietPolygonPoint mittelpunkt;

  public GebietPolygone() {
    super();
  }

  public GebietPolygone(Gebiet gebiet, List<GebietPolygonPoint> gebietPolygonPoints) {
    setGebiet(gebiet);

    GebietPolygon gebietPolygon = null;

    for (GebietPolygonPoint gebietPolygonPoint : gebietPolygonPoints) {
      switch (gebietPolygonPoint.getGebietPolygonPointArt()) {
        case BEGINN:
          gebietPolygon = new GebietPolygon();
          getPolygonList().add(gebietPolygon);
          gebietPolygon.add(gebietPolygonPoint);
          break;
        case MITTELPUNKT:
          setMittelpunkt(gebietPolygonPoint);
          break;
        case PUNKT:
          if (gebietPolygon == null) {
            throw new IllegalStateException("Beginn erwartet, Punkt gefunden");
          }
          gebietPolygon.add(gebietPolygonPoint);
          break;
        default:
          throw new IllegalStateException("Unbekannte GebietPolygonPointArt:" + gebietPolygonPoint.getGebietPolygonPointArt());
      }
    }
  }

  private List<GebietPolygon> polygonList = new ArrayList<>();

  public List<GebietPolygon> getPolygonList() {
    return polygonList;
  }

  public GebietPolygonPoint getMittelpunkt() {
    return mittelpunkt;
  }

  public void setMittelpunkt(GebietPolygonPoint mittelpunkt) {
    this.mittelpunkt = mittelpunkt;
  }

  public Gebiet getGebiet() {
    return gebiet;
  }

  public void setGebiet(Gebiet gebiet) {
    this.gebiet = gebiet;
  }

  public GebietPolygone merge(GebietPolygone gebietPolygone, Gebiet zielgebiet) {

    List<GebietPolygonPoint> gebietPolygonPoints = new ArrayList<>();
    GebietPolygone result = new GebietPolygone(zielgebiet, gebietPolygonPoints);

    GebietPolygonPoint neuerMitelpunkt = new GebietPolygonPoint();
    neuerMitelpunkt.setLatLng(GebietPolygonPoint.berechneMitteLatLng(gebietPolygonPoints));
    neuerMitelpunkt.setPosition(0L);
    neuerMitelpunkt.setGebiet(zielgebiet);
    neuerMitelpunkt.setGebietPolygonPointArt(GebietPolygonPointArt.MITTELPUNKT);
    result.setMittelpunkt(neuerMitelpunkt);
    return result;
  }

  public List<GebietPolygonPoint> getGebietPolygonPoints() {
    List<GebietPolygonPoint> result = new ArrayList<>();

    if (mittelpunkt != null) {
      result.add(mittelpunkt);
    }
    for (GebietPolygon gebietPolygon : polygonList) {
      result.addAll(gebietPolygon.getGebietPolygonPointListReadOnly());
    }
    return result;
  }

  public String getName() {
    if (getGebiet() == null) {
      return null;
    }
    return getGebiet().getName();
  }

}
