/*
**    Name: ODBCLib.c
**
**    Date: Thu Jan 17 12:13:43 2002
**
*/

#include "ODBCLib.h"
#include "kernel.h"
#include "hourglass.h"
#include "wimp.h"
#include <string.h>

ODBCLibWindow odbcwindows[256];

int odbclibhourglass = 0;

int odbclibquit = 0;

int odbclibversion = 0;

int odbclibtask = 0;

/* Wait for free query slot */

int ODBCLibWait(ODBCLibState state)
    {
    _kernel_swi_regs regs;

    wimp_message message;

    if (odbclibquit != 0)
       {
       return 1;
       }

    if (state == ODBC_STATE_COMPLETE)
        {
        regs.r[0] = SQL_QueryStatusSet;
        regs.r[1] = ODBC_STATE_PENDING;

        _kernel_swi(SQL_QueryStatus,&regs,&regs);

        if (odbclibversion == 0)
            {
            regs.r[0] = SQL_DMTaskGet;

            _kernel_swi(SQL_DMTask,&regs,&regs);

            if (regs.r[2] < 100)
                {
                os_error error;

                wimp_error_box_flags flags;

                flags = wimp_ERROR_BOX_OK_ICON;

                error.errnum = 0;
                strcpy(error.errmess,"Incorrect ODBC version.");

                regs.r[0] = (int)&error;
                regs.r[1] = flags;
                regs.r[2] = (int)"ODBC";
                _kernel_swi(Wimp_ReportError,&regs,&regs);

                return 1;
                }
            else
                {
                odbclibversion = regs.r[2];
                odbclibtask = regs.r[1];
                }
            }

/* Send pending message */

        message.size     = 20;
        message.your_ref = 0;
        message.action   = message_SQL_PENDING;

        regs.r[0] = wimp_USER_MESSAGE;
        regs.r[2] = (int)odbclibtask;
        regs.r[1] = (int)&message;
        _kernel_swi(Wimp_SendMessage,&regs,&regs);
        }

    regs.r[1] = -1;

    while (regs.r[1] != state)
        {
        regs.r[0] = SQL_QueryStatusGet;

        _kernel_swi(SQL_QueryStatus,&regs,&regs);

        if (regs.r[1] == ODBC_STATE_NOSERVER)
            {
            regs.r[0] = (int)"<ODBC$Dir>.!Run";

            _kernel_swi(XWimp_StartTask,&regs,&regs);
            }

        if (regs.r[1] != state)
            {
            if (ODBCLibPoll(state) || odbclibquit)
                {
                return 1;
                }
            }
        }

    return 0;
    }

/* Wimp poll handler */

int ODBCLibPoll(ODBCLibState state)
    {
    wimp_block block;

    _kernel_swi_regs regs;

    regs.r[0] = wimp_MASK_LOSE |
                wimp_MASK_GAIN |
                wimp_MASK_RECORDED |
                wimp_MASK_ACKNOWLEDGE;

    if (state == ODBC_STATE_COMPLETE)
        {
//        regs.r[0] |= wimp_MASK_NULL;
        }

    regs.r[1] = (int)&block;

    _kernel_swi(Wimp_Poll,&regs,&regs);

    switch (regs.r[0])
        {
        case wimp_REDRAW_WINDOW_REQUEST:
            regs.r[1] = (int)&block;
            _kernel_swi(Wimp_RedrawWindow,&regs,&regs);

            while (regs.r[0] != 0)
                {
                regs.r[1] = (int)&block;
                _kernel_swi(Wimp_GetRectangle,&regs,&regs);
                }

            ODBCLibAddWindow((int)block.redraw.w,1);
            break;

        case wimp_USER_MESSAGE:
            if (block.message.action == message_QUIT)
                {
                odbclibquit = 1;
                }
            break;

        case wimp_POINTER_LEAVING_WINDOW:
            if (odbclibhourglass > 0)
                {
                _kernel_swi(XHourglass_Off,&regs,&regs);
                odbclibhourglass--;
                }
            break;

        case wimp_POINTER_ENTERING_WINDOW:
            _kernel_swi(XHourglass_On,&regs,&regs);
            odbclibhourglass++;
            break;

        case wimp_CLOSE_WINDOW_REQUEST:
        case wimp_MOUSE_CLICK:
        case wimp_KEY_PRESSED:
            break;
        }

    return 0;
    }

/* Set finished state */

int ODBCLibFinished(void)
    {
    _kernel_swi_regs regs;

    regs.r[0] = SQL_QueryStatusSet;
    regs.r[1] = ODBC_STATE_READY;

    _kernel_swi(SQL_QueryStatus,&regs,&regs);

    regs.r[0] = SQL_QueryStatusReplyGet;

    _kernel_swi(SQL_QueryStatus,&regs,&regs);

    return regs.r[1];
    }


/* Initialise */

int ODBCLibInitialise(void)
    {
    memset(odbcwindows,0,sizeof(odbcwindows));
    return 0;
    }


/* Add window */

int ODBCLibAddWindow(int w,int type)
    {
    int index;

    index = 0;

    while (index < 256)
        {
        if (odbcwindows[index].w == w)
            {
            break;
            }
        else if (odbcwindows[index].w == 0)
            {
            odbcwindows[index].w = w;
            odbcwindows[index].type = type;
            break;
            }
        index++;
        }
    return 0;
    }


/* Refresh all windows that need it */

int ODBCLibRefresh(void)
    {
    int index;

    wimp_window_info info;

    _kernel_swi_regs regs;

    while (odbclibhourglass > 0)
        {
        _kernel_swi(XHourglass_Off,&regs,&regs);
        odbclibhourglass--;
        }

    if (odbcwindows[0].w == 0)
        {
        return 0;
        }

    for (index = 0;index < 256;index++)
        {
        if (odbcwindows[index].w != 0)
            {
            info.w = (wimp_w)odbcwindows[index].w;
            regs.r[1] = ((int)&info) | 1;
            _kernel_swi(Wimp_GetWindowInfo,&regs,&regs);

            if (odbcwindows[index].type == 1)
                {

/* Redraw */

                regs.r[0] = odbcwindows[index].w;
                regs.r[1] = info.extent.x0;
                regs.r[2] = info.extent.y0;
                regs.r[3] = info.extent.x1;
                regs.r[4] = info.extent.y1;
                _kernel_swi(Wimp_ForceRedraw,&regs,&regs);
                }
            else if (odbcwindows[index].type == 2)
                {

/* Open */
                regs.r[1] = ((int)&info) | 1;
                _kernel_swi(Wimp_CloseWindow,&regs,&regs);

                regs.r[1] = ((int)&info) | 1;
                _kernel_swi(Wimp_OpenWindow,&regs,&regs);

                }

            odbcwindows[index].w = 0;
            }
        }

    return 0;
    }

/* Application poll loop */

int ODBCLibLoop(odbclib_loop *loopfunc)
    {
    ODBCLibInitialise();

    while (loopfunc() == 0 && odbclibquit == 0)
        {
        ODBCLibRefresh();
        }

    return 0;
    }
