/*
        libGUI dinamic library SDK
        load library and link function
 */

#include "libGUI-devel.h"

#pragma pack(push,1)
struct IMPORT
{
        char *name;
        void *function;
};
#pragma pack(pop)

typedef struct IMPORT import_t;

static char *sys_libGUI_path="/sys/lib/libGUI.obj";

static char* funcnames[] = {"LibGUIversion","InitLibGUI","LibGUImain","QuitLibGUI",

                                "CreateWindow","SetWindowSizeRequest",

                                "PackControls","DestroyControl","SetControlSizeRequest","GetControlSizeX",
                                "GetControlSizeY","SetControlNewPosition","GetControlPositionX",
                                "GetControlPositionY","SetFocuse","RedrawControl","SpecialRedrawControl",

                                "SetCallbackFunction","BlockCallbackFunction","UnblockCallbackFunction",

                                "SetIDL_Function","DestroyIDL_Function",

                                "SetTimerCallbackForFunction","DestroyTimerCallbackForFunction",

                                "SetCallbackFunctionForEvent","DestroyCallbackFunctionForEvent",

                                "CreateButton","CreateButtonWithText",

                                "CreateProgressBar","SetProgressBarPulse","ProgressBarSetText","ProgressBarGetText",

                                "CreateHorizontalScrollBar","CreateVerticalScrollBar",

                                "CreateScrolledWindow","ScrolledWindowPackControls",

                                "CreateImage",

                                "CreateText","TextBackgroundOn","TextBackgroundOff",

                                "LoadFont","FreeFont"};


static inline void* gui_ksys_load_dll(char *path)
{
        void    *dll_export;

        __asm{
                        mov eax,68
                        mov ebx,19
                        mov ecx,path
                        int 0x40
                        mov dll_export,eax
                };

        return(dll_export);
}

static inline void gui_ksys_debug_out(int c)
{
        __asm{
                        mov eax,63
                        mov ebx,1
                        mov ecx,c
                        int 0x40
        };
}

static void gui_debug_out_str(char *s)
{

        while(*s)
        {
                if (*s=='\n') gui_ksys_debug_out(13);

                gui_ksys_debug_out(*s);
                s++;
        }
}

static int gui_strcmp(const char* string1, const char* string2)
{
        while (1)
        {
                if (*string1<*string2)
                        return -1;
                if (*string1>*string2)
                        return 1;
                if (*string1=='\0')
                        return 0;
                string1++;
                string2++;
        }
}

static void* gui_cofflib_getproc(import_t *lib, char *name)
{
        int i;

        for(i = 0; lib[i].name && gui_strcmp(name, lib[i].name); i++);

        if(lib[i].name) return lib[i].function;
                        else    return 0;
}

static inline void __declspec(noreturn) gui_ksys_exit(int value)
{
        __asm{
                        xor eax,eax
                        dec eax
                        mov ebx,value
                        int 0x40
        };
}

