export default class Waterfall {
  constructor({
    width,
    margin,
    grid = 1
  }) {
    this.config({
      width,
      margin,
      grid
    });
  }

  config({
    width,
    margin,
    grid = 1
  }) {
    this.width = width;
    this.margin = margin;
    this.grid = grid;
    this.rowsLength = Math.floor(this.width / this.grid);
    let rows = [{
      num: this.rowsLength,
      value: 0
    }];
    this.rows = rows;
  }

  getPostion(width, height) {
    let num = Math.ceil(width / this.grid);

    if (num > this.rowsLength) {
      throw new Error('超出最大宽度');
    }

    let min = Infinity;
    let idx = 0;
    let rowsLength = 0;
    let leftNum = 0;
    let total = this.rowsLength;

    for (let i = this.rows.length - 1; i > -1; i--) {
      rowsLength += this.rows[i].num;
      total -= this.rows[i].num;

      if (rowsLength >= num) {
        const top = this.rows[i].value;

        if (top <= min) {
          leftNum = total;
          min = this.rows[i].value;
          idx = i;
        }
      }

      if (this.rows[i - 1] && this.rows[i - 1].value < this.rows[i].value) {
        rowsLength = 0;
      }
    }

    const row = this.rows[idx];

    if (row.num > num) {
      const newRow = {
        num: row.num - num,
        value: row.value
      };
      this.rows.splice(idx + 1, 0, newRow);
      row.num = num;
    } else if (row.num < num) {
      let total = row.num;

      for (let index = idx + 1; index < this.rows.length; index++) {
        total += this.rows[index].num;

        if (total <= num) {
          row.num += this.rows[index].num;
          this.rows.splice(index, 1);
          index -= 1;
        } else {
          row.num = num;
          this.rows[index].num = total - num;
        }

        if (total >= num) break;
      }
    }

    let value = row.value;
    row.value += height + this.margin;
    return {
      left: leftNum * this.grid + idx * this.margin,
      top: value
    };
  }

}