///
/// Created by @Haoyi on 2021/7/16
///

part of '../visual_feast_engine.dart';

class RenderLayer {
  final int order;
  final RenderQueue pendingRenders = RenderQueue();
  final RenderQueue visibleRenders = RenderQueue();
  final RenderQueue invisibleRenders = RenderQueue();

  final Map<int, RenderElement> rendersIdMapping = <int, RenderElement>{};

  RenderLayer(this.order);

  static final RenderLayer invalid = RenderLayer(-1);

  void addRender(RenderElement renderObject) {
    pendingRenders.addBack(renderObject);
  }

  void removeRender(RenderElement renderObject) {
    renderObject._unlink();
    renderObject.dispatchDetach();
  }

  void removeAll() {
    while (pendingRenders.isNotEmpty) {
      final render = pendingRenders.popFront();
      render?.dispatchDetach();
    }

    while (visibleRenders.isNotEmpty) {
      final render = visibleRenders.popFront();
      render?.dispatchDetach();
    }

    while (invisibleRenders.isNotEmpty) {
      final render = invisibleRenders.popFront();
      render?.dispatchDetach();
    }
  }

  bool get isEmpty => pendingRenders.isEmpty && visibleRenders.isEmpty && invisibleRenders.isEmpty;

  void frameUpdate(double t) {
    if (pendingRenders.isNotEmpty) {
      // Log.d("##frameUpdate!! ${pendingRenders.isNotEmpty} ${visibleRenders.isNotEmpty}");
      pendingRenders.onStart();
      visibleRenders._addAllToBack(pendingRenders);
      pendingRenders.reset();
    }
    visibleRenders.propagate((render) {
      if (render._visibility == RenderVisibility.visible) {
        render.dispatchFrameUpdate(t);
      } else {
        render._unlink();
        invisibleRenders.addBack(render as RenderElement);
      }
    });

    invisibleRenders.propagate((render) {
      if (render._visibility == RenderVisibility.invisible) {
        render.dispatchFrameUpdate(t);
      } else {
        render._unlink();
        visibleRenders.addBack(render as RenderElement);
      }
    });
  }

  void render(Canvas canvas) {
    visibleRenders.onRender(canvas);
  }
}
