package alternativa.engine3d.core {

	import alternativa.engine3d.alternativa3d;
	
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.geom.ColorTransform;
	import __AS3__.vec.Vector;
	import flash.display.DisplayObject;

	use namespace alternativa3d;
	
	public class Canvas extends Sprite {
		
		static private const defaultColorTransform:ColorTransform = new ColorTransform();
		static private const collector:Vector.<Canvas> = new Vector.<Canvas>();
		static private var collectorLength:int = 0;
		
		/**
		 * @private 
		 */
		alternativa3d var gfx:Graphics = graphics;
		
		private var modifiedGraphics:Boolean;
		private var modifiedAlpha:Boolean;
		private var modifiedBlendMode:Boolean;
		private var modifiedColorTransform:Boolean;
		private var modifiedFilters:Boolean;
		
		/**
		 * @private 
		 */
		alternativa3d var _numChildren:int = 0;
		/**
		 * @private 
		 */
		alternativa3d var numDraws:int = 0;

		public function Canvas() {
			mouseEnabled = false;
			mouseChildren = false;
		}

		/**
		 * @private 
		 */
		alternativa3d function getChildCanvas(useGraphics:Boolean, useChildren:Boolean, alpha:Number, blendMode:String, colorTransform:ColorTransform, filters:Array):Canvas {
			var canvas:Canvas, displayObject:DisplayObject;
			// Зачистка не канвасов
			while (_numChildren > numDraws && !((displayObject = getChildAt(_numChildren - 1 - numDraws)) is Canvas)) removeChild(displayObject), _numChildren--;
			// Получение канваса
			if (_numChildren > numDraws++) canvas = displayObject as Canvas, canvas.gfx.clear() else canvas = (collectorLength > 0) ? collector[--collectorLength] : new Canvas(), addChildAt(canvas, 0), _numChildren++;
			// Пометка о том, что в graphics будет что-то нарисовано
			canvas.modifiedGraphics = useGraphics;
			// Если не нужны дочерние канвасы
			if (!useChildren) canvas.removeChildren(0); 
			// Установка свойств
			if (alpha != 1) canvas.alpha = alpha, canvas.modifiedAlpha = true else if (canvas.modifiedAlpha) canvas.alpha = 1, canvas.modifiedAlpha = false;
			if (blendMode != "normal") canvas.blendMode = blendMode, canvas.modifiedBlendMode = true else if (canvas.modifiedBlendMode) canvas.blendMode = "normal", canvas.modifiedBlendMode = false;
			if (colorTransform != null) colorTransform.alphaMultiplier = alpha, canvas.transform.colorTransform = colorTransform, canvas.modifiedColorTransform = true else if (canvas.modifiedColorTransform) defaultColorTransform.alphaMultiplier = alpha, canvas.transform.colorTransform = defaultColorTransform, canvas.modifiedColorTransform = false;
			if (filters != null) canvas.filters = filters, canvas.modifiedFilters = true else if (canvas.modifiedFilters) canvas.filters = null, canvas.modifiedFilters = false;
			return canvas;
		}
		
		/**
		 * @private 
		 */
		alternativa3d function removeChildren(keep:int):void {
			for (var canvas:Canvas; _numChildren > keep; _numChildren--) {
				if ((canvas = removeChildAt(0) as Canvas) != null) {
					if (canvas.modifiedGraphics) canvas.gfx.clear();
					canvas.removeChildren(0), collector[collectorLength++] = canvas;
				}
			}
		}
		
	}
}