package Engine
{
	import flash.display.BitmapData;
	import flash.geom.Matrix;
	import flash.geom.Rectangle;
	import Game.Objects.Bullets.SimpleBullet;
	
	/**
	 * ...
	 * @author ...
	 */
	public class SpriteGroup extends GameSprite
	{
		public var Sprites:Array;
		
		public var zSorting:Boolean = true;
		public var CollisionCheck:Boolean = false;
		
		private var _matrix:Matrix = new Matrix();
		private var _clipRect:Rectangle = null;
		
		/**
		 *
		 */
		override public function AddedToEngine():void
		{
			for (var i:int = 0; i < Sprites.length; i++) {
				GameSprite(Sprites[i]).AddedToEngine();
			}
			super.AddedToEngine();
		}
		
				/**
		 * Функция сортировки по zIndex
		 * @param	a
		 * @param	b
		 * @return
		 */
		private function zIndexSortFunction(a:GameSprite, b:GameSprite):int {
			if (a.zIndex < b.zIndex) {
				return -1;
			}else if (a.zIndex > b.zIndex) {
				return 1;
			}else {
				return 0;
			}
		}
		
		/**
		 * Подготовка списка спрайтов для прорисовки
		 */
		public function prepareSprites():void {
			var i:int;
			var j:int;
			
			if (CollisionCheck) {
				for (i = 0; i < Sprites.length - 1; i++) {
					var op1:GameSprite = Sprites[i];
					
					if (!op1.CollisionEnabled) {
						continue;
					}
					
					for (j = 1; j < Sprites.length; j++) {
						
						var op2:GameSprite = Sprites[j];
						
						if (!op2.CollisionEnabled) {
							continue;
						}
						
						if (op1.Rect.intersects(op2.Rect)) {
							op1.Collision(op2);
							op2.Collision(op1);
						}
					}
				}
			}
			
			/** Удаление лишьних **/
			for (i = Sprites.length - 1; i >= 0; i--) {
				var current:GameSprite = Sprites[i];
				
				if (current.Delete) {
					Sprites[i] = Sprites[Sprites.length-1];
					Sprites.pop();
				}
			}
			
			/** Сортировка по zIndex **/
			if (zSorting) {
				Sprites.sort(zIndexSortFunction);
			}
		}
		
		override public function Draw(surface:BitmapData, inmatrix:Matrix = null):void
		{
			_matrix.identity();
			if (inmatrix != null) {
				_matrix.concat(inmatrix);
			}
						
			_matrix.scale(scale, scale);
			_matrix.translate(x, y);
			
			prepareSprites();
			
			for (var i:int = 0; i < Sprites.length; i++) {
				var Current:GameSprite = Sprites[i];
				Current.Draw(surface, _matrix);
				
				if (_clipRect != null) {
					if(Current.Rect != null) {
						if (!_clipRect.intersects(Current.Rect)) {
							Current.outside = true;
						}else {
							Current.outside = false;
						}
					}
				}
			}
		}
		
		override public function Move():void
		{
			for (var i:int = 0; i < Sprites.length; i++) {
				GameSprite(Sprites[i]).Move();
			}
		}
		
		override public function Play():void
		{
			for (var i:int = 0; i < Sprites.length; i++) {
				GameSprite(Sprites[i]).Play();
			}
		}
		
		override public function get Rect():Rectangle
		{
			return _clipRect;
		}
		
		override public function get rotation():Number
		{
			return super.rotation;
		}
		
		override public function set rotation(value:Number):void
		{
			super.rotation = value;
		}
		
		public function get spriteCount():uint {
			var res:uint = 0;
			for (var i:uint = 0; i < Sprites.length; i++) {
				if (Sprites[i] is SpriteGroup) {
					res += SpriteGroup(Sprites[i]).spriteCount;
				}else{
					if (Sprites[i] is GameSprite) {
						res++;
					}
				}
			}
			
			return res;
		}
		
		public function AddSprite(newSprite:GameSprite):void {
			Sprites[Sprites.length] = newSprite;
			newSprite.parentEngine = parentEngine;
			newSprite.Group = this;
		}
		
		public function SetClipRect(clipRect:Rectangle):void {
			_clipRect = clipRect;
			trace(this, 'clip rect is', clipRect);
		}
		
		public function SpriteGroup()
		{
			Sprites = new Array();
			super(null, null);
		}
		
	}

}