/*
	Реализация спецификаций 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;

import malik.emulator.media.text.*;

public final class Font extends Object
{
	public static final int FONT_STATIC_TEXT = 0;
	public static final int FONT_INPUT_TEXT = 1;
	public static final int FACE_SYSTEM = 0;
	public static final int FACE_MONOSPACE = 32;
	public static final int FACE_PROPORTIONAL = 64;
	public static final int STYLE_PLAIN = 0;
	public static final int STYLE_BOLD = 1;
	public static final int STYLE_ITALIC = 2;
	public static final int STYLE_UNDERLINED = 4;
	public static final int SIZE_SMALL = 8;
	public static final int SIZE_MEDIUM = 0;
	public static final int SIZE_LARGE = 16;
	private static final Font[] RASTER_FONTS;
	private static final Font[][] FONTS;

	static
	{
		int i;
		int j;
		Font[] f;
		Font[][] fonts = new Font[3][24];
		MIDletProxy proxy = MIDletProxy.getInstance();
		for(j = fonts.length; j-- > 0; )
		{
			for(i = (f = fonts[j]).length; i-- > 0; )
			{
				f[i] = new Font(proxy.getFont(i >> 3, i & 0x03), j << 5, i & 0x07, i & (-0x08));
			}
		}
		RASTER_FONTS = new Font[RasterFont.getRasterFontsCount()];
		FONTS = fonts;
	}

	public static Font getDefaultFont()
	{
		return FONTS[FACE_SYSTEM >> 5][STYLE_PLAIN | SIZE_MEDIUM];
	}

	public static Font getFont(int fontSpecifier)
	{
		switch(fontSpecifier)
		{
		default:
			throw new IllegalArgumentException("Font.getFont: " +
					"недопустимое значение параметра fontSpecifier.");
		case FONT_STATIC_TEXT:
			return FONTS[FACE_SYSTEM >> 5][STYLE_PLAIN | SIZE_MEDIUM];
		case FONT_INPUT_TEXT:
			return FONTS[FACE_SYSTEM >> 5][STYLE_PLAIN | SIZE_SMALL];
		}
	}

	public static Font getFont(int face, int style, int size)
	{
		if(face != FACE_MONOSPACE && face != FACE_PROPORTIONAL && face != FACE_SYSTEM)
		{
			throw new IllegalArgumentException("Font.getFont: " +
					"недопустимое значение параметра face.");
		}
		if(style < 0 || style >= 8)
		{
			throw new IllegalArgumentException("Font.getFont: " +
					"недопустимое значение параметра style.");
		}
		if(size != SIZE_LARGE && size != SIZE_MEDIUM && size != SIZE_SMALL)
		{
			throw new IllegalArgumentException("Font.getFont: " +
					"недопустимое значение параметра size.");
		}
		return FONTS[face >> 5][style | size];
	}

	public static Font getRasterFont(int rasterFontIndex)
	{
		int i;
		int j;
		Font[] af;
		Font f;
		Font result;
		RasterFont font;
		if(rasterFontIndex < 0 || rasterFontIndex >= RASTER_FONTS.length)
		{
			throw new IndexOutOfBoundsException("Font.getRasterFont: " +
					"параметр rasterFontIndex выходит из диапазона.");
		}
		if((result = RASTER_FONTS[rasterFontIndex]) == null)
		{
			label0:
			{
				font = RasterFont.getRasterFontAtIndex(rasterFontIndex);
				for(i = FONTS.length; i-- > 0; )
				{
					for(j = (af = FONTS[i]).length; j-- > 0; )
					{
						if((f = af[j]).ref == font && (f.style & STYLE_UNDERLINED) == 0)
						{
							result = RASTER_FONTS[rasterFontIndex] = f;
							break label0;
						}
					}
				}
				result = RASTER_FONTS[rasterFontIndex] = new Font(font, 0, 0, 0);
			}
		}
		return result;
	}


	private int face;
	private int style;
	private int size;
	private RasterFont ref;

	private Font(RasterFont ref, int face, int style, int size)
	{
		this.face = face;
		this.style = style;
		this.size = size;
		this.ref = ref;
	}

	public boolean isPlain()
	{
		return style == STYLE_PLAIN;
	}

	public boolean isBold()
	{
		return (style & STYLE_BOLD) != 0;
	}

	public boolean isItalic()
	{
		return (style & STYLE_ITALIC) != 0;
	}

	public boolean isUnderlined()
	{
		return (style & STYLE_UNDERLINED) != 0;
	}

	public int getFace()
	{
		return face;
	}

	public int getStyle()
	{
		return style;
	}

	public int getSize()
	{
		return size;
	}

	public int getHeight()
	{
		return ref.getHeight();
	}

	public int getBaselinePosition()
	{
		return ref.getBaselinePosition();
	}

	public int charWidth(char src)
	{
		return ref.charWidth((int) src);
	}

	public int charsWidth(char[] src, int offset, int length)
	{
		int lim;
		int len;
		if(src == null)
		{
			throw new NullPointerException("Font.charsWidth: " +
					"параметр src равен нулевой ссылке.");
		}
		if((lim = offset + length) > (len = src.length) ||
				lim < offset || offset > len || offset < 0)
		{
			throw new ArrayIndexOutOfBoundsException("Font.charsWidth: " +
					"индекс выходит из диапазона.");
		}
		return ref.charsWidth(src, offset, length);
	}

	public int stringWidth(String src)
	{
		if(src == null)
		{
			throw new NullPointerException("Font.stringWidth: " +
					"параметр src равен нулевой ссылке.");
		}
		return ref.stringWidth(src);
	}

	public int substringWidth(String src, int offset, int length)
	{
		int lim;
		int len;
		if(src == null)
		{
			throw new NullPointerException("Font.substringWidth: " +
					"параметр src равен нулевой ссылке.");
		}
		if((lim = offset + length) > (len = src.length()) ||
				lim < offset || offset > len || offset < 0)
		{
			throw new StringIndexOutOfBoundsException("Font.substringWidth: " +
					"индекс выходит из диапазона.");
		}
		return ref.substringWidth(src, offset, length);
	}

	public RasterFont getReference()
	{
		return ref;
	}
}
