using System;
using System.Runtime.InteropServices;

using ALLEGRO_BITMAP = System.IntPtr;
using uchar = System.Byte;

namespace sharpallegro5
{
    /* bitmap.h */
    public partial class AllegroApi
    {
        /* Type: ALLEGRO_BITMAP
         */
        //struct ALLEGRO_BITMAP ALLEGRO_BITMAP;


        /* Enum: ALLEGRO_PIXEL_FORMAT
         */
        //enum ALLEGRO_PIXEL_FORMAT
        //{
        public const int ALLEGRO_PIXEL_FORMAT_ANY = 0;
        public const int ALLEGRO_PIXEL_FORMAT_ANY_NO_ALPHA = 1;
        public const int ALLEGRO_PIXEL_FORMAT_ANY_WITH_ALPHA = 2;
        public const int ALLEGRO_PIXEL_FORMAT_ANY_15_NO_ALPHA = 3;
        public const int ALLEGRO_PIXEL_FORMAT_ANY_16_NO_ALPHA = 4;
        public const int ALLEGRO_PIXEL_FORMAT_ANY_16_WITH_ALPHA = 5;
        public const int ALLEGRO_PIXEL_FORMAT_ANY_24_NO_ALPHA = 6;
        public const int ALLEGRO_PIXEL_FORMAT_ANY_32_NO_ALPHA = 7;
        public const int ALLEGRO_PIXEL_FORMAT_ANY_32_WITH_ALPHA = 8;
        public const int ALLEGRO_PIXEL_FORMAT_ARGB_8888 = 9;
        public const int ALLEGRO_PIXEL_FORMAT_RGBA_8888 = 10;
        public const int ALLEGRO_PIXEL_FORMAT_ARGB_4444 = 11;
        public const int ALLEGRO_PIXEL_FORMAT_RGB_888 = 12;	/* 24 bit format */
        public const int ALLEGRO_PIXEL_FORMAT_RGB_565 = 13;
        public const int ALLEGRO_PIXEL_FORMAT_RGB_555 = 14;
        public const int ALLEGRO_PIXEL_FORMAT_RGBA_5551 = 15;
        public const int ALLEGRO_PIXEL_FORMAT_ARGB_1555 = 16;
        public const int ALLEGRO_PIXEL_FORMAT_ABGR_8888 = 17;
        public const int ALLEGRO_PIXEL_FORMAT_XBGR_8888 = 18;
        public const int ALLEGRO_PIXEL_FORMAT_BGR_888 = 19;	/* 24 bit format */
        public const int ALLEGRO_PIXEL_FORMAT_BGR_565 = 20;
        public const int ALLEGRO_PIXEL_FORMAT_BGR_555 = 21;
        public const int ALLEGRO_PIXEL_FORMAT_RGBX_8888 = 22;
        public const int ALLEGRO_PIXEL_FORMAT_XRGB_8888 = 23;
        public const int ALLEGRO_PIXEL_FORMAT_ABGR_F32 = 24;
        public const int ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE = 25;
        public const int ALLEGRO_PIXEL_FORMAT_RGBA_4444 = 26;
        public const int ALLEGRO_NUM_PIXEL_FORMATS = 27;
        //};


        /*
         * Bitmap flags
         */
        public const int ALLEGRO_MEMORY_BITMAP = 0x0001;
        public const int ALLEGRO_KEEP_BITMAP_FORMAT = 0x0002;
        public const int ALLEGRO_FORCE_LOCKING = 0x0004;
        public const int ALLEGRO_NO_PRESERVE_TEXTURE = 0x0008;
        public const int ALLEGRO_ALPHA_TEST = 0x0010;
        public const int _ALLEGRO_INTERNAL_OPENGL = 0x0020;
        public const int ALLEGRO_MIN_LINEAR = 0x0040;
        public const int ALLEGRO_MAG_LINEAR = 0x0080;
        public const int ALLEGRO_MIPMAP = 0x0100;
        public const int ALLEGRO_NO_PREMULTIPLIED_ALPHA = 0x0200;
        public const int ALLEGRO_VIDEO_BITMAP = 0x0400;


        /* Flags for the blitting functions */
        public const int ALLEGRO_FLIP_HORIZONTAL = 0x00001;
        public const int ALLEGRO_FLIP_VERTICAL = 0x00002;


        /*
         * Locking flags
         */
        public const int ALLEGRO_LOCK_READWRITE = 0;
        public const int ALLEGRO_LOCK_READONLY = 1;
        public const int ALLEGRO_LOCK_WRITEONLY = 2;


        /*
         * Blending modes
         */
        //enum ALLEGRO_BLEND_MODE
        //{
        public const int ALLEGRO_ZERO = 0;
        public const int ALLEGRO_ONE = 1;
        public const int ALLEGRO_ALPHA = 2;
        public const int ALLEGRO_INVERSE_ALPHA = 3;
        //};

        //enum ALLEGRO_BLEND_OPERATIONS
        //{
        public const int ALLEGRO_ADD = 0;
        public const int ALLEGRO_SRC_MINUS_DEST = 1;
        public const int ALLEGRO_DEST_MINUS_SRC = 2;
        public const int ALLEGRO_NUM_BLEND_OPERATIONS = 3;
        //};


