Bubbles cleanup and bug fixes.
diff --git a/src/com/savoirfairelinux/sflphone/model/Attractor.java b/src/com/savoirfairelinux/sflphone/model/Attractor.java
index 51b1850..fed2690 100644
--- a/src/com/savoirfairelinux/sflphone/model/Attractor.java
+++ b/src/com/savoirfairelinux/sflphone/model/Attractor.java
@@ -9,7 +9,14 @@
 public class Attractor {
 
 	public interface Callback {
-		public void onBubbleSucked(Bubble b);
+
+		/**
+		 * Called when a bubble is on the "active" zone of the attractor.
+		 * 
+		 * @param b The bubble that is on the attractor.
+		 * @return true if the bubble should be removed from the model, false otherwise.
+		 */
+		public boolean onBubbleSucked(Bubble b);
 	}
 
 	final PointF pos;
@@ -20,9 +27,9 @@
 
 	private final RectF bounds = new RectF();
 
-	public Attractor(PointF pos, float radius, Callback callback, Bitmap img) {
+	public Attractor(PointF pos, float size, Callback callback, Bitmap img) {
 		this.pos = pos;
-		this.radius = radius;
+		this.radius = size/2;
 		this.callback = callback;
 		this.img = img;
 	}
diff --git a/src/com/savoirfairelinux/sflphone/model/Bubble.java b/src/com/savoirfairelinux/sflphone/model/Bubble.java
index 546bb3c..a45b746 100644
--- a/src/com/savoirfairelinux/sflphone/model/Bubble.java
+++ b/src/com/savoirfairelinux/sflphone/model/Bubble.java
@@ -37,36 +37,32 @@
 		this.attractor = attractor;
 	}
 
-	public Bubble(float x, float y, float rad, Bitmap photo) {
-		internalBMP = photo;
-		pos.set(x, y);
-
-		internalBMP = Bitmap.createScaledBitmap(internalBMP, (int) rad, (int) rad, false);
+	public Bubble(float x, float y, float size, Bitmap photo) {
+		internalBMP = Bitmap.createScaledBitmap(photo, (int) size, (int) size, false);
 		int w = internalBMP.getWidth(), h = internalBMP.getHeight();
 
-		externalBMP = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+		pos.set(x, y);
+		radius = w / 2;
+		bounds = new RectF(pos.x - radius, pos.y - radius, pos.x + radius, pos.y + radius);
+		attractor = new PointF(x, y);
 
-		radius = externalBMP.getWidth() / 2;
 		Path path = new Path();
-
 		path.addCircle(radius, radius, radius, Path.Direction.CW);
 
-		bounds = new RectF(pos.x - radius, pos.y - radius, pos.x + radius, pos.y + radius);
-
-		Paint mPaintPath = new Paint(Paint.ANTI_ALIAS_FLAG);
-		mPaintPath.setStyle(Paint.Style.FILL);
-		mPaintPath.setAntiAlias(true);
+		Paint circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+		circlePaint.setStyle(Paint.Style.FILL);
 		Bitmap circle = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
 		Canvas circle_drawer = new Canvas(circle);
-		circle_drawer.drawOval(new RectF(0, 0, w, h), mPaintPath);
+		circle_drawer.drawOval(new RectF(0, 0, w, h), circlePaint);
 
-		attractor = new PointF(x, y);
-		mPaintPath.setFilterBitmap(false);
+		externalBMP = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
+		Canvas canvas = new Canvas(externalBMP);
 
-		Canvas internalCanvas = new Canvas(externalBMP);
-		internalCanvas.drawBitmap(internalBMP, 0, 0, mPaintPath);
-		mPaintPath.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
-		internalCanvas.drawBitmap(circle, 0, 0, mPaintPath);
+		circlePaint.setFilterBitmap(false);
+		canvas.drawBitmap(internalBMP, 0, 0, circlePaint);
+
+		circlePaint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
+		canvas.drawBitmap(circle, 0, 0, circlePaint);
 	}
 
 	public Bubble(float x, float y, float rad, Context c, int resID) {
@@ -87,10 +83,7 @@
 		pos.x = x;
 		pos.y = y;
 		float rad = scale*radius*density;
-		bounds.left = pos.x - rad;
-		bounds.right = pos.x + rad;
-		bounds.top = pos.y - rad;
-		bounds.bottom = pos.y + rad;
+		bounds.set(pos.x-rad, pos.y-rad, pos.x+rad, pos.y+rad);
 	}
 
 	public float getPosX() {
diff --git a/src/com/savoirfairelinux/sflphone/model/BubbleModel.java b/src/com/savoirfairelinux/sflphone/model/BubbleModel.java
index 87d3718..5631a86 100644
--- a/src/com/savoirfairelinux/sflphone/model/BubbleModel.java
+++ b/src/com/savoirfairelinux/sflphone/model/BubbleModel.java
@@ -101,7 +101,8 @@
 				PointF attractor_pos = b.attractor;
 				float attractor_dist = (attractor_pos.x-bx)*(attractor_pos.x-bx) + (attractor_pos.y-by)*(attractor_pos.x-by);
 
-				for(Attractor t : attractors) {
+				for(int j=0; j<attr_n; j++) {
+					Attractor t = attractors.get(j);
 					float dx = t.pos.x-bx, dy = t.pos.y-by;
 					float adist = dx*dx + dy*dy;
 					if(adist < attractor_dist) {
@@ -163,9 +164,13 @@
 				b.setPos((float)(bx+dx), (float)(by+dy));
 
 				if(attractor != null && attractor_dist < attractor_dist_suck*attractor_dist_suck) {
-					attractor.callback.onBubbleSucked(b);
-					bubbles.remove(b);
-					n--;
+					b.dragged = false;
+					if(attractor.callback.onBubbleSucked(b)) {
+						bubbles.remove(b);
+						n--;
+					} else {
+						b.target_scale = 1.f;
+					}
 				}
 			}
 
diff --git a/src/com/savoirfairelinux/sflphone/model/BubblesView.java b/src/com/savoirfairelinux/sflphone/model/BubblesView.java
index 8ca439a..2ee08fd 100644
--- a/src/com/savoirfairelinux/sflphone/model/BubblesView.java
+++ b/src/com/savoirfairelinux/sflphone/model/BubblesView.java
@@ -30,6 +30,8 @@
 	private float density;

 	private float textDensity;

 

+	private boolean dragging_bubble = false;

+

 	public BubblesView(Context context, AttributeSet attrs)

 	{

 		super(context, attrs);

@@ -48,7 +50,7 @@
 

 		attractor_paint.setColor(Color.RED);

 		//attractor_paint.set

-		name_paint.setTextSize(18*textDensity);

+		name_paint.setTextSize(18 * textDensity);

 		name_paint.setColor(0xFF303030);

 		name_paint.setTextAlign(Align.CENTER);

 	}

@@ -140,53 +142,60 @@
 			final int n_bubbles = bubbles.size();

 

 			if (action == MotionEvent.ACTION_DOWN) {

-				for(int i=0; i<n_bubbles; i++) {

+				for (int i = 0; i < n_bubbles; i++) {

 					Bubble b = bubbles.get(i);

 					if (b.intersects(event.getX(), event.getY())) {

 						b.dragged = true;

 						b.last_drag = System.nanoTime();

 						b.setPos(event.getX(), event.getY());

 						b.target_scale = .8f;

+						dragging_bubble = true;

 					}

 				}

 			} else if (action == MotionEvent.ACTION_MOVE) {

 				long now = System.nanoTime();

-				for(int i=0; i<n_bubbles; i++) {

+				for (int i = 0; i < n_bubbles; i++) {

 					Bubble b = bubbles.get(i);

 					if (b.dragged) {

 						float x = event.getX(), y = event.getY();

-						float dt = (float) ((now-b.last_drag)/1000000000.);

+						float dt = (float) ((now - b.last_drag) / 1000000000.);

 						float dx = x - b.getPosX(), dy = y - b.getPosY();

 						b.last_drag = now;

 

 						b.setPos(event.getX(), event.getY());

 						/*int hn = event.getHistorySize() - 2;

-					Log.w(TAG, "event.getHistorySize() : " + event.getHistorySize());

-					if(hn > 0) {

+						Log.w(TAG, "event.getHistorySize() : " + event.getHistorySize());

+						if(hn > 0) {

 						float dx = x-event.getHistoricalX(hn);

 						float dy = y-event.getHistoricalY(hn);

 						float dt = event.getHistoricalEventTime(hn)/1000.f;*/

-						b.speed.x = dx/dt;

-						b.speed.y = dy/dt;

+						b.speed.x = dx / dt;

+						b.speed.y = dy / dt;

 						//Log.w(TAG, "onTouch dx:" + b.speed.x + " dy:" + b.speed.y);

 						//}

 						return true;

 					}

 				}

 			} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {

-				for(int i=0; i<n_bubbles; i++) {

+				for (int i = 0; i < n_bubbles; i++) {

 					Bubble b = bubbles.get(i);

 					if (b.dragged) {

 						b.dragged = false;

 						b.target_scale = 1.f;

 					}

 				}

+				dragging_bubble = false;

 			}

 		}

 

 		return true;

 	}

 

+	public boolean isDraggingBubble()

+	{

+		return dragging_bubble;

+	}

+

 	class BubblesThread extends Thread

 	{

 		private boolean running = false;

@@ -251,17 +260,15 @@
 				List<Bubble> bubbles = model.getBubbles();

 				List<Attractor> attractors = model.getAttractors();

 

-				for (int i=0, n=attractors.size(); i < n; i++) {

+				for (int i = 0, n = attractors.size(); i < n; i++) {

 					Attractor a = attractors.get(i);

-					//canvas.drawCircle(a.pos.x, a.pos.y, 10, attractor_paint);

 					canvas.drawBitmap(a.getBitmap(), null, a.getBounds(), null);

 				}

 

-				for (int i=0, n=bubbles.size(); i<n; i++) {

+				for (int i = 0, n = bubbles.size(); i < n; i++) {

 					Bubble b = bubbles.get(i);

-					//RectF bounds = new RectF(b.getBounds());

 					canvas.drawBitmap(b.getBitmap(), null, b.getBounds(), null);

-					canvas.drawText(b.contact.getmDisplayName(), b.getPosX(), b.getPosY()-50*density, name_paint);

+					canvas.drawText(b.contact.getmDisplayName(), b.getPosX(), b.getPosY() - 50 * density, name_paint);

 				}

 			}

 		}