import React, {Component} from 'react';
import './Grid.css';
import GridComponent from './GridComponent/GridComponent';

export default class extends Component {
  constructor(props) {
    super(props);
    window.addEventListener("resize", this.updateSizeAsync);
    this.checkSizeInterval = setInterval(()=> {
      this.updateSize()
    }, 2000);
  }

  checkSizeInterval;

  state = {
    calculated: false,
    dimensions: {
      columns: 0,
      rows: 0
    }
  };

  calculateDimensions = (size) => {
    return {
      columns: Math.floor(size.width / 4),
      rows: Math.floor(size.height / 4)
    };
  };

  getSize = () => {
    const elem = this.refs.GridOwner;
    return {
      height: elem ? elem.clientHeight : 0,
      width: elem ? elem.clientWidth : 0
    };
  };

  updateSize = () => {
    const state = {
      ...this.state
    };
    const size = this.getSize();
    const dimensions = this.calculateDimensions(size);
    if (state.dimensions !== dimensions) {
      this.setState({
        calculated: true,
        dimensions: dimensions
      })
    }
  };

  updateSizeAsync = () => {
    return new Promise((done) => {
      this.updateSize();
      done();
    });
  };

  componentDidMount() {
    this.updateSizeAsync();
  }

  componentWillUnmount() {
    window.removeEventListener("resize", this.updateSizeAsync);
    clearInterval(this.checkSizeInterval);
  };

  render() {
    let children = null;
    const dimensions = this.state.dimensions;
    if (this.state.calculated) {
      children = React.Children.map(this.props.children, (child, i) => {
        if (child) {
          let row = child.props.row || 0;
          if (typeof(row) === 'function') {
            row = row(dimensions);
          }

          let col = child.props.col || 0;
          if (typeof(col) === 'function') {
            col = col(dimensions);
          }

          let rowSpan = child.props.rowSpan;
          if (typeof(rowSpan) === 'function') {
            rowSpan = rowSpan(dimensions.rows - row, dimensions.rows);
          }

          let colSpan = child.props.colSpan;
          if (typeof(colSpan) === 'function') {
            colSpan = colSpan(dimensions.columns - col, dimensions.columns);
          }

          rowSpan = rowSpan ? (rowSpan === 'remain' ? (dimensions.rows - row) : rowSpan) : null;
          colSpan = colSpan ? (colSpan === 'remain' ? dimensions.columns - col : colSpan) : null;

          return <GridComponent
            row={row}
            col={col}
            rowSpan={rowSpan}
            colSpan={colSpan}
            key={'gc_' + i}>{child}</GridComponent>;
        } else {
          return null;
        }
      })
      .filter(i => i !== null);
    }

    const style = {
      style: {
        gridTemplateColumns: '4px '.repeat(dimensions.columns).trim(),
        gridTemplateRows: '4px '.repeat(dimensions.rows).trim(),
        gridAutoColumns: '4px',
        gridAutoRows: '4px'
      }
    };

    return (
      <div
        ref='GridOwner'
        className={'GridOwner'}>
        <div className={'Grid'} {...style}>
          {children}
        </div>
      </div>
    )
  };
};