/* eslint-disable no-prototype-builtins */
import Graph from 'graphology';
import { Providers, LayoutAlgorithm } from './types';

export abstract class Layout<provider extends Providers> {
  protected graph: Graph | null = null;
  protected verbose: boolean = false;
  protected boundingBox: { x1: number; x2: number; y1: number; y2: number } = { x1: 0, x2: 0, y1: 1000, y2: 1000 };

  constructor(
    public provider: provider,
    public algorithm: LayoutAlgorithm<provider>,
  ) {
    // console.info(`Created the following Layout: ${provider} - ${this.algorithm}`);
  }

  public setVerbose(verbose: boolean) {
    this.verbose = verbose;
  }

  public async layout(graph: Graph, boundingBox?: { x1: number; x2: number; y1: number; y2: number }) {
    this.graph = graph;

    if (boundingBox !== undefined) {
      this.boundingBox = boundingBox;

      if (this.verbose) {
        console.log(`Setting bounding box to ${JSON.stringify(this.boundingBox)}`);
      }
    }

    if (this.verbose) {
      console.log(`${this.provider} [${this.algorithm}] layouting now`);
    }

    graph.forEachNode(node => {
      const attr = graph.getNodeAttributes(node);
      if (!attr.hasOwnProperty('x')) {
        graph.setNodeAttribute(node, 'x', Math.random());
      }
      if (!attr.hasOwnProperty('y')) {
        graph.setNodeAttribute(node, 'y', Math.random());
      }
    });
  }
}