function Strip(x, y, w, h) constructor {
    self.x = x;
	self.y = y;
	self.w = w;
	self.h = h;
}

function sprite_pack_skyline(rectangles, width, height) {
	var maxw = 0;
	var maxh = 0;
    
    array_sort(rectangles, function(a, b) {
        return b.w - a.w;
    });
    
    var skyline = [ new Strip(0, 0, width, height) ];
    var packed  = [];
	
    for (var i = 0; i < array_length(rectangles); i++) {
        var rect = rectangles[i];
        var bestStrip  = noone;
        var bestWasted = width * height;
        
        for (var j = 0; j < array_length(skyline); j++) {
            var strip = skyline[j];
            if (strip.w >= rect.w && strip.h >= rect.h) {
                var wasted = strip.w * strip.h;
                if (wasted <= bestWasted) {
                    bestStrip = strip;
                    bestWasted = wasted;
                }
            }
        }
        
        if (bestStrip == noone) continue;
		
        rect.x = bestStrip.x;
        rect.y = bestStrip.y;
        array_push(packed, rect);
			
        if (bestStrip.w > rect.w)
            array_push(skyline, new Strip(bestStrip.x + rect.w, bestStrip.y, bestStrip.w - rect.w, bestStrip.h));
            
        if (bestStrip.h > rect.h)
            array_push(skyline, new Strip(bestStrip.x, bestStrip.y + rect.h, rect.w, bestStrip.h - rect.h));
            
        array_remove(skyline, bestStrip);
            
        array_sort(skyline, function(a, b) {
            return a.x - b.x;
        });
		
		maxw = max(maxw, rect.x + rect.w);
		maxh = max(maxh, rect.y + rect.h);
    }
    
    return [ new Rectangle(0, 0, maxw, maxh), packed ];
}