using System;

using sharpallegro5;

using ALLEGRO_DISPLAY = System.IntPtr;

public class ex_drawpixels : AllegroExample
{
    public const int WIDTH = 640;
    public const int HEIGHT = 480;
    public const int NUM_STARS = 300;
    public const int TARGET_FPS = 9999;


    public struct Point
    {
        public float x, y;
    };


    static int Main()
    {
        ALLEGRO_DISPLAY display;
        ALLEGRO_KEYBOARD_STATE key_state = new ALLEGRO_KEYBOARD_STATE();
        Point[,] stars = new Point[3, NUM_STARS / 3];
        float[] speeds = { 0.0001f, 0.05f, 0.15f };
        ALLEGRO_COLOR[] colors = new ALLEGRO_COLOR[3];
        long start, now, elapsed, frame_count;
        int total_frames = 0;
        double program_start;
        double length;
        int layer, star;
        ALLEGRO_LOCKED_REGION lr;

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

        al_install_keyboard();

        display = al_create_display(WIDTH, HEIGHT);
        if (display == IntPtr.Zero)
        {
            abort_example("Could not create display.\n");
            return 1;
        }

        colors[0] = al_map_rgba(255, 100, 255, 128);
        colors[1] = al_map_rgba(255, 100, 100, 255);
        colors[2] = al_map_rgba(100, 100, 255, 255);

        for (layer = 0; layer < 3; layer++)
        {
            for (star = 0; star < NUM_STARS / 3; star++)
            {
                //Point p = stars[layer, star];
                //p.x = rand() % WIDTH;
                //p.y = rand() % HEIGHT;
                stars[layer, star].x = rand() % WIDTH;
                stars[layer, star].y = rand() % HEIGHT;
            }
        }


        start = (long)al_get_time() * 1000;
        now = start;
        elapsed = 0;
        frame_count = 0;
        program_start = al_get_time();


        while (true)
        {
            if (frame_count < (1000 / TARGET_FPS))
            {
                frame_count += elapsed;
            }
            else
            {
                int X, Y;

                frame_count -= (1000 / TARGET_FPS);
                al_clear_to_color(al_map_rgb(0, 0, 0));
                for (star = 0; star < NUM_STARS / 3; star++)
                {
                    Point p = stars[0, star];
                    al_draw_pixel(p.x, p.y, colors[0]);
                }
                //IntPtr ptr = al_get_backbuffer(display);
                //lr = al_lock_bitmap(al_get_backbuffer(display), ALLEGRO_PIXEL_FORMAT_ANY, 0);

                for (layer = 1; layer < 3; layer++)
                {
                    for (star = 0; star < NUM_STARS / 3; star++)
                    {
                        Point p = stars[layer, star];
                        // put_pixel ignores blending
                        al_put_pixel((int)p.x, (int)p.y, colors[layer]);
                    }
                }

                /* Check that dots appear at the window extremes. */
                X = WIDTH - 1;
                Y = HEIGHT - 1;
                al_put_pixel(0, 0, al_map_rgb_f(1, 1, 1));
                al_put_pixel(X, 0, al_map_rgb_f(1, 1, 1));
                al_put_pixel(0, Y, al_map_rgb_f(1, 1, 1));
                al_put_pixel(X, Y, al_map_rgb_f(1, 1, 1));

                al_unlock_bitmap(al_get_backbuffer(display));
                al_flip_display();
                total_frames++;
            }

            now = (long)al_get_time() * 1000;
            elapsed = now - start;
            start = now;

            for (layer = 0; layer < 3; layer++)
            {
                for (star = 0; star < NUM_STARS / 3; star++)
                {
                    //Point p = stars[layer, star];
                    //p.y -= speeds[layer] * elapsed;
                    //if (p.y < 0)
                    //{
                    //    p.x = rand() % WIDTH;
                    //    p.y = HEIGHT;
                    //}
                    stars[layer, star].y -= speeds[layer] * elapsed;
                    if (stars[layer, star].y < 0)
                    {
                        stars[layer, star].x = rand() % WIDTH;
                        stars[layer, star].y = HEIGHT;
                    }
                }
            }

            al_rest(0.001);

            al_get_keyboard_state(ref key_state);
            if (al_key_down(ref key_state, ALLEGRO_KEY_ESCAPE))
                break;
        }

        length = al_get_time() - program_start;

        if (length != 0)
        {
            Console.Write("{0} FPS\n", (int)(total_frames / length));
        }

        al_destroy_display(display);

        return 0;
    }
}