import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from "@angular/router";
import { Server } from "../../../../server";
import { ServerModel } from "../../../../models/atlasData/server.model";
import { IslandDataModel } from "../../../../../data/models/island-data.model";
import { IslandInstanceModel } from "../../../../models/atlasData/island-instance.model";
import { ServerSublevelModel } from "../../../../models/atlasData/serverSublevel.model";
import { DiscoveryZoneModel } from "../../../../models/atlasData/discovery-zone.model";

@Component({
  selector: 'app-server',
  templateUrl: './server.component.html'
})
export class ServerComponent implements OnInit {
  private cell: ServerModel;
  private templateOptions: string[];
  private islandOptions: object = {};
  private newIslandName: string;

  constructor(private server: Server, private route: ActivatedRoute) {
  }

  ngOnInit() {
    let index = this.route.snapshot.paramMap.get('index');
    this.cell = this.server.serverGrid.servers[index];
    this.templateOptions = this.server.serverGrid.serverTemplates.map(i => i.name);
    Object.values(this.server.islands.islandData).forEach((i: IslandDataModel) => {this.islandOptions[i.name] = i.customDisplayName()});
  }

  private changeIslandModel(index: number, name: string) {
    let oldIsland = this.cell.islandInstances[index];
    let newIsland = IslandInstanceModel.fromIslandData(this.server.islands[name]);
    newIsland.id = this.server.serverGrid.getNextId();

    // keep X, Y and Rotation the same
    newIsland.worldX = oldIsland.worldX;
    newIsland.worldY = oldIsland.worldY;
    newIsland.rotation = oldIsland.rotation;

    this.removeSublevelsForIsland(oldIsland);
    this.addSublevelsForIsland(newIsland);
    this.cell.islandInstances[index] = newIsland;
    this.updateExtraSublevels();
  }

  private removeSublevelsForIsland(island: IslandInstanceModel) {
    const islandData = this.server.islands[island.name];
    islandData.sublevelNames.forEach(i => {
      const j = this.cell.sublevels.findIndex(sublevel => sublevel.name === i);
      if (j > -1) {
        this.cell.sublevels.splice(j, 1);
      }
    });
  }

  private addSublevelsForIsland(island: IslandInstanceModel) {
    const islandData = this.server.islands[island.name];
    islandData.sublevelNames.forEach(i => {
      let newSublevel = new ServerSublevelModel();
      newSublevel.name = i;
      newSublevel.setupFromIsland(island, islandData, this.cell, this.server.serverGrid);
      this.cell.sublevels.push(newSublevel);
    });
  }

  private updateExtraSublevels() {
    // Extra Sublevels can be identical across multiple islands,
    // so need to merge any changes. Easiest to just merge through
    // all of the available islands instead.
    this.cell.totalExtraSublevels = [];
    this.cell.islandInstances.forEach(i => {
      const islandData = this.server.islands[i.name];
      islandData.extraSublevels.forEach(j => {
        if (this.cell.totalExtraSublevels.indexOf(j) === -1) {
          this.cell.totalExtraSublevels.push(j);
        }
      });
    });
  }

  addNewIsland() {
    const newIslandData = this.server.islands[this.newIslandName];
    let newIsland = IslandInstanceModel.fromIslandData(newIslandData);
    newIsland.id = this.server.serverGrid.getNextId();
    this.addSublevelsForIsland(newIsland);
    this.cell.islandInstances.push(newIsland);
    this.updateExtraSublevels();
  }

  deleteIsland(index: number) {
    let oldIsland = this.cell.islandInstances[index];
    this.removeSublevelsForIsland(oldIsland);
    this.cell.islandInstances.splice(index, 1);
    this.updateExtraSublevels();
  }

  addNewDiscovery() {
    let newDisco = new DiscoveryZoneModel();
    newDisco.id = this.server.serverGrid.getNextId();
    this.cell.discoZones.push(newDisco);
  }

  deleteDiscovery(index: number) {
    this.cell.discoZones.splice(index, 1);
  }
}
