using System;

using sharpallegro5;

using ALLEGRO_DISPLAY = System.IntPtr;
using ALLEGRO_BITMAP = System.IntPtr;
using ALLEGRO_TIMER = System.IntPtr;
using ALLEGRO_EVENT_QUEUE = System.IntPtr;

public class ex_bitmap : AllegroExample
{
    static int Main(string[] argv)
    {
        string filename;
        ALLEGRO_DISPLAY display;
        ALLEGRO_BITMAP membitmap, bitmap;
        ALLEGRO_TIMER timer;
        ALLEGRO_EVENT_QUEUE queue;
        bool redraw = true;
        double zoom = 1;
        double t0;
        double t1;

        if (argv.Length > 1)
        {
            filename = argv[1];
        }
        else
        {
            filename = "data/mysha.pcx";
        }

        if (!al_init())
        {
            abort_example("Could not init Allegro.\n");
        }

        if (argv.Length > 2)
        {
            al_set_new_display_adapter(int.Parse(argv[2]));
        }

        al_install_mouse();
        al_install_keyboard();

        al_init_image_addon();

        display = al_create_display(640, 480);
        if (display == IntPtr.Zero)
        {
            abort_example("Error creating display\n");
        }

        al_set_window_title(display, filename);

        /* We load the bitmap into a memory bitmap, because creating a
         * display bitmap could fail if the bitmap is too big to fit into a
         * single texture.
         * FIXME: Or should A5 automatically created multiple display bitmaps?
         */
        al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
        t0 = al_get_time();
        membitmap = al_load_bitmap(filename);
        t1 = al_get_time();
        if (membitmap == IntPtr.Zero)
        {
            abort_example("{0} not found or failed to load\n", filename);
        }
        al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);

        Console.Write("Loading took {0:0.0000} seconds\n", t1 - t0);

        // FIXME: 
        // Now try to split the memory bitmap into display bitmaps?
        bitmap = al_clone_bitmap(membitmap);
        if (bitmap == IntPtr.Zero)
            bitmap = membitmap;

        timer = al_create_timer(1.0 / 30);
        queue = al_create_event_queue();
        al_register_event_source(queue, al_get_keyboard_event_source());
        al_register_event_source(queue, al_get_display_event_source(display));
        al_register_event_source(queue, al_get_timer_event_source(timer));
        al_start_timer(timer);

        while (true)
        {
            ALLEGRO_EVENT @event = new ALLEGRO_EVENT();
            al_wait_for_event(queue, ref @event);
            if (@event.type == ALLEGRO_EVENT_DISPLAY_ORIENTATION)
            {
                int o = @event.display.orientation;
                if (o == (int)ALLEGRO_DISPLAY_ORIENTATION.ALLEGRO_DISPLAY_ORIENTATION_0_DEGREES)
                {
                    Console.Write("0 degrees\n");
                }
                else if (o == (int)ALLEGRO_DISPLAY_ORIENTATION.ALLEGRO_DISPLAY_ORIENTATION_90_DEGREES)
                {
                    Console.Write("90 degrees\n");
                }
                else if (o == (int)ALLEGRO_DISPLAY_ORIENTATION.ALLEGRO_DISPLAY_ORIENTATION_180_DEGREES)
                {
                    Console.Write("180 degrees\n");
                }
                else if (o == (int)ALLEGRO_DISPLAY_ORIENTATION.ALLEGRO_DISPLAY_ORIENTATION_270_DEGREES)
                {
                    Console.Write("270 degrees\n");
                }
                else if (o == (int)ALLEGRO_DISPLAY_ORIENTATION.ALLEGRO_DISPLAY_ORIENTATION_FACE_UP)
                {
                    Console.Write("Face up\n");
                }
                else if (o == (int)ALLEGRO_DISPLAY_ORIENTATION.ALLEGRO_DISPLAY_ORIENTATION_FACE_DOWN)
                {
                    Console.Write("Face down\n");
                }
            }
            if (@event.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
                break;
            if (@event.type == ALLEGRO_EVENT_KEY_CHAR)
            {
                if (@event.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
                    break;
                if (@event.keyboard.unichar == '1')
                    zoom = 1;
                if (@event.keyboard.unichar == '+')
                    zoom *= 1.1;
                if (@event.keyboard.unichar == '-')
                    zoom /= 1.1;
                if (@event.keyboard.unichar == 'f')
                    zoom = (double)al_get_display_width(display) /
                        al_get_bitmap_width(bitmap);
            }
            if (@event.type == ALLEGRO_EVENT_TIMER)
                redraw = true;

            if (redraw && al_is_event_queue_empty(queue))
            {
                redraw = false;
                al_clear_to_color(al_map_rgb_f(0, 0, 0));
                if (zoom == 1)
                    al_draw_bitmap(bitmap, 0, 0, 0);
                else
                    al_draw_scaled_rotated_bitmap(
                        bitmap, 0, 0, 0, 0, (float)zoom, (float)zoom, 0, 0);
                al_flip_display();
            }
        }

        al_destroy_bitmap(bitmap);

        return 0;
    }
}