-- functions for drawing


local function drawSprite(byte, nextByte, settings)
	local sprite = IMGFRAME:Clone();
	local child = settings.child;
	local attached = settings.attached;
	
	local sizeSet = settings.styles[settings.style][settings.size];
	local character = sizeSet.characters[byte];
	
	-- fill in the defining properties
	sprite.Name = byte;
	sprite.ImageColor3 = child.TextColor3;
	sprite.ImageTransparency = attached.TextTransparency;
	sprite.ZIndex = child.ZIndex;
	
	-- setup the image
	sprite.Image = settings.atlases[character.atlas + 1];
	sprite.ImageRectSize = vector2(character.width, character.height);
	sprite.ImageRectOffset = vector2(character.x, character.y);
	
	-- kerning
	local kernx, kerny = 0, 0
	if (nextByte and sizeSet.kerning[byte] and sizeSet.kerning[byte][nextByte]) then
		local k = sizeSet.kerning[byte][nextByte];
		kernx = k.x;
		kerny = k.y;
	end;
	
	-- positioning
	sprite.Position = udim2(0, kernx, 0, character.yoffset + kerny);
	sprite.Size = udim2(0, character.width, 0, character.height);
	
	return sprite, kernx, kerny + character.yoffset + character.height;
end;

local function drawLine(text, height, gsprites, settings)
	local width = 0;
	local maxheight = 0;
	local sprites = {};

	local child = settings.child;
	local attached = settings.attached;
	
	local ntext = #text;
	local sizeSet = settings.styles[settings.style][settings.size];
	
	for i = 1, ntext do
		local i2 = i + 1 <= ntext and i + 1;
		local b = byte(sub(text, i, i));
		local b2 = i2 and byte(sub(text, i2, i2));
		local character, kernx, mheight = drawSprite(b, b2, settings);
		maxheight = mheight > maxheight and mheight or maxheight
		character.Position = character.Position + udim2(0, width, 0, height);
		width = width + (i2 and sizeSet.characters[b].xadvance or sizeSet.characters[b].width) + kernx;
		insert(sprites, character);
		insert(gsprites, character);
	end;
	
	local xalign = getAlignMultiplier(child.TextXAlignment);
	local adjust = (abs(child.AbsoluteSize.x) - width) * xalign;
	for i = 1, ntext do
		local character = sprites[i];
		character.Position = character.Position + udim2(0, adjust, 0, 0);
	end;
	
	return width, maxheight;
end;

local function drawLines(text, settings, parent)
	local child = settings.child;	
	
	if (child.TextScaled) then
		settings.size = scaleText(text, settings);
	end;

	local lines = child.TextWrapped and wrapText(text, settings.size, settings) or getLines(text);
	local lineHeight = settings.styles[settings.style][settings.size].lineHeight;
	
	local widths = {0};
	local height = -settings.styles[settings.style][settings.size].firstAdjust;
	local sprites = {};
	
	for i = 1, #lines do
		local line = lines[i];
		local width, lh = drawLine(line, height, sprites, settings);
		height = height + lh;
		insert(widths, width);
	end;
	
	local yalign = getAlignMultiplier(child.TextYAlignment);
	local adjust = (abs(child.AbsoluteSize.y) - height) * yalign;
	for i = 1, #sprites do
		local character = sprites[i];
		character.Position = character.Position + udim2(0, 0, 0, adjust);
		character.Parent = parent;
	end;
	
	return sprites;
end;