import {AfterViewInit, Component, Input, ViewEncapsulation} from "@angular/core";


/**
 * <section-scroll [customClass]="'optional classes for section e.g. uk-section-primary'"
 *                 [childrenCustomClass]="'optional classes for content e.g. uk-container'">
 *   <div top>...</div>
 *   <div left>...</div>
 *   <div scroll>...</div>
 * </section-scroll>
 *
 * */
@Component({
  selector: 'section-scroll',
  template: `
    <div [ngClass]="customClass">
      <ng-content select="[top]"></ng-content>
      <div [ngClass]="childrenCustomClass">
        <div class="uk-grid" uk-grid>
          <ng-content select="[left]"></ng-content>
          <ng-content select="[scroll]"></ng-content>
        </div>
      </div>
    </div>
  `,
  styleUrls: ['section-scroll.component.css'],
  encapsulation: ViewEncapsulation.None
})
export class SectionScrollComponent implements AfterViewInit {
  
  @Input()
  public customClass = null;
  @Input()
  public childrenCustomClass = null;
  @Input()
  public animationSteps: number = 20;
  private observer: IntersectionObserver = null;
  /**
   * Define as keys the ids of elements in scroll section and as values the ids of left section
   * */
  @Input()
  private map: Map<string, string> = null;
  private left: Map<string, HTMLElement> = new Map<string, HTMLElement>();
  private scroll: Map<string, HTMLElement> = new Map<string, HTMLElement>();
  
  constructor() {
  }
  
  ngOnDestroy() {
    if (this.observer) {
      this.observer.disconnect();
    }
  }
  
  ngAfterViewInit() {
    if (typeof document !== "undefined" && this.map) {
      this.createObserver();
    }
  }
  
  createObserver() {
    let observer;
    let options = {
      root: null,
      rootMargin: "-20%",
      threshold: this.buildThresholdList()
    };
    Array.from(this.map.values()).forEach(value => {
      let element = document.getElementById(value);
      element.style.display = 'none';
      this.left.set(value, element);
    })
    Array.from(this.map.keys()).forEach(key => {
      this.scroll.set(key, document.getElementById(key));
    })
    observer = new IntersectionObserver(entries => {
      entries.forEach((entry) => {
        entry.target['style'].opacity = String(entry.intersectionRatio);
        let id = this.map.get(entry.target.id);
        if(entry.isIntersecting) {
          Array.from(this.left.keys()).forEach(element => {
            if (element !== id) {
              this.left.get(element).style.display = 'none';
            } else {
              this.left.get(element).style.display = 'block';
            }
          });
        }
      });
    }, options);
    Array.from(this.scroll.values()).forEach(target => {
      observer.observe(target)
    });
  }
  
  buildThresholdList() {
    let thresholds = [];
    for (let i = 1.0; i <= this.animationSteps; i++) {
      let ratio = i / this.animationSteps;
      thresholds.push(ratio);
    }
    thresholds.push(0);
    return thresholds;
  }
}