void link_libGUI(import_t *exp,char **imports)
{
        LibGUIversion=(DWORD (stdcall *)(void))
                        gui_cofflib_getproc(exp,imports[0]);
        InitLibGUI=(char (stdcall *)(void))
                        gui_cofflib_getproc(exp,imports[1]);
        LibGUImain=(void (stdcall *)(parent_t *WindowParent))
                        gui_cofflib_getproc(exp,imports[2]);
        QuitLibGUI=(void (stdcall *)(parent_t *window))
                        gui_cofflib_getproc(exp,imports[3]);
        CreateWindow=(parent_t* (stdcall *)(void))
                        gui_cofflib_getproc(exp,imports[4]);
        SetWindowSizeRequest=(void (stdcall *)(parent_t *WindowParent,int size_x,int size_y))
                        gui_cofflib_getproc(exp,imports[5]);
        PackControls=(void (stdcall *)(void *Parent,void *control))
                        gui_cofflib_getproc(exp,imports[6]);
        DestroyControl=(void (stdcall *)(void *control))
                        gui_cofflib_getproc(exp,imports[7]);
        SetControlSizeRequest=(void (stdcall *)(void *Control,int new_size_x,int new_size_y))
                        gui_cofflib_getproc(exp,imports[8]);
        GetControlSizeX=(int (stdcall *)(void *Control))
                        gui_cofflib_getproc(exp,imports[9]);
        GetControlSizeY=(int (stdcall *)(void *Control))
                        gui_cofflib_getproc(exp,imports[10]);
        SetControlNewPosition=(void (stdcall *)(void *Control,int new_x,int new_y))
                        gui_cofflib_getproc(exp,imports[11]);
        GetControlPositionX=(int (stdcall *)(void *Control))
                        gui_cofflib_getproc(exp,imports[12]);
        GetControlPositionY=(int (stdcall *)(void *Control))
                        gui_cofflib_getproc(exp,imports[13]);
        SetFocuse=(void* (stdcall *)(void *Control))
                        gui_cofflib_getproc(exp,imports[14]);
        RedrawControl=(void (stdcall *)(void *Control))
                        gui_cofflib_getproc(exp,imports[15]);
        SpecialRedrawControl=(void (stdcall *)(void *Control))
                        gui_cofflib_getproc(exp,imports[16]);
        SetCallbackFunction=(gui_callback_t* (stdcall *)(void *Control,
                                        int event_name,void *callback_func,void *callback_func_data))
                        gui_cofflib_getproc(exp,imports[17]);
        BlockCallbackFunction=(void (stdcall *)(void *Control,gui_callback_t *callback_ID))
                        gui_cofflib_getproc(exp,imports[18]);
        UnblockCallbackFunction=(void (stdcall *)(void *Control,gui_callback_t *callback_ID))
                        gui_cofflib_getproc(exp,imports[19]);
        SetIDL_Function=(void (stdcall *)(parent_t *Parent,void *function,void *function_data))
                        gui_cofflib_getproc(exp,imports[20]);
        DestroyIDL_Function=(void (stdcall *)(parent_t *Parent))
                        gui_cofflib_getproc(exp,imports[21]);
        SetTimerCallbackForFunction=(gui_timer_t* (stdcall *)(parent_t *parent_window,
                                        int time_tick,void *func,void *func_data))
                        gui_cofflib_getproc(exp,imports[22]);
        DestroyTimerCallbackForFunction=(void (stdcall *)(gui_timer_t *timer))
                        gui_cofflib_getproc(exp,imports[23]);
        SetCallbackFunctionForEvent=(gui_callbackevent_t* (stdcall *)(parent_t *parent_window,
                                        int event_type,void *func,void *func_data))
                        gui_cofflib_getproc(exp,imports[24]);
        DestroyCallbackFunctionForEvent=(void (stdcall *)(gui_callbackevent_t *callback_event))
                        gui_cofflib_getproc(exp,imports[25]);
        CreateButton=(gui_button_t* (stdcall *)(gui_button_data_t *info_for_control))
                        gui_cofflib_getproc(exp,imports[26]);
        CreateButtonWithText=(gui_button_t* (stdcall *)(gui_button_data_t *info,char *txt))
                        gui_cofflib_getproc(exp,imports[27]);
        CreateProgressBar=(gui_progress_bar_t* (stdcall *)(gui_progress_bar_data_t *info_for_control))
                        gui_cofflib_getproc(exp,imports[28]);
        SetProgressBarPulse=(void (stdcall *)(gui_progress_bar_t *ProgressBar,int time_update))
                        gui_cofflib_getproc(exp,imports[29]);
        ProgressBarSetText=(void (stdcall *)(gui_progress_bar_t *pbar,char *txt))
                        gui_cofflib_getproc(exp,imports[30]);
        ProgressBarGetText=(char* (stdcall *)(gui_progress_bar_t *pbar))
                        gui_cofflib_getproc(exp,imports[31]);
        CreateHorizontalScrollBar=(gui_scroll_bar_t* (stdcall *)(gui_scroll_bar_data_t *info_for_control))
                        gui_cofflib_getproc(exp,imports[32]);
        CreateVerticalScrollBar=(gui_scroll_bar_t* (stdcall *)(gui_scroll_bar_data_t *info_for_control))
                        gui_cofflib_getproc(exp,imports[33]);
        CreateScrolledWindow=(gui_scrolled_window_t* (stdcall *)(gui_scrolled_window_data_t *info_for_control))
                        gui_cofflib_getproc(exp,imports[34]);
        ScrolledWindowPackControls=(void (stdcall *)(gui_scrolled_window_t *parent,void *Control))
                        gui_cofflib_getproc(exp,imports[35]);
        CreateImage=(gui_image_t* (stdcall *)(gui_image_data_t *info_for_control))
                        gui_cofflib_getproc(exp,imports[36]);
        CreateText=(gui_text_t* (stdcall *)(gui_text_data_t *info_for_control))
                        gui_cofflib_getproc(exp,imports[37]);
        TextBackgroundOn=(void (stdcall *)(gui_text_t *Text))
                        gui_cofflib_getproc(exp,imports[38]);
        TextBackgroundOff=(void (stdcall *)(gui_text_t *Text))
                        gui_cofflib_getproc(exp,imports[39]);
        LoadFont=(font_t* (stdcall *)(char *fullfontname))
                        gui_cofflib_getproc(exp,imports[40]);
        FreeFont=(void (stdcall *)(font_t *font))
                        gui_cofflib_getproc(exp,imports[41]);
}

void    LoadLibGUI(char *lib_path)
{
        import_t        *exp;
        char            *path;
        DWORD           vers;

        if (lib_path==0)
        {
                path=sys_libGUI_path;
                exp=(import_t*)gui_ksys_load_dll(path);
        }
        else
        {
                path=lib_path;
                exp=(import_t*)gui_ksys_load_dll(path);
        }

        if (exp==0)
        {
                gui_debug_out_str("\ncan't load lib=");
                gui_debug_out_str(path);
                gui_ksys_exit(0);
        }
        else
        {
                link_libGUI(exp,funcnames);
                if (InitLibGUI())
                {
                        gui_debug_out_str("\ncan't initialize libGUI");
                        gui_ksys_exit(0);
                }
        }
}




