var graphics = use('graphics')
var color = use('color')

var sprite = {
    image: null,
    set color(x) { this._sprite.color = x; },
    get color() { return this._sprite.color; },
    anim_speed: 1,
    play(str, loop = true, reverse = false, fn) {
      if (!this.animset) {
        fn?.();
        return;
      }
    
      if (typeof str == 'string') {
        if (!this.animset[str])  {
          fn?.();
          return;
        }
        this.anim = this.animset[str];
      }

      var playing = this.anim;
    
      var stop;

      this.del_anim?.();
      this.del_anim = () => {
        this.del_anim = null;
        advance = null;
        stop?.();
      };

      var f = 0;
      if (reverse) f = playing.frames.length - 1;

    var advance = (time) => {
      var done = false;
      if (reverse) {
        f = (((f - 1) % playing.frames.length) + playing.frames.length) % playing.frames.length;
        if (f == playing.frames.length - 1) done = true;
      } else {
        f = (f + 1) % playing.frames.length;
        if (f == 0) done = true;
      }

      this.image = playing.frames[f];

      if (done) {
        // notify requestor
        fn?.();
        if (!loop) {
          this?.stop();
          return;
        }
      }
      
      return playing.frames[f].time/this.anim_speed;
    }
    stop = this.delay(advance, playing.frames[f].time/this.anim_speed);
    advance();
  },
  stop() {
    this.del_anim?.();
  },
  set path(p) {
    var image = graphics.texture(p);
    if (!image) {
      log.warn(`Could not find image ${p}.`);
      return;
    }

    this._p = p;

    this.del_anim?.();
    if (image.texture)
      this.image = image;
    else if (image.frames) {
      // It's an animation
      this.anim = image;      
      this.image = image.frames[0];
      this.animset = [this.anim]
      this.play()
    } else {
      // Maybe an animset; try to grab the first one
      for (var anim in image) {
        if (image[anim].frames) {
          this.anim = image[anim];
          this.image = image[anim].frames[0];
          this.animset = image;
          this.play()
          break;
        }
      }
    }
    
    this.transform.scale = this.image.texture.dim //[this.image.texture.width, this.image.texture.height]
    this._sprite.set_image(this.image)
  },
  get path() {
    return this._p;
  },
  garbage: function() {
    this.del_anim?.();
    this.anim = null;
    tree.delete(this._sprite)
    this.transform.parent = null
    for (var t of this.transform.children())
      t.parent = null
    delete this.transform.sprite      
    delete this._sprite
//    log.console("CLEARED SPRITE")
  },
  anchor: [0, 0],
  set layer(v) { this._sprite.layer = v; },
  get layer() { return this._sprite.layer; },
  pick() {
    return this;
  },
  boundingbox() {
    return Object.freeze(this._sprite.rect) // freeze so it can't be modified on the outside
  }
};

sprite.setanchor = function (anch) {
  var off = [0, 0];
  switch (anch) {
    case "ll":
      break;
    case "lm":
      off = [-0.5, 0];
      break;
    case "lr":
      off = [-1, 0];
      break;
    case "ml":
      off = [0, -0.5];
      break;
    case "mm":
      off = [-0.5, -0.5];
      break;
    case "mr":
      off = [-1, -0.5];
      break;
    case "ul":
      off = [0, -1];
      break;
    case "um":
      off = [-0.5, -1];
      break;
    case "ur":
      off = [-1, -1];
      break;
  }
  this.anchor = off;
  this.pos = this.dimensions().scale(off);
};

sprite.inputs = {};
sprite.inputs.kp9 = function () {
  this.setanchor("ll");
};
sprite.inputs.kp8 = function () {
  this.setanchor("lm");
};
sprite.inputs.kp7 = function () {
  this.setanchor("lr");
};
sprite.inputs.kp6 = function () {
  this.setanchor("ml");
};
sprite.inputs.kp5 = function () {
  this.setanchor("mm");
};
sprite.inputs.kp4 = function () {
  this.setanchor("mr");
};
sprite.inputs.kp3 = function () {
  this.setanchor("ur");
};
sprite.inputs.kp2 = function () {
  this.setanchor("um");
};
sprite.inputs.kp1 = function () {
  this.setanchor("ul");
};

var rtree = use('rtree')

var tree = new rtree
sprite.tree = tree;

var IN = Symbol()

sprite.t_hook = function() {
  var msp = this.sprite._sprite;
  if (this[IN])
    tree.delete(msp);
  msp.rect = this.torect()
  msp.set_affine(this)
    tree.add(msp)
  this[IN] = true
}

Object.mixin(sprite,use("transform"))

sprite.to_queue = function(ysort = false)
{
  var pos = prosperon.camera.transform.pos;
  var size =  prosperon.camera.size;
  var camrect = {
    x:pos.x-size.x/2,
    y:pos.y-size.y/2,
    width:size.x,
    height:size.y
  };
  var culled = sprite.tree.query(camrect)
  if (culled.length == 0) return [];
  var cmd = graphics.make_sprite_queue(culled, prosperon.camera, null, 1);
  return cmd;
}

return sprite;

---

var color = use('color')
var transform = use('transform')
var sprite = use('sprite')

this.transform = new transform;
if (this.overling.transform)
  this.transform.parent = this.overling.transform;
  
this.transform.change_hook = $.t_hook;
var msp = new sprite
this._sprite = msp; 
msp.color = color.white;
this.transform.sprite = this


