package ru.dbotthepony.kstarbound.client.freetype.struct;

import com.sun.jna.Pointer;
import com.sun.jna.Structure;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.nio.ByteBuffer;

/**************************************************************************
 *
 * struct:
 *   FT_Bitmap
 *
 * description:
 *   A structure used to describe a bitmap or pixmap to the raster.  Note
 *   that we now manage pixmaps of various depths through the `pixel_mode`
 *   field.
 *
 * fields:
 *   rows ::
 *     The number of bitmap rows.
 *
 *   width ::
 *     The number of pixels in bitmap row.
 *
 *   pitch ::
 *     The pitch's absolute value is the number of bytes taken by one
 *     bitmap row, including padding.  However, the pitch is positive when
 *     the bitmap has a 'down' flow, and negative when it has an 'up' flow.
 *     In all cases, the pitch is an offset to add to a bitmap pointer in
 *     order to go down one row.
 *
 *     Note that 'padding' means the alignment of a bitmap to a byte
 *     border, and FreeType functions normally align to the smallest
 *     possible integer value.
 *
 *     For the B/W rasterizer, `pitch` is always an even number.
 *
 *     To change the pitch of a bitmap (say, to make it a multiple of 4),
 *     use @FT_Bitmap_Convert.  Alternatively, you might use callback
 *     functions to directly render to the application's surface; see the
 *     file `example2.cpp` in the tutorial for a demonstration.
 *
 *   buffer ::
 *     A typeless pointer to the bitmap buffer.  This value should be
 *     aligned on 32-bit boundaries in most cases.
 *
 *   num_grays ::
 *     This field is only used with @FT_PIXEL_MODE_GRAY; it gives the
 *     number of gray levels used in the bitmap.
 *
 *   pixel_mode ::
 *     The pixel mode, i.e., how pixel bits are stored.  See @FT_Pixel_Mode
 *     for possible values.
 *
 *   palette_mode ::
 *     This field is intended for paletted pixel modes; it indicates how
 *     the palette is stored.  Not used currently.
 *
 *   palette ::
 *     A typeless pointer to the bitmap palette; this field is intended for
 *     paletted pixel modes.  Not used currently.
 */
@Structure.FieldOrder({
	"rows",
	"width",
	"pitch",
	"buffer",
	"num_grays",
	"pixel_mode",
	"palette_mode",
	"palette",
})
public class FT_Bitmap extends Structure {
	/**
	 *  The number of bitmap rows.
	 */
	public int    rows;

	/**
	 * The number of pixels in bitmap row.
	 */
	public int    width;

	/**
	 *     The pitch's absolute value is the number of bytes taken by one
	 *     bitmap row, including padding.  However, the pitch is positive when
	 *     the bitmap has a 'down' flow, and negative when it has an 'up' flow.
	 *     In all cases, the pitch is an offset to add to a bitmap pointer in
	 *     order to go down one row.
	 *
	 *     Note that 'padding' means the alignment of a bitmap to a byte
	 *     border, and FreeType functions normally align to the smallest
	 *     possible integer value.
	 *
	 *     For the B/W rasterizer, `pitch` is always an even number.
	 *
	 *     To change the pitch of a bitmap (say, to make it a multiple of 4),
	 *     use @FT_Bitmap_Convert.  Alternatively, you might use callback
	 *     functions to directly render to the application's surface; see the
	 *     file `example2.cpp` in the tutorial for a demonstration.
	 */
	public int    pitch;

	/**
	 *     A typeless pointer to the bitmap buffer.  This value should be
	 *     aligned on 32-bit boundaries in most cases.
	 */
	@Nullable public Pointer  buffer;

	@Nullable
	public ByteBuffer getByteBuffer() {
		if (buffer == null)
			return null;

		long size = (long) width * rows;
		return buffer.getByteBuffer(0L, size);
	}

	public short  num_grays;

	/**
	 *     The pixel mode, i.e., how pixel bits are stored.  See FT_Pixel_Mode
	 *     for possible values.
	 */
	public byte   pixel_mode;

	@Nonnull
	public FT_Pixel_Mode pixelMode() {
		return FT_Pixel_Mode.values()[pixel_mode];
	}

	public byte   palette_mode;
	@Nullable public Pointer palette;
}
