function arrangeWindows (forced) {
	
	var windows = new Array();
	var windowsCount = 0;
	
	$$('.moving').each(function(el) { 
		if (!el.hasClass('closing')) {
			windows[windowsCount++] = el;
			if (el.curFx) el.curFx.pause();
		}
	});
	
	windows.sort(compareBlocks);	
	
	// Odstepy miedzy oknami
	var margin = 20;

	var containerWidth = $('container').getWidth() - margin;
	
	// Ustawiamy zerowy fikcyjny wiersz, zeby miec punkt odniesienia
	var rows = new Array();
	rows[0] = 0;
	var processed = new Array();
	var procCount = 0;
	var rowCount = 1;
	
	var cur = 0;
	while (cur < windowsCount) {
		//
		var i;
		for (i = 0; i < rowCount; i++) {
			var left = margin;
			
			okRow = 0;
			if (procCount > 0) {
				while (left + windows[cur].getWidth() <= containerWidth + margin) {
					// Obliczamy aktualny srodek okienka i miejsce do ktorego, chcemy je przeniesc
					var ax = windows[cur].getStyle('left').toInt() + (windows[cur].getWidth() / 2);
					var ay = windows[cur].getStyle('top').toInt() + (windows[cur].getHeight() / 2);
					var bx = left + (windows[cur].getWidth() / 2);
					var by = rows[i] + (windows[cur].getHeight() / 2);
					
					// Kwadrat odleglosci, ktora przebedzie okienko
					var dist = (ax - bx) * (ax - bx) + (ay - by) * (ay - by);
					
					//
					var k = 0;
					while (k < procCount) {
						// Sprawdzamy, czy jest miejsce
						if (processed[k].row + processed[k].height + margin > rows[i] && ((left <= processed[k].left && left + windows[cur].getWidth() + margin > processed[k].left) || (left >= processed[k].left && processed[k].right > left)) ) {
							break;
						}
							

						//
						k++;
					}
					
					if (k < processed.length) {
						left = processed[k].right;
						continue;
					}
					
					
					/*
					var k = 0;
					while (k < procCount) {
						// Liczymy rogi okienka processed[k], zeby sprawdzic, czy blokuje droge
						var tl = processed[k].left, tr = processed[k].right, tt = processed[k].row, tb = processed[k].row + processed[k].height;
						
						//
						if (segmentsIntersect(ax, ay, bx, by, tl, tt, tr, tt) && segmentsIntersect(ax, ay, bx, by, tr, tb, tl, tb)) {
							//break;
						}
						if (segmentsIntersect(ax, ay, bx, by, tr, tt, tr, tb) && segmentsIntersect(ax, ay, bx, by, tl, tb, tl, tt)) {
							//break;
						}				
							

						//
						k++;
					}*/
					
					//
					if (k == processed.length) {
						okRow = 1;
						break;
					}
					
					if (left < processed[k].right) {
						left = processed[k].right;
					}else {
						break;
					}

					
				}
			}else {
				okRow = 1;
			}
			
			if (okRow) {
				// Przestawiamy okienko
				windows[cur].curFx = new Fx.Morph(windows[cur], { duration: (Math.min(200+Math.ceil(Math.random()*800)), 1150), transition: Fx.Transitions.Sine.easeOut });
				windows[cur].curFx.start({
					'left': left,
					'top': rows[i]
				});
				
				
				processed[procCount++] = { right: left + windows[cur].getWidth() + margin,
											height: windows[cur].getHeight(),
											left: left,
											row: rows[i] };

				var curRow = rows[i] + windows[cur].getHeight() + margin;
				
				var t = 0;
				while (t < rowCount && curRow > rows[t]) t++;
				
				if (t == rowCount) {
					rows[rowCount++] = curRow;
				}else if (rows[t] != curRow) {
					for (var pnt = rowCount; pnt >= t; pnt--) {
						rows[pnt + 1] = rows[pnt]
					}
					rows[t] = curRow;
					rowCount++;
				}

				
				//
				break;
			}
		}
		
		
		//
		cur++;
	}
	

}

function compareBlocks (a, b) {
		var ay = a.getPosition().y;
		var by = b.getPosition().y;
		var ax = a.getPosition().x;
		var bx = b.getPosition().x;
		
		var aw = a.getWidth();
		var bw = b.getWidth();
		var ah = a.getHeight();
		var bh = b.getHeight();
		
		if (ay != by) {
			return ay - by;
		} else if (ax != bx) {
			return ax - bx;
		} else if (aw != bw) {
			return bw - aw;
		} else {
			return bh - ah;
		}
	}
