package com.ptaylor.effects
{
  import com.flashdynamix.motion.effects.IEffect;
  import com.flashdynamix.motion.layers.BitmapLayer;
  import com.ptaylor.effects.extras.Emitter;
  
  import flash.display.Graphics;
  
  import mx.core.UIComponent;
  
  /**
  * The EmitterCanvas has a single BitmapLayer child that renders all the
  * Emitter and IEffects. This class supports rendering multiple Emitters
  * and multiple IEffects, as well as drawing a backgroundColor behind
  * the BitmapLayer.
  */
  public class EmitterCanvas extends UIComponent
  {
    protected var layer:BitmapLayer;
    protected var emittersChanged:Boolean = false;
    protected var effectsChanged:Boolean = false;
    protected var _emitters:Array;
    protected var _effects:Array;
    
    protected var bgColor:uint = 0x0;
    
    public function EmitterCanvas()
    {
      super();
    }
    
    public function set backgroundColor(c:uint):void
    {
      bgColor = c;
      invalidateDisplayList();
    }
    
    public function get backgroundColor():uint
    {
      return bgColor;
    }
    
    public function get emitters():Array
    {
      return _emitters;
    }
    
    public function set emitters(a:Array):void
    {
      _emitters = a.concat();
      emittersChanged = true;
      invalidateDisplayList();
    }
    
    public function get effects():Array
    {
      return _effects;
    }
    
    public function set effects(a:Array):void
    {
      _effects = a.concat();
      effectsChanged = true;
      invalidateDisplayList();
    }
    
    override protected function createChildren():void
    {
      super.createChildren();
      
      layer = new BitmapLayer();
      addChild(layer);
    }
    
    protected function renderEmitters():void
    {
      if(!emitters || emitters.length < 1)
        return;
      
      var e:Emitter;
      var i:int, n:int = emitters.length;
      for(i = 0; i < n; i++)
      {
        e = Emitter(emitters[i]);
        if(e.drawEffect && layer.list.indexOf(e.drawEffect) > -1)
          layer.remove(e.drawEffect);
        e.drawEffect = layer.draw(e.holder);
        e.start();
      }
    }
    
    protected function renderEffects():void
    {
      if(!effects || effects.length < 1)
        return;
      
      var e:IEffect;
      var i:int, n:int = effects.length;
      for(i = 0; i < n; i++)
      {
        e = IEffect(effects[i]);
        if(layer.list.indexOf(e) > -1)
          layer.remove(e);
        layer.add(e);
      }
    }
    
    override protected function updateDisplayList(w:Number, h:Number):void
    {
      super.updateDisplayList(w, h);
      
      layer.layerWidth = w;
      layer.layerHeight = h;
      
      var g:Graphics = graphics;
      g.clear();
      g.beginFill(backgroundColor, 1);
      g.drawRect(0, 0, w, h);
      
      if(emittersChanged)
        renderEmitters();
      if(effectsChanged)
        renderEffects();
      
      emittersChanged = false;
      effectsChanged = false;
    }
  }
}