package base;

import openfl.Assets;
import openfl.display.Bitmap;
import openfl.display.BitmapData;
import openfl.display.DisplayObject;
import openfl.display.Sprite;
import openfl.events.MouseEvent;

class GameSprite extends Sprite {
  public var bitmap: Bitmap;

  var childGameSprites:Array<GameSprite> = [];
  var currentTween: Tween = null;

  var timers: Array<{
    time: Float,
    action: Void -> Void
  }> = [];

  public function new(?assetId: String = null, ?centered: Bool = false, ?shiftX: Float = 0, ?shiftY: Float = 0) {
    super();

    if(assetId != null) {
      bitmap = new Bitmap(Assets.getBitmapData(assetId));
      if(centered) {
        bitmap.x = -bitmap.width / 2;
        bitmap.y = -bitmap.height / 2;
      } else {
        bitmap.x = shiftX;
        bitmap.y = shiftY;
      }

      addChild(bitmap);
    }
  }

  /**
   * Update
   */
  public function update(delta: Float): Void {
    if(currentTween != null) {
      currentTween = currentTween.update(delta);
    }

    for(timer in timers) {
      if(timer.time <= 0) {
        timer.action();
        timers.remove(timer);
      } else {
        timer.time -= delta;
      }
    }

    for(child in childGameSprites) {
      child.update(delta);
    }
  }

  override public function addChild(child:DisplayObject): DisplayObject {
    if(Std.is(child, GameSprite)) {
      if(childGameSprites.indexOf(cast child) == -1)
        childGameSprites.push(cast child);
    }
    return super.addChild(child);
  }

  override public function removeChild(child:DisplayObject): DisplayObject {
    if(Std.is(child, GameSprite)) {
      childGameSprites.remove(cast child);
    }
    return super.removeChild(child);
  }

  public function keyDown(keyCode: Int, ctrl: Bool, alt: Bool, shift: Bool) {
    for(child in childGameSprites) {
      if(child.visible) {
        child.keyDown(keyCode, ctrl, alt, shift);
      }
    }
  }

  public function keyUp(keyCode: Int, ctrl: Bool, alt: Bool, shift: Bool) {
    for(child in childGameSprites) {
      if(child.visible) {
        child.keyUp(keyCode, ctrl, alt, shift);
      }
    }
  }

  /**
   *  Timer
   *  
   *  @param time - 
   *  @param action - 
   */
  public function timer(time: Float, action: Void -> Void) {
    timers.push({
      time: time,
      action: action
    });
  }

  /**
   *  
   */
  public function tween(properties:Dynamic, time: Float, onComplete: Void -> Void = null) {
    return currentTween = new Tween(this, time, properties);
  }
}
