import { Component, OnInit } from '@angular/core';
// import { Observable } from 'rxjs/Observable';
import { HttpClient, HttpHeaders } from "@angular/common/http";

import Map from 'ol/Map.js';
import View from 'ol/View.js';
import Draw from 'ol/interaction/Draw.js';
import Select from 'ol/interaction/Select.js';
import Feature from 'ol/Feature';
import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer.js';
import { OSM, Vector as VectorSource } from 'ol/source.js';
import { defaults as defaultControls } from 'ol/control.js';
import MousePosition from 'ol/control/MousePosition.js';
import { createStringXY } from 'ol/coordinate.js';
import { Circle as CircleStyle, Fill, Stroke, Style, Text } from 'ol/style.js';
import { WFS, GML } from 'ol/format.js'

@Component({
  selector: 'olglib-map',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.css']
})
export class MapComponent implements OnInit {
  featureTypes = [
    { id: 1, name: "None" },
    { id: 2, name: "Point" },
    { id: 3, name: "LineString" },
    { id: 4, name: "Polygon" },
    { id: 5, name: "Circle" }
  ];
  selectedType = { id: 1, name: "None" };
  activation = "false";

  // Map Values
  map: Map;
  draw: Draw;
  select: Select;
  vectorSource: VectorSource;
  formatWFS: WFS;
  formatGML: GML;
  featureList = [];
  xs: XMLSerializer;

  constructor() { }

  initMap() {
    // this.featureList = [];
    console.log(this.featureList);
    var raster = new TileLayer({
      source: new OSM()
    });

    this.vectorSource = new VectorSource({ wrapX: false });

    var vector = new VectorLayer({
      source: this.vectorSource
    });

    var mousePositionControl = new MousePosition({
      coordinateFormat: createStringXY(4),
      className: 'custom-mouse-position',
      target: document.getElementById('mouse-position'),
      undefinedHTML: '&nbsp'
    });

    this.map = new Map({
      layers: [raster, vector],
      target: 'map',
      controls: defaultControls({
        attributionOptions: {
          collapsible: false
        }
      }).extend([mousePositionControl]),
      view: new View({
        center: [14139993, 4511864],
        zoom: 5
      })
    });
  }

  initSelect() {
    this.select = new Select();
    // this.map.addInteraction(this.select);
    var flist = this.featureList;
    var tselect = this.select;
    this.select.on('select', function(evt) {
      var selected = evt.selected;

      if (selected.length) {
        selected.forEach(function(feature) {
          console.info(feature);

          const idx = flist.indexOf(feature);
          if (idx > -1) flist.splice(idx, 1);
          console.log(tselect);
          tselect.getLayer(feature).getSource().removeFeature(feature);
          tselect.getFeatures().clear();
        });
      }
    });
  }

  startInteraction() {
    var type = this.selectedType.name;
    console.log(type);
    var flist = this.featureList;
    if (type !== 'None') {
      this.draw = new Draw({
        source: this.vectorSource,
        type: type
      });

      this.map.addInteraction(this.draw);

      this.draw.on('drawstart', function() {

      });

      this.draw.on('drawend', function(e) {
        flist.push(e.feature);
      })
    }
  }

  createWFS(namespace: string, type: string, srs: string) {
    this.formatWFS = new WFS();
    this.formatGML = new GML({
      featureNS: namespace,
      featureType: type,
      srsName: srs
    });
    this.xs = new XMLSerializer();
  }

  transactWFS(mode: string, feature: Feature) {
    var node;
    switch (mode) {
      case 'insert':
        node = this.formatWFS.writeTransaction([feature], null, null, this.formatGML);
        break;
      case 'update':
        node = this.formatWFS.writeTransaction(null, [feature], null, this.formatGML);
        break;
      case 'delete':
        node = this.formatWFS.writeTransaction(null, null, [feature], this.formatGML);
        break;
    }

    var payload = this.xs.serializeToString(node);

    // const headers = new HttpHeaders({'Content-Type': 'text/xml'}).set('Accept', 'xml');
    // headers.set('dataType', 'xml');
    // headers.set('data', payload);
    //
    // this.http.post(
    //   "http://localhost:8080/geoserver/wfs",
    //   { headers: headers, responseType: 'text/xml' }).subscribe();
    // $http({
    //   method: 'POST',
    //   url: 'http://localhost:8080/geoserver/wfs',
    //   data: payload,
    //   headers: {'Content-Type': 'text/xml; charset=utf-8'}
    // })
    var httpRequest = new XMLHttpRequest();
    httpRequest.open('POST', 'http://localhost:8080/geoserver/wfs', false);
    // httpRequest.setRequestHeader("X-Requested-With","XMLHttpRequest");
    // httpRequest.setRequestHeader('Content-Type', 'text/xml');
    // httpRequest.setRequestHeader('dataType', 'xml');
    // httpRequest.setRequestHeader('responseType', 'text/xml');
    // httpRequest.setRequestHeader('Accept', 'text/xml')
    // httpRequest.setRequestHeader('data',payload);
    // httpRequest.setRequestHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:4200');
    // httpRequest.setRequestHeader('Access-Control-Request-Method', '*');
    // httpRequest.setRequestHeader('Access-Control-Allow-Credentials', 'true');
    httpRequest.send(payload);
  }

  changeInteraction() {
    console.log(this.selectedType);
    this.map.removeInteraction(this.draw);
    this.startInteraction();
    console.log(this.featureList);
  }

  getFeatures() {
    console.log(this.featureList);
  }

  saveFeatures() {
    for (let feature of this.featureList) {
      console.log(feature);
      this.transactWFS("insert", feature);
    }
    this.featureList = [];
  }

  startDelete() {
    console.log("Start Delete");
    this.activation = "true";
    this.map.addInteraction(this.select);
  }

  endDelete() {
    console.log("End Delete");
    this.activation = "false";
    this.map.removeInteraction(this.select);
  }

  ngOnInit() {
    this.initMap();
    this.initSelect();
    this.createWFS('user_features', 'wfs_geom', 'EPSG:3857');
  }
}