        /* Type: ALLEGRO_LOCKED_REGION
         */
        [StructLayout(LayoutKind.Sequential)]
        public struct ALLEGRO_LOCKED_REGION
        {
            public IntPtr data;
            public int format;
            public int pitch;
            public int pixel_size;
        }

        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_set_new_bitmap_format(int format);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_set_new_bitmap_flags(int flags);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_get_new_bitmap_format();
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_get_new_bitmap_flags();
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_add_new_bitmap_flag(int flag);

        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_get_bitmap_width(ALLEGRO_BITMAP bitmap);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_get_bitmap_height(ALLEGRO_BITMAP bitmap);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_get_bitmap_format(ALLEGRO_BITMAP bitmap);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_get_bitmap_flags(ALLEGRO_BITMAP bitmap);

        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern ALLEGRO_BITMAP al_create_bitmap(int w, int h);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_destroy_bitmap(ALLEGRO_BITMAP bitmap);

        /* Blitting */
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_draw_bitmap(ALLEGRO_BITMAP bitmap, float dx, float dy, int flags);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_draw_bitmap_region(ALLEGRO_BITMAP bitmap, float sx, float sy, float sw, float sh, float dx, float dy, int flags);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_draw_scaled_bitmap(ALLEGRO_BITMAP bitmap, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, int flags);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_draw_rotated_bitmap(ALLEGRO_BITMAP bitmap, float cx, float cy, float dx, float dy, float angle, int flags);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_draw_scaled_rotated_bitmap(ALLEGRO_BITMAP bitmap, float cx, float cy, float dx, float dy, float xscale, float yscale, float angle, int flags);

        /* Tinted blitting */
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_draw_tinted_bitmap(ALLEGRO_BITMAP bitmap, ALLEGRO_COLOR tint, float dx, float dy, int flags);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_draw_tinted_bitmap_region(ALLEGRO_BITMAP bitmap, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, float dx, float dy, int flags);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_draw_tinted_scaled_bitmap(ALLEGRO_BITMAP bitmap, ALLEGRO_COLOR tint, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, int flags);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_draw_tinted_rotated_bitmap(ALLEGRO_BITMAP bitmap, ALLEGRO_COLOR tint, float cx, float cy, float dx, float dy, float angle, int flags);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_draw_tinted_scaled_rotated_bitmap(ALLEGRO_BITMAP bitmap, ALLEGRO_COLOR tint, float cx, float cy, float dx, float dy, float xscale, float yscale, float angle, int flags);

        /* Locking */
        //ALLEGRO_LOCKED_REGION *al_lock_bitmap(ALLEGRO_BITMAP *bitmap, int format, int flags)
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern IntPtr al_lock_bitmap(IntPtr bitmap, int format, int flags);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern ALLEGRO_LOCKED_REGION al_lock_bitmap_region(ALLEGRO_BITMAP bitmap, int x, int y, int width, int height, int format, int flags);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_unlock_bitmap(IntPtr bitmap);

        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_put_pixel(int x, int y, ALLEGRO_COLOR color);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_put_blended_pixel(int x, int y, ALLEGRO_COLOR color);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern ALLEGRO_COLOR al_get_pixel(ALLEGRO_BITMAP bitmap, int x, int y);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_get_pixel_size(int format);

        /* Pixel mapping */
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern ALLEGRO_COLOR al_map_rgb(uchar r, uchar g, uchar b);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern ALLEGRO_COLOR al_map_rgba(uchar r, uchar g, uchar b, uchar a);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern ALLEGRO_COLOR al_map_rgb_f(float r, float g, float b);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern ALLEGRO_COLOR al_map_rgba_f(float r, float g, float b, float a);


        /* Pixel unmapping */
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_unmap_rgb(ALLEGRO_COLOR color, ref uchar r, ref uchar g, ref uchar b);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_unmap_rgba(ALLEGRO_COLOR color, ref uchar r, ref uchar g, ref uchar b, ref uchar a);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_unmap_rgb_f(ALLEGRO_COLOR color, ref float r, ref float g, ref float b);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_unmap_rgba_f(ALLEGRO_COLOR color, ref float r, ref float g, ref float b, ref float a);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern int al_get_pixel_format_bits(int format);


        /* Masking */
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_convert_mask_to_alpha(ALLEGRO_BITMAP bitmap, ALLEGRO_COLOR mask_color);

        /* Clipping */
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_set_clipping_rectangle(int x, int y, int width, int height);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_get_clipping_rectangle(ref int x, ref int y, ref int w, ref int h);

        /* Sub bitmaps */
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern ALLEGRO_BITMAP al_create_sub_bitmap(ALLEGRO_BITMAP parent, int x, int y, int w, int h);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_is_sub_bitmap(ALLEGRO_BITMAP bitmap);

        /* Miscellaneous */
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern ALLEGRO_BITMAP al_clone_bitmap(ALLEGRO_BITMAP bitmap);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern bool al_is_bitmap_locked(ALLEGRO_BITMAP bitmap);

        /* Blending */
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_set_blender(int op, int source, int dest);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_get_blender(ref int op, ref int source, ref int dest);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_set_separate_blender(int op, int source, int dest, int alpha_op, int alpha_source, int alpha_dest);
        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void al_get_separate_blender(ref int op, ref int source, ref int dest, ref int alpha_op, ref int alpha_src, ref int alpha_dest);

        [DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
        public static extern void _al_put_pixel(ALLEGRO_BITMAP bitmap, int x, int y, ALLEGRO_COLOR color);
    }
}
