/*
	Реализация спецификаций CLDC версии 1.1 (JSR-139), MIDP версии 2.1 (JSR-118)
	и других спецификаций для функционирования компактных приложений на языке
	Java (мидлетов) в среде программного обеспечения Малик Эмулятор.

	Copyright © 2016, 2019 Малик Разработчик

	Это свободная программа: вы можете перераспространять ее и/или изменять
	ее на условиях Меньшей Стандартной общественной лицензии GNU в том виде,
	в каком она была опубликована Фондом свободного программного обеспечения;
	либо версии 3 лицензии, либо (по вашему выбору) любой более поздней версии.

	Эта программа распространяется в надежде, что она будет полезной,
	но БЕЗО ВСЯКИХ ГАРАНТИЙ; даже без неявной гарантии ТОВАРНОГО ВИДА
	или ПРИГОДНОСТИ ДЛЯ ОПРЕДЕЛЕННЫХ ЦЕЛЕЙ. Подробнее см. в Меньшей Стандартной
	общественной лицензии GNU.

	Вы должны были получить копию Меньшей Стандартной общественной лицензии GNU
	вместе с этой программой. Если это не так, см.
	<https://www.gnu.org/licenses/>.
*/


package javax.microedition.lcdui;

public class TextOutputMultilined extends TextOutput
{
	public static final char LINE_SEPARATOR = '\n';
	public static final char WHITE_SPACE = '\u0020';


	protected int linesCount;
	protected int[] linesBounds;

	public TextOutputMultilined()
	{
	}

	public TextOutputMultilined(int capacity)
	{
		super(capacity);
	}

	public void split(Font font, int width)
	{
		boolean ending;
		char ch;
		int i;
		int j;
		int s;
		int e;
		int n;
		int w;
		int line = 0;
		int len = length;
		char[] c = chars;
		int[] l = new int[17];
		for(i = s = 0; i <= len; i = s = n)
		{
			w = 0;
			do
			{
				if((ending = i >= len) || (ending = (ch = c[i]) == LINE_SEPARATOR) ||
						(j = w + font.charWidth(ch)) > width)
				{
					break;
				}
				w = j;
				i++;
			} while(true);
			if(ending)
			{
				n = (e = i) + 1;
			}
			else if(i == s)
			{
				n = e = s + 1;
			}
			else
			{
				n = e = i;
				for(j = i - 1; j > s; j--)
				{
					if((ch = c[j]) == WHITE_SPACE)
					{
						n = (e = j) + 1;
						break;
					}
					if(isWordSeparator(ch))
					{
						n = e = j + 1;
						break;
					}
				}
			}
			if(l.length == line + 1)
			{
				Array.copy(l, 0, l = new int[(line << 1) - 1], 0, line);
			}
			l[line++] = s;
			l[line++] = e - s;
		}
		l[line] = len;
		linesCount = line >> 1;
		linesBounds = l;
	}

	public boolean isWordSeparator(char c)
	{
		return (c >= 0 && c <= 32) || c == '!' || c == '%' || c == '&' ||
				(c >= ')' && c <= '/') || (c >= ':' && c <= '@') || (c >= '\\' && c <= '`') ||
				(c >= '|' && c <= '~');
	}

	public final int getLinesCount()
	{
		return linesCount;
	}

	public final int getLineStart(int lineIndex)
	{
		int linesCount;
		return (linesCount = this.linesCount) > 0 &&
				lineIndex >= 0 && lineIndex <= linesCount ? linesBounds[lineIndex << 1] : -1;
	}

	public final int getLineLength(int lineIndex)
	{
		return lineIndex >= 0 && lineIndex < linesCount ? linesBounds[(lineIndex << 1) + 1] : 0;
	}

	public final int getLineAt(int position)
	{
		int a;
		int b;
		int c;
		int a1;
		int a2;
		int a3;
		int count;
		int[] bounds = linesBounds;
		a = 0;
		b = (count = linesCount) >> 1;
		c = count;
		do
		{
			a1 = bounds[a << 1];
			a2 = bounds[b << 1];
			a3 = bounds[c << 1];
			if(b - a <= 1 && c - b <= 1)
			{
				break;
			}
			if(position >= a1 && position < a2)
			{
				c = b;
				b = (a + c) >> 1;
				continue;
			}
			if(position >= a2 && position <= a3)
			{
				a = b;
				b = (a + c) >> 1;
				continue;
			}
			return -1;
		} while(true);
		if(position >= a2)
		{
			if(b >= 0 && b <= count)
			{
				return b;
			}
		}
		if(position >= a1)
		{
			if(a >= 0 && a <= count)
			{
				return a;
			}
		}
		return -1;
	}
}
