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

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

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

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

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


package malik.emulator.media.graphics;

public final class GraphicBuffer extends Object
{
	private int offset;
	private int scanlength;
	private int width;
	private int height;
	private int[] pixels;

	public GraphicBuffer(int[] pixels, int offset, int scanlength, int width, int height)
	{
		int lim;
		int len;
		int length = width + (height - 1) * scanlength;
		if(pixels == null)
		{
			throw new NullPointerException("GraphicBuffer: " +
					"параметр pixels равен нулевой ссылке.");
		}
		if(width <= 0 || height <= 0)
		{
			throw new IllegalArgumentException("GraphicBuffer: " +
					"размеры графического буфера могут быть только положительными.");
		}
		if(scanlength < width)
		{
			throw new IllegalArgumentException("GraphicBuffer: " +
					"длина линии сканирования не может быть меньше ширины.");
		}
		if((lim = offset + length) > (len = pixels.length) ||
				lim < offset || offset > len || offset < 0)
		{
			throw new ArrayIndexOutOfBoundsException("GraphicBuffer: " +
					"индекс выходит из диапазона.");
		}
		this.offset = offset;
		this.scanlength = scanlength;
		this.width = width;
		this.height = height;
		this.pixels = pixels;
	}

	public boolean equals(Object ref)
	{
		GraphicBuffer g;
		return ref == this || ref instanceof GraphicBuffer &&
				getBase() == (g = (GraphicBuffer) ref).getBase() &&
				scanlength == g.scanlength && width == g.width && height == g.height;
	}

	public int hashCode()
	{
		return getBase() ^ scanlength ^ width ^ (height << 16);
	}

	public String toString()
	{
		return "Графический буфер[база=0x" + Integer.toHexString(getBase()) +
				", длина линии сканирования=" + scanlength +
				", ширина=" + width + ", высота=" + height + "]";
	}

	public void setPixel(int x, int y, int colorARGB)
	{
		if(x >= 0 && x < width && y >= 0 && y < height)
		{
			pixels[offset + x + y * scanlength] = colorARGB;
		}
	}

	public int getPixel(int x, int y)
	{
		return x >= 0 && x < width && y >= 0 && y < height ?
				pixels[offset + x + y * scanlength] : 0;
	}

	public int getBase()
	{
		return Array.getFirstElementAddress(pixels) + (offset << 2);
	}

	public int getSizes()
	{
		return width | height << 16;
	}

	public int getOffset()
	{
		return offset;
	}

	public int getScanlength()
	{
		return scanlength;
	}

	public int getWidth()
	{
		return width;
	}

	public int getHeight()
	{
		return height;
	}

	public int[] getPixels()
	{
		return pixels;
	}
}
