import {ApplicationRef, ChangeDetectorRef, Component, OnInit} from '@angular/core';
import {circle, icon, latLng, LatLng, Marker, marker, point, polygon, polyline, Polyline, tileLayer} from 'leaflet';
import {GeoJSON, LatLngExpression} from 'leaflet';
import {VttTraceWsService} from './vtt-trace-ws.service';
import {Feature, GeometryObject, LineString, MultiLineString, Point} from 'geojson';
import {LeafletCoreDemoModel} from './core-demo.model';
import {Observable} from 'rxjs/Observable';


// Utilise la librairie ngx-leaflet
// https://www.asymmetrik.com/ngx-leaflet-tutorial-angular-cli/
// https://github.com/Asymmetrik/ngx-leaflet
// Voir aussi la doc de Leaflet
// https://leafletjs.com/reference-1.3.0.html
// et le projet exemple ngx-leaflet

@Component({
  selector: 'app-vtt-trace',
  templateUrl: './vtt-trace.component.html',
  styleUrls: ['./vtt-trace.component.css'],
  providers: [VttTraceWsService]
})

export class VttTraceComponent implements OnInit {
  // Open Street Map and Open Cycle Map definitions
  LAYER_OCM = {
    id: 'opencyclemap',
    name: 'Open Cycle Map',
    enabled: true,
    layer: tileLayer('http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', {
      maxZoom: 18,
      attribution: 'Open Cycle Map'
    })
  };
  LAYER_OSM = {
    id: 'openstreetmap',
    name: 'Open Street Map',
    enabled: false,
    layer: tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
      maxZoom: 18,
      attribution: 'Open Street Map'
    })
  };

  // Values to bind to Leaflet Directive
  layersControlOptions = { position: 'bottomright' };
  baseLayers = {
    'Open Street Map': this.LAYER_OSM.layer,
    'Open Cycle Map': this.LAYER_OCM.layer
  };


  /*
   * This is a specification of the leaflet options
   * The reason to duplicate this object is so we can easily render it to the template
   */
  optionsSpec: {
    layers: any[],
    zoom: number,
    center: number[]
  } = {
    layers: [
      {
        url: 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
        maxZoom: 18,
        attribution: 'Open Street Map'
      }
    ],
    zoom: 5,
    center: [ 46, 2 ]
  };

  // Fields for managing the form inputs and binding to leaflet zoom/center
/*
  model = new LeafletCoreDemoModel(
    this.optionsSpec.center[0],
    this.optionsSpec.center[1],
    this.optionsSpec.zoom
  );
*/
  zoom: number;
  center: LatLng;
  latitude: number;
  longitude: number;
  zoomLevels: number[] = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 ];

  layers = [];
  options = {
    layers: this.optionsSpec.layers.map((l) => {
      return tileLayer(l.url, { maxZoom: l.maxZoom, attribution: l.attribution });
    }),
    zoom: this.optionsSpec.zoom,
    center: latLng(this.optionsSpec.center[0], this.optionsSpec.center[1])
  };

  featuresCollection: Array<GeoJSON.Feature<Point>> = [];

  onApply() {
    this.zoom = this.zoom;
    this.center = latLng(this.latitude, this.longitude);

    return false;
  }

  constructor(private vttTraceWs: VttTraceWsService) { }

  ngOnInit() {
    this.getMarkersObs();
  }

  private getMarkersObs() {
    this.vttTraceWs.gettVttRandosDescFromServerObs()
      .subscribe((response: Array<string>) => {
        response.forEach(x => {
          const json = JSON.parse(x);
          this.addMarker(json);
          this.featuresCollection.push(json);
        });
      });
  }

  addMarker(feature: Feature<Point>) {
    const newMarker = marker(
      [feature.geometry.coordinates[0], feature.geometry.coordinates[1]],
      {
        icon: icon({
          iconSize: [ 25, 41 ],
          iconAnchor: [ 13, 41 ],
          iconUrl: 'assets/marker-icon.png',
          shadowUrl: 'assets/marker-shadow.png'
        })
      }
    );

    console.log(feature.properties.name);
    console.log('here' + this);
    newMarker.bindPopup(feature.properties.name).openPopup();
    newMarker.on('click', this.markerOnClick, newMarker);
    this.layers.push(newMarker);
  }

  markerOnClick(e) {
    console.log(e);
    const window: Window = self;
    console.log('parent' + this);
    this.zoom = 15;
    console.log(this.zoom);
    this.center = latLng(this.latitude, this.longitude);
    //this.options.center = e.latlng;

    console.log(this.center);
    const attributes = e.layer.properties;
    console.log(attributes.name, attributes);
    // do some stuff…
    return false;
  }

  addRoute() {
    // create a red polyline from an array of LatLng points
    const route = polyline(this.vttTraceWs.getMockRoute1());
    this.layers.push(route);
  }

  addRoute2() {
    this.layers.push(polyline(this.vttTraceWs.getMockRoute2()));
  }

  addRoute3() {
    this.layers.push(polyline(this.vttTraceWs.getMockRoute3()));
  }

  addRoute4() {
    this.vttTraceWs.getMockRoute4()
      .subscribe(data => {
        console.log(data)
        const featureCollection: GeoJSON.FeatureCollection<Point | LineString | MultiLineString> = data
        const g = featureCollection.features[1].geometry.coordinates;
        //     console.log(g);
        console.log(featureCollection.features[1].geometry.coordinates[0]);
        //     // return featureCollection.features[0].geometry.coordinates[0];
        //     resul =  GeoJSON.coordsToLatLngs(g, 0);
        this.layers.push(polyline(GeoJSON.coordsToLatLngs(g, 0)));
      });
  }

  addRoute5() {
    this.vttTraceWs.getMockRoute5()
      .subscribe(data => {
        console.log(data)
        const featureCollection: GeoJSON.FeatureCollection<Point | LineString | MultiLineString> = data
        const g = featureCollection.features[0].geometry.coordinates;
        console.log(featureCollection.features[0].geometry.coordinates[0]);
        this.layers.push(polyline(GeoJSON.coordsToLatLngs(g, 1)));
      });
  }

  addRoute6() {
    this.vttTraceWs.getMockRoute6()
      .subscribe(data => {
        console.log(data)
        const featureCollection: GeoJSON.FeatureCollection<Point | LineString | MultiLineString> = data
        const g = featureCollection.features[0].geometry.coordinates;
        console.log(featureCollection.features[0].geometry.coordinates[0]);
        this.layers.push(polyline(GeoJSON.coordsToLatLngs(g, 1)));
      });
  }


  /*  private showRoute() {
        this.fitBounds(this.layers.getBounds(), {
          padding: point(24, 24),
          maxZoom: 12,
          animate: true
        });
    }*/

}


