import { clamp } from '../utility'

class Dim4 {
  constructor (scX, ofX, scY, ofY) {
    this.scX = scX
    this.ofX = ofX
    this.scY = scY
    this.ofY = ofY
    this._update()
  }

  static fromTable (tbl) {
    let sx = 0.0
    let ox = 0.0
    let sy = 0.0
    let oy = 0.0
    if (tbl.length === 2) {
      let x = tbl[0]
      let y = tbl[1]

      if (typeof x === 'object' && x.length === 2) {
        sx = x[0]
        ox = x[1]
      } else if (typeof x === 'number') {
        sx = x
      }

      if (typeof y === 'object' && y.length === 2) {
        sx = y[0]
        ox = y[1]
      } else if (typeof y === 'number') {
        sx = y
      }
    } else if (tbl.length === 4) {
      sx = tbl[0]
      ox = tbl[1]
      sy = tbl[2]
      oy = tbl[3]
    }
    return new Dim4(sx, ox, sy, oy)
  }

  toTable () {
    return [this.scX, this.ofX, this.scY, this.ofY]
  }

  _update () {
    this[0] = this.scX
    this[1] = this.ofX
    this[2] = this.scY
    this[3] = this.ofY
  }
}

class Node2D {
  constructor (pos, size, rotation) {
    // Translation
    this.gpos = [0.0, 0.0]
    this.pos = pos || new Dim4(0.0, 0.0, 0.0, 0.0)

    // Scaling
    this.gscale = [1.0, 1.0]
    this.size = size || new Dim4(0.0, 0.0, 0.0, 0.0)

    // Rotation in degrees
    this.rotation = rotation || 0.0

    this.parent = null
    this.children = []
  }

  updateTransform () {

  }

  // Getters
  get position () {
    return this.pos
  }

  get translation () {
    return this.pos
  }

  // Draw base
  draw (gl) {
    // Nothing to draw here, so just draw children
    for (let i in this.children) {
      let child = this.children[i]
      if (!(child instanceof Node2D)) continue
      child.draw(gl)
    }
  }

  update (dt) {
    // Update children
    for (let i in this.children) {
      let child = this.children[i]
      if (!(child instanceof Node2D)) continue
      child.update(dt)
    }
  }

  addChild (ch) {
    // Recursive add in case of table
    if (ch && typeof ch === 'object' && ch.length) {
      for (let i in ch) {
        this.addChild(ch[i])
      }
    }

    if (!(ch instanceof Node2D)) return
    this.children.push(ch)
  }

  setParent (p) {
    if (!(p instanceof Node2D)) return
    this.parent = p
  }
}
