
package com.netgrind.core {
	import flash.geom.Rectangle;
	
	/**
	 * ...
	 * @author netgrind
	 */
	public class UtilsArray {
		
		public static function merge2d(parent:Array, child:Array, x:int, y:int):Array {
			for (var i:int = 0; i < child.length; i ++) {
				for (var j:int = 0; j < child[i].length; j++) {
					parent[i + x][j + y] = child[i][j];
				}//end for
			}
			return parent;
		}
		
		public static function fill2d(width:int, height:int, fill:*=null):Array {
			var a:Array = new Array();
			for (var i:int = 0; i < width; i++) {
				a.push(new Array());
				for (var j:int = 0; j < height; j++) {
					a[i][j] = fill;
				}//end for
			}//end for
			return a;
		}//end getBlankWorld
		
		public static function rotate2d(array:Array):Array {
			var a:Array = new Array();
			for (var i:int = 0; i < array.length; i++) {				
				for (var j:int = 0; j < array[0].length; j++) {
					if (!a[j]) {
						a[j] = new Array();
					}
					a[j][i] = array[i][j];					
				}//end for				
			}//end for
			return a;
		}//end rotateArray
		
		public static function swapValues2d(a:Array, oldVal:*, newVal:*):Array{
			for (var i:int = 0; i < a.length; i++) {
				for (var j:int = 0; j < a[i].length; j++) {
					if (a[i][j] == oldVal) {
						a[i][j] = newVal;
					}
				}
			}
			return a;
		}
		
		public static function flood2d(a:Array, i:int, j:int, oldVal:*, newVal:*):Array {
			if(i>-1&& i<a.length && j>-1 && j < a[i].length){
				if (a[i][j] == oldVal) {
					a[i][j] = newVal;
					flood2d(a, i + 1, j, oldVal, newVal);
					flood2d(a, i - 1, j, oldVal, newVal);
					flood2d(a, i, j+1, oldVal, newVal);
					flood2d(a, i, j-1, oldVal, newVal);
				}
			}
			return a
		}
		
		public static function hasValue2d(a:Array, val:*):Boolean {
			for (var i:int = 0; i < a.length; i++) {
				if (a[i].indexOf(val) != -1) {
					return true
				}
			}//end for
			return false;
		}
		
		public static function clone2d(a:Array):Array {
			var b:Array = [];
			for (var i:int = 0; i < a.length; i++) {
				b.push([]);
				for (var j:int = 0; j < a[i].length; j++) {
					b[i][j] = a[i][j];
				}
			}
			return b;
		}
		
		public static function getRectFrom(a:Array, x:int, y:int, convertTo:*= null):Object {
			var val:* = a[x][y];
			var locki:int = -1
			var lockj:int = -1
			for (var i:int = x; i < a.length; i++) {
				for (var j:int = y; j < a[i].length; j++) {
					if (lockj!=-1 && j>= lockj) {
						break;
					}
					if (a[i][j] != val) {
						if (lockj==-1) {
							lockj = j;
							break;
						}else if (locki == -1) {
							if (convertTo) {
								for (var k:int = x; k < i; k++) {
									for (var l:int = y; l < lockj; l++) {
										a[k][l] = convertTo;
									}
								}
							}
							return { x:x, y:y, w:Math.max(i - x,1), h:Math.max(lockj - y,1) };
						}
					}
				}
			}
			return null;
		}
		
		static public function slice2d(array:*, rect:Rectangle):Array {
			var a:Array = new Array();
			for (var i:int = rect.x;i<array.length && i <rect.x+rect.width; i++) {
				a.push([]);
				for (var j:int = rect.y; j < array[i].length && j < rect.y + rect.height; j++) {
					a[i-rect.x].push(array[i][j]);
				}
			}
			return a;
		}
		
		static public function fill(length:int, fill:*):Array {
			var a:Array = new Array()
			for (var i:int = 0; i < length; i++) {
				a[i]=(fill);
			}
			return a;
		}
		
		static public function randomize(a:Array, num:Number):Array {
			for (var i:int = 0; i < a.length; i++) {
				a[i] += Math.random() * num - num * .5;
			}
			return a;
		}
		
		
		//WARNING DOES NOT RETURN SAME OBJECT
		static public function randomizeContent(a:Array):Array {
			var b: Array = [];
			while (a.length) {
				var i:int = Math.floor(Math.random() * a.length);
				b.push(a[i]);
				a.splice(i, 1);
			}
			return b;
		}
		
		static public function sine(a:Array, amp:Number=1, freq:Number = 1, phase:Number=0):Array {
			for (var i:int = 0; i < a.length; i++) {
				a[i] +=  amp * Math.sin(Utils.degToRad(freq*i+phase));
			}
			return a;
		}
		
		static public function linear(length:int = 100, offset:Number = 1):Array {
			var a:Array = [offset];
			for (var i:int = 1; i < length; i++) {
				a[i] = a[i-1]+offset;
			}
			return a;
		}
		
		static public function add(a:Array, b:Array):Array {
			var c:Array = []
			for (var i:int = 0; i < Math.min(a.length, b.length); i++) {
				c[i] = a[i] + b[i];
			}
			return c;
		}
		
		static public function vectorFill(v:*,num:int,fill:*):* {
			for (var i:int = 0; i < num; i++) {
				v.push(fill);
			}
			return v;
		}
		
		static public function circle(a:Array,rad:Number,offset:Number,sinVal:String='x',cosVal:String='y'):void {
			var deg:Number = 360 / a.length;
			for (var i:int = 0; i < a.length; i++) {
				var angle:Number = (deg * i+offset) * Math.PI / 180;
				a[i][sinVal] = Math.sin(angle)*rad
				a[i][cosVal] = Math.cos(angle)*rad
			}
		}
		
	}
	
}