import "luxe: assets" for Assets
import "luxe: render" for Material
import "math/math" for M
import "math/Vector" for Vector

class Util{
  static material_from_image_path(path){
    var image = Assets.image(path)
    return material_from_image(image)
  }

  static material_from_image(image){
    var material = Material.create("luxe: material_basis/sprite_pixelated")
    Material.set_image(material, 0, image)
    return material
  }

  static copy_list(from, to){
    for(i in 0...from.count){
      to[i] = from[i]
    }
  }

  static for_all(sequences, fn){
    var count = sequences.count
    var counter = (0...count)
    var iterators = List.filled(count, null)
    counter.each{|i| iterators[i] = sequences[i].iterate(iterators[i])}
    while(iterators.all{|iter| !!iter}){
      var values = (0...count).map{|i| sequences[i].iteratorValue(iterators[i])}.toList
      call_arg_list(fn, values)
      counter.each{|i| iterators[i] = sequences[i].iterate(iterators[i])}
    }
  }

  static call_arg_list(fn, args){
    var l = args.count
    if(l == 0){
      fn.call()
    } else if(l == 1) {
      fn.call(args[0])
    } else if(l == 2) {
      fn.call(args[0], args[1])
    } else if(l == 3) {
      fn.call(args[0], args[1], args[2])
    } else if(l == 4) {
      fn.call(args[0], args[1], args[2], args[3])
    } else if(l == 5) {
      fn.call(args[0], args[1], args[2], args[3], args[4])
    } else if(l == 6) {
      fn.call(args[0], args[1], args[2], args[3], args[4], args[5])
    } else if(l == 7) {
      fn.call(args[0], args[1], args[2], args[3], args[4], args[5], args[6])
    } else if(l == 8) {
      fn.call(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7])
    } else if(l == 9) {
      fn.call(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8])
    } else {
      System.print("%(l) is too many arguments")
    }
  }

  //hue value saturation to rgb colors. all values in 0-1 range
  static hsv(h, s, v){
    //hue to rgb
    h = h % 1
    var col = [
      (h * 6 - 3).abs - 1,
      2 - (h * 6 - 2).abs,
      2 - (h * 6 - 4).abs
    ]
    col = M.clamp(col, 0, 1)
    //then add saturation
    col = M.lerp(1, col, s)
    //and value
    col = col.map{|comp| comp * v}

    return col.toList + [1]
  }
}