/*
 * Copyright 2015 defrac inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package defrac.display;

import defrac.display.event.raw.EnterFrameEvent;
import defrac.display.particle.ParticleStrategy;
import defrac.display.render.RenderContent;
import defrac.display.render.Renderer;
import defrac.event.EventBinding;
import defrac.gl.GLMatrix;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 *
 */
public class ParticleSystem extends DisplayObject {
  @Nullable
  private ParticleStrategy strategy;

  @Nullable
  private EventBinding<EnterFrameEvent> enterFrame;

  public ParticleSystem(@Nonnull final ParticleStrategy strategy) {
    this.strategy(strategy);
  }

  @Override
  protected void onAttachToStage() {
    super.onAttachToStage();

    final Stage stage = stage();

    assert stage != null;

    initAABB(0.0f, 0.0f, stage.width(), stage.height());

    enterFrame =
        stage.globalEvents().onEnterFrame.add(this::onEnterFrame);

    if(strategy == null) {
      enterFrame.pause();
    }
  }

  @Nullable
  public ParticleStrategy strategy() {
    return strategy;
  }

  @Nonnull
  public ParticleSystem strategy(@Nullable final ParticleStrategy value) {
    final ParticleStrategy oldValue = strategy;

    if(value == oldValue) {
      return this;
    }

    strategy = value;

    if(oldValue == null) {
      if(enterFrame != null) {
        enterFrame.resume();
      }
    } else if(value == null && enterFrame != null) {
      enterFrame.pause();
    }

    invalidate(DisplayObjectFlags.RENDERLIST_DIRTY);

    return this;
  }

  private void onEnterFrame(@Nonnull final EnterFrameEvent event) {
    assert strategy != null;
    strategy.update(event);
    invalidate(DisplayObjectFlags.RENDERLIST_MATRIX_DIRTY);
  }

  /** {@inheritDoc} */
  @Nullable
  @Override
  public RenderContent render(@Nonnull final GLMatrix projectionMatrix,
                              @Nonnull final GLMatrix modelViewMatrix,
                              @Nonnull final Renderer renderer,
                              @Nonnull final BlendMode parentBlendMode,
                              final float parentAlpha) {
    return strategy == null
        ? null
        : strategy.render(
              projectionMatrix,
              modelViewMatrix,
              renderer,
              blendMode.inherit(parentBlendMode),
              parentAlpha * alpha);
  }
}

@@ -795,42 +795,8 @@
 er;%0A
-import defrac.event.EventBinding;%0A
 impo
@@ -948,16 +948,48 @@
 yObject 
+implements OnEnterFrameReceiver 
 %7B%0A  @Nul
@@ -1036,73 +1036,8 @@
 y;%0A%0A
-  @Nullable%0A  private EventBinding%3CEnterFrameEvent%3E enterFrame;%0A%0A
   pu
@@ -1334,153 +1334,8 @@
 ());
-%0A%0A    enterFrame =%0A        stage.globalEvents().onEnterFrame.add(this::onEnterFrame);%0A%0A    if(strategy == null) %7B%0A      enterFrame.pause();%0A    %7D
 %0A  %7D
@@ -1629,189 +1629,8 @@
 e;%0A%0A
-    if(oldValue == null) %7B%0A      if(enterFrame != null) %7B%0A        enterFrame.resume();%0A      %7D%0A    %7D else if(value == null && enterFrame != null) %7B%0A      enterFrame.pause();%0A    %7D%0A%0A
     
@@ -1703,23 +1703,57 @@
 %0A  %7D%0A%0A  
-private
+/** %7B@inheritDoc%7D */%0A  @Override%0A  public
  void on
@@ -1807,23 +1807,19 @@
 ) %7B%0A    
-assert 
+if(
 strategy
@@ -1819,24 +1819,47 @@
 trategy 
-!
+=
 = null
-;
+) %7B%0A      return;%0A    %7D%0A
 %0A    str
@@ -1879,16 +1879,17 @@
 event);%0A
+%0A
     inva

Use OnEnterFrameReceiver in ParticleSystem