using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

using sharpallegro5;

using ALLEGRO_DISPLAY = System.IntPtr;
using ALLEGRO_EVENT_QUEUE = System.IntPtr;
using ALLEGRO_TIMER = System.IntPtr;
using ALLEGRO_CONFIG = System.IntPtr;
using ALLEGRO_USTR = sharpallegro5.AllegroApi._al_tagbstring;
using System.IO;

namespace test_sharpallegro5
{
    class Program : Allegro
    {
        static void System()
        {
            Console.WriteLine("al_init: " + al_init());
            //al_install_system(int version, function atexit_ptr);
            //al_uninstall_system();
            Console.WriteLine("al_is_system_installed: " + al_is_system_installed());

            uint version = al_get_allegro_version();
            int major = (int)(version >> 24);
            int minor = (int)((version >> 16) & 255);
            int revision = (int)((version >> 8) & 255);
            int release = (int)(version & 255);

            IntPtr path = al_get_standard_path(ALLEGRO_EXENAME_PATH);
            if (path == IntPtr.Zero)
            {
                Console.WriteLine("al_get_standard_path: ERROR");
            }
            else
            {                
                //ALLEGRO_USTR filename = path.filename;
                //Console.WriteLine("al_get_standard_path(ALLEGRO_EXENAME_PATH): " + filename.data);

                //IntPtr pathPtr = AllegroApi.al_get_standard_path(ALLEGRO_EXENAME_PATH);
                //string test = AllegroApi.al_path_cstr(pathPtr, '/');
                //IntPtr path2 = al_create_path(@"C:\Windows");
                //string drive = al_get_path_drive(path2);
                //al_destroy_path(path2);
                //string cstr = al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP);
            }

            //public static extern ALLEGRO_SYSTEM al_get_system_driver();
            //[DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
            //public static extern ALLEGRO_CONFIG al_get_system_config();





            //[DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
            //public static extern void al_set_org_name(string org_name);
            //[DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
            //public static extern void al_set_app_name(string app_name);
            //[DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
            //public static extern string al_get_org_name();
            //[DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
            //public static extern string al_get_app_name();

            //[DllImport(allegroDllName, CallingConvention = CallingConvention.Cdecl)]
            //public static extern bool al_inhibit_screensaver(bool inhibit);
        }

        static void Utf8()
        {
            IntPtr ustr = al_ustr_new("ciao! come va oggi? Ma va là!!");
            ALLEGRO_USTR allegro_ustr = (ALLEGRO_USTR)Marshal.PtrToStructure(ustr, typeof(ALLEGRO_USTR));
            uint length = al_ustr_length(ustr);
            uint size = al_ustr_size(ustr);

            IntPtr empty_string = al_ustr_empty_string();
            string cstr = al_cstr(empty_string);
            cstr = al_cstr(ustr);

            IntPtr ustr_dup = al_ustr_dup(ustr);
            string cstr_dup = al_cstr_dup(ustr);
            //string cstr_auto = Marshal.PtrToStringUni(cstr_dup);

            al_ustr_free(ustr);


        }

        static void Main(string[] args)
        {
            //System();

            Utf8();

            Console.WriteLine("ALLEGRO_VERSION_STR: " + ALLEGRO_VERSION_STR);
            Console.WriteLine("ALLEGRO_DATE_STR: " + ALLEGRO_DATE_STR);
            Console.WriteLine("ALLEGRO_DATE: " + ALLEGRO_DATE);
            Console.WriteLine("ALLEGRO_VERSION_INT: " + ALLEGRO_VERSION_INT);

            Console.WriteLine("al_get_allegro_version(): " + al_get_allegro_version());

            Console.WriteLine("al_is_system_installed(): " + al_is_system_installed());

            al_set_org_name("elvenprogrammer");
            al_set_app_name("test_sharpallegro5");
            Console.WriteLine("al_get_org_name(): " + al_get_org_name());
            IntPtr path = al_create_path("C:/Windows");

            ALLEGRO_USTR drive = new ALLEGRO_USTR();
            drive = (ALLEGRO_USTR)Marshal.PtrToStructure(path, typeof(ALLEGRO_USTR));
            Console.WriteLine("al_get_standard_path(): " + al_get_standard_path(ALLEGRO_EXENAME_PATH));
            Console.WriteLine("al_get_app_name(): " + al_get_app_name());

            al_install_mouse();
            al_install_keyboard();

            ALLEGRO_DISPLAY display = al_create_display(640, 480);
            ALLEGRO_TIMER timer = al_create_timer(1.0 / 2);

            if (File.Exists("test.ini"))
            {
                ALLEGRO_CONFIG config = al_load_config_file("test.ini");
                al_get_config_value(config, "section", "test");
            }
            else
            {
                ALLEGRO_CONFIG config = al_create_config();
                al_add_config_section(config, "section");
                al_set_config_value(config, "section", "test", "test value!");
                al_save_config_file("test.ini", config);
            }


            bool exit = false;

            ALLEGRO_EVENT_QUEUE queue = al_create_event_queue();
            al_register_event_source(queue, al_get_keyboard_event_source());
            al_register_event_source(queue, al_get_mouse_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 (!exit)
            {
                ALLEGRO_EVENT e = new ALLEGRO_EVENT();

                if (al_get_next_event(queue, ref e))
                {
                    switch (e.type)
                    {
                        case ALLEGRO_EVENT_DISPLAY_CLOSE:
                            exit = true;
                            break;
                        case ALLEGRO_EVENT_MOUSE_BUTTON_DOWN:
                            Console.WriteLine("ALLEGRO_EVENT_MOUSE_BUTTON_DOWN");
                            break;
                        case ALLEGRO_EVENT_KEY_DOWN:
                            Console.WriteLine("ALLEGRO_EVENT_KEY_DOWN");
                            break;
                        case ALLEGRO_EVENT_TIMER:
                            Console.WriteLine("TIMER");
                            break;
                    }
                }

                al_flip_display();
            }
        }
    }
}
