class CreateOverlayModal implements Modal {

  constructor() {
    const _this = this;
    const closeBtn = document.getElementById("createOverlay-closeBtn");
    if (closeBtn) {
      closeBtn.onclick = ()=>{_this.setVisible(false)};
    }
    const s = this.self();
    if (s) {
      s.onsubmit = (e: any): void => {
        e.preventDefault();
      }
    }
  }

  self(): HTMLElement | null {
    return document.getElementById("createOverlay-container");
  }
  
  title(): HTMLElement | null{
    return document.getElementById("createOverlay-title");
  }
  
  content(): HTMLElement | null {
    return document.getElementById("createOverlay-content");
  }
  
  submitBtn(): HTMLElement | null {
    return document.getElementById("createOverlay-submitBtn");
  }
  
  radiusContainer(): HTMLElement | null {
    return document.getElementById("radius-container");
  }
  
  setName(name: string): void {
    const self = document.getElementById("createOverlay-name") as HTMLInputElement;
    if (self) {
      self.value = name;
    }
  }
  
  setDesc(desc: string): void {
    const self = document.getElementById("createOverlay-desc") as HTMLInputElement;
    if (self) {
      self.value = desc;
    }
  }
  
  setRadius(radius: Number) {
    const self = document.getElementById("createOverlay-radius") as HTMLInputElement;
    if (self) {
      self.value = String(radius);
    }
  }
  
  nameField(): string { 
    return (document.getElementById("createOverlay-name") as HTMLInputElement)?.value ?? "";
  }
  
  descField(): string {
    return (document.getElementById("createOverlay-desc") as HTMLInputElement)?.value ?? "";
  }

  radiusField(): string {
    return (document.getElementById("createOverlay-radius") as HTMLInputElement)?.value ?? "";
  }

  visible(): boolean {
    return this.self()?.style.display != "none";
  }
  
  setVisible(v: boolean): void {
    const modal = this.self();
    if (modal) {
      modal.style.display = v ? "block" : "none";
    }
  }
  
  setExtraButtonsVisible(v: boolean): void {
    const extraBtns = document.getElementById("edit-extra-btns");
    if (extraBtns) {
      extraBtns.style.display = v ? "inline" : "none";
    }
  }
  
  gotoBtn(): HTMLElement | null {
    return document.getElementById("goto-btn");
  }
  
  exportBtn(): HTMLElement | null {
    return document.getElementById("export-btn");
  }
  
  deleteBtn(): HTMLElement | null {
    return document.getElementById("delete-btn");
  }
  
  clearInputs(): void {
    const name = document.getElementById("createOverlay-name") as HTMLInputElement;
    const desc = document.getElementById("createOverlay-desc") as HTMLInputElement;
    const radius = document.getElementById("createOverlay-radius") as HTMLInputElement;
    
    if (name?.value) {
      name.value = "";
    }
    if (desc?.value) {
      desc.value = "";
    }
    if (Number(radius?.value) != 500) {
      radius.value = "500";
    }
  }
  
  setState(state: OverlayType, args: any): void {
    const _this = this;
    const title = this.title()
    const radiusContainer = _this.radiusContainer();
    const submitBtn = _this.submitBtn();
    
    _this.clearInputs();
    if (radiusContainer) {
      radiusContainer.style.display = state == OverlayType.CIRCLE ? "block" : "none";
    }
    const editing = args.self ? true : false;
    this.setExtraButtonsVisible(editing);
    if (editing) {
      const gotoBtn = this.gotoBtn();
      const exportBtn = this.exportBtn();
      const deleteBtn = this.deleteBtn();
      
      if (title) {
        switch (state) {
          case OverlayType.POINT:
            title.innerHTML = "Edit Marker ";
            break;
          case OverlayType.CIRCLE:
            title.innerHTML = "Edit Circle ";
            break;
          case OverlayType.POLYGON:
            title.innerHTML = "Edit Polygon ";
            break;
        }
      }
      
      if (gotoBtn) {
        gotoBtn.onclick = () => {
          _this.setVisible(false);
          args.map.setView(args.self.center());
        }
      }
      
      if (exportBtn) {
        exportBtn.onclick = () => {
          MapHandler.exportSingle(args.self);
        }
      }
      
      if (deleteBtn) {
        deleteBtn.onclick = () => {
          MapHandler.confirmDelete(args.self as OverlayBase);
        }
      }
      
      this.setName(args.self.name);
      this.setDesc(args.self.desc);
      if (state == OverlayType.CIRCLE) {
        this.setRadius(args.self.options.radius);
      }
      
      if (submitBtn) {
        submitBtn.onclick = () => {
          const name = TextUtils.encodeHTML(_this.nameField());
          const desc = TextUtils.encodeHTML(_this.descField());
          if (name.trim().length < 1) {
            return;
          }
          
          args.self.name = name;
          args.self.desc = desc;
          args.self.setPopupContent(`<h3>${name}</h3><p>${desc}</p>`);
          _this.setVisible(false);
        }
      }
    } else {  
    
    switch (state) {
      case OverlayType.POINT:
        if (title) {
          title.innerHTML = "Add Marker ";
        }

        if (submitBtn) {
          submitBtn.onclick = () => {
            const name = TextUtils.encodeHTML(_this.nameField());
            const desc = TextUtils.encodeHTML(_this.descField());
            if (name.trim().length < 1) {
              return;
            }
            const point = new Marker(name, desc, args.latlng, {title: name, alt: name});
            point.add(args.map);
            args.overlays.markers.push(point);
            _this.setVisible(false);
          }
        }
        break;
      case OverlayType.CIRCLE:
        if (title) {
          title.innerHTML = "Add Circle ";
        }
        if (submitBtn) {
          submitBtn.onclick = () => {
            const radius = _this.radiusField();
            const name = TextUtils.encodeHTML(_this.nameField());
            const desc = TextUtils.encodeHTML(_this.descField());
            if (name.trim().length < 1) {
              return;
            }
            const circle = new Circle(name, desc, args.latlng, {radius: Number(radius) || 500});
            circle.add(args.map);
            args.overlays.circles.push(circle);
            _this.setVisible(false);
          }
        }
        break;
      case OverlayType.POLYGON:
        if (title) {
          title.innerHTML = "Add Polygon ";
        }
        if (submitBtn) {
          submitBtn.onclick = () => {
            const name = TextUtils.encodeHTML(_this.nameField());
            const desc = TextUtils.encodeHTML(_this.descField());
            if (name.trim().length < 1) {
              return;
            }
            const polygon = new Polygon(name, desc, args.points, {});
            polygon.add(args.map);
            args.overlays.polygons.push(polygon);
            _this.setVisible(false);
          }
        }
        break;
    }
    }
    if (title) {
      title.innerHTML += OverlayBase.centerAsString(args.self ? args.self.center() : (state === OverlayType.POLYGON ? args.overlays.polyline.center() : args.latlng));
    }
  }
}