package com.dare.sonyericsson.liquidlife.lib.metaballs {
	import flash.display.Sprite;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.filters.BlurFilter;
	import flash.filters.BitmapFilterQuality;
	import flash.geom.Rectangle;
	import flash.geom.Point;	

	/**
	 * Creates a number of metaballs and renders them
	 * 
	 * @author wijnand.warren
	 */
	public class MetaBallRenderer extends Sprite {
		
		private var _renderWidth:int;
		private var _renderHeight:int;
		private var _numberOfBalls:int;
		private var minRadius:Number;
		private var maxRadius:Number;
		
		private var _ballList:Array;
		private var _graphicList:Array;
		private var container:Sprite;
		
		// balls
		private var bitmap:Bitmap;
        private var bitmapData:BitmapData;
        private var targetColour:uint;
		//balls mask
		private var maskBitmap:Bitmap;
        private var maskBitmapData:BitmapData;
		
		/**
		 * CONSTRUCTOR
		 */
		public function MetaBallRenderer(width:int, height:int, numberOfBalls:int, minRadius:Number, maxRadius:Number, colour:uint=0x3fb9ff) {
			_renderWidth = width;
			_renderHeight = height;
			_numberOfBalls = numberOfBalls;
			this.minRadius = minRadius;
			this.maxRadius = maxRadius;
			targetColour = colour | 0xff << 24;
			
			init();
		}
		
		/**
		 * 
		 */
		private function init():void {
			// TODO: use vector instead?
			_ballList = new Array();
			_graphicList = new Array();
			container = new Sprite();
 
            for (var i:uint = 0; i < _numberOfBalls; i++) {
                var radius:uint = Math.round(Math.random() * (maxRadius - minRadius) + minRadius);
                
                var ball : MetaBall = new MetaBall(radius);
				_ballList.push(ball);
                
                container.addChild(ball);
            }

            // According to Help blurX and blurY values that are power of 2 are optimized
            // to render more quickly
            container.filters = [new BlurFilter(32, 32, BitmapFilterQuality.MEDIUM)];
 
            renderFrame();
 
            addChild(bitmap);
		}
		
		// ============================
		// PUBLIC
		// ============================
		
		/**
		 * Renders the current scene 
		 */
		public function renderFrame():void {
//			trace("MetaBallRenderer.renderFrame()");
			
			if(bitmap) removeChild(bitmap);
			if(maskBitmap) removeChild(maskBitmap);
			
            var bounds:Rectangle = new Rectangle(0, 0, _renderWidth, _renderHeight);
            var zeroPoint:Point = new Point(0, 0);
 
			//draw to bitmap:
            bitmapData = new BitmapData(_renderWidth, _renderHeight, false, 0x00ffffff);
            bitmap = new Bitmap(bitmapData.clone());
            bitmapData.draw(container);
 
//			bitmap.bitmapData.threshold(bitmapData, bounds, zeroPoint, "<", 0x00ee00, 0xFFFF0000, 0x0000FF00, false);
			bitmap.bitmapData.threshold(bitmapData, bounds, zeroPoint, "<", 0x00ee00, targetColour, 0x0000FF00, false);
			addChild(bitmap);
			
			// Create mask
			maskBitmapData = new BitmapData(_renderWidth, _renderHeight, true, 0x00ffffff);
            maskBitmap = new Bitmap(maskBitmapData.clone());
            maskBitmapData.draw(container);
			
			maskBitmap.bitmapData.threshold(bitmap.bitmapData, bounds, zeroPoint, ">=", 0xffffff, 0x0000ff00, 0x00ffffff, true);
			addChild(maskBitmap);
			
			// masking, so we can apply some filters to this later
			bitmap.cacheAsBitmap = true;
			maskBitmap.cacheAsBitmap = true;
			bitmap.mask = maskBitmap;
		}
		
		// ============================
		// GETTERS
		// ============================
		public function get ballList():Array
		{
			return _ballList;
		}
		/*public function set ballList( value:Array ):void
		{
			_ballList = value;
		}*/
		
		public function get numberOfBalls():int
		{
			return _numberOfBalls;
		}
		/*public function set numberOfBalls( value:int ):void
		{
			_numberOfBalls = value;
		}*/
	}
}
