/* Search.c */

// File contains all routines for creating and handling the search window

#include <exec/types.h>
#include <clib/dos_protos.h>
#include <clib/exec_protos.h>
#include <clib/gadtools_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <intuition/gadgetclass.h>
#include <graphics/gfxmacros.h>
#include <graphics/GfxBase.h>
#include <intuition/intuition.h>
#include <intuition/IntuitionBase.h>
#include <libraries/gadtools.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

#include "CycleDBase.h"
#include "Search.h"

// Function creates gadgets in search window
struct Gadget *createSearchGadgets(struct Gadget **glistptr, void *searchvi,
    UWORD searchtopborder, struct Gadget *search_gads[], struct StringInfo *gad_ptr[])
{
struct NewGadget ng;
struct Gadget *gad;

STRPTR names[] =
{
    "Destination",
    "Date",
    NULL,
};

/* All the gadget creation calls accept a pointer to the previous gadget, and
** link the new gadget to that gadget's NextGadget field.  Also, they exit
** gracefully, returning NULL, if any previous gadget was NULL.  This limits
** the amount of checking for failure that is needed.  You only need to check
** before you tweak any gadget structure or use any of its fields, and finally
** once at the end, before you add the gadgets.
*/

/* The following operation is required of any program that uses GadTools.
** It gives the toolkit a place to stuff context data.
*/
gad = CreateContext(glistptr);

/* Since the NewGadget structure is unmodified by any of the CreateGadget()
** calls, we need only change those fields which are different.
*/

ng.ng_LeftEdge   = 180;
ng.ng_TopEdge    = 10+searchtopborder;
ng.ng_Width      = 150;
ng.ng_Height     = 12;
ng.ng_GadgetText = "_Enter Search String:";
ng.ng_TextAttr   = &Topaz80;
ng.ng_VisualInfo = searchvi;
ng.ng_GadgetID   = MYGAD_SEARCHSTRING;
ng.ng_Flags      = NG_HIGHLABEL;
search_gads[MYGAD_SEARCHSTRING] = gad = CreateGadget(STRING_KIND, gad, &ng,
                    GTST_String,   "",
                    GTST_MaxChars, 100,
                    GT_Underscore, '_',
                    TAG_END);
gad_ptr[2] = (struct StringInfo *) gad->SpecialInfo;

ng.ng_LeftEdge   = 450;
ng.ng_GadgetText = NULL;
ng.ng_GadgetID   = MYGAD_DESTDATE;
search_gads[MYGAD_DESTDATE] = gad = CreateGadget(MX_KIND, gad, &ng,
                    GTMX_Active, 0,
                    GTMX_Labels, names,
                    GTMX_Spacing, 4,
                    TAG_END);

return(gad);
}

/*
** Function to handle a GADGETUP or GADGETDOWN event.
*/
BOOL searchGadgetEvent(struct Screen *mysc, struct Window *searchwin, struct Gadget *gad, UWORD code,
    struct Gadget *search_gads[], struct StringInfo *gad_ptr[], BOOL &destdate)
{
long state = 0;

switch (gad->GadgetID)
    {
    case MYGAD_SEARCHSTRING:
        return(TRUE);
        break;
    case MYGAD_DESTDATE:
        GT_GetGadgetAttrs(search_gads[MYGAD_DESTDATE], searchwin, NULL, GTMX_Active, &state, TAG_END);
        if(state == 0)
            destdate = FALSE;
        else if(state == 1)
            destdate = TRUE;
        break;
    }
    return(FALSE);
}

/*
** Function to handle vanilla keys.
*/
void searchVanillaKey(struct Window *searchwin, UWORD code,
    struct Gadget *search_gads[])
{
switch (code)
    {
    case 'e':
    case 'E':
        ActivateGadget(search_gads[MYGAD_SEARCHSTRING], searchwin, NULL);
        break;
    }
}

// Function to deal with user input
void eventhandling(struct Screen *mysc, struct Window *searchwin,
    struct Gadget *search_gads[], struct StringInfo *gad_ptr[], BOOL &destdate)
{
    struct IntuiMessage *imsg;
    ULONG imsgClass;
    UWORD imsgCode;
    BOOL terminated = FALSE;
    struct Gadget *gad;

while (!terminated)
    {
    Wait (1 << searchwin->UserPort->mp_SigBit);

    /* GT_GetIMsg() returns an IntuiMessage with more friendly information for
    ** complex gadget classes.  Use it wherever you get IntuiMessages where
    ** using GadTools gadgets.
    */

    while ((!terminated) &&
           (imsg = GT_GetIMsg(searchwin->UserPort)))
        {
        /* Presuming a gadget, of course, but no harm...
        ** Only dereference this value (gad) where the Class specifies
        ** that it is a gadget event.
        */
        gad = (struct Gadget *)imsg->IAddress;

        imsgClass = imsg->Class;
        imsgCode = imsg->Code;

        /* Use the toolkit message-replying function here... */
        GT_ReplyIMsg(imsg);

        switch (imsgClass)
            {
            /*  --- WARNING --- WARNING --- WARNING --- WARNING --- WARNING ---
            ** GadTools puts the gadget address into IAddress of IDCMP_MOUSEMOVE
            ** messages.  This is NOT true for standard Intuition messages,
            ** but is an added feature of GadTools.
            */
            case IDCMP_VANILLAKEY:
                searchVanillaKey(searchwin, imsgCode, search_gads);
                break;

            case IDCMP_GADGETDOWN:
            case IDCMP_GADGETUP:
                terminated = searchGadgetEvent(mysc, searchwin, gad, imsgCode, search_gads,
                                gad_ptr, destdate);
                break;

            case IDCMP_CLOSEWINDOW:
                terminated = TRUE;
                break;

            case IDCMP_REFRESHWINDOW:
                /* With GadTools, the application must use GT_BeginRefresh()
                ** where it would normally have used BeginRefresh()
                */
                GT_BeginRefresh(searchwin);
                GT_EndRefresh(searchwin, TRUE);
                break;
            }
        }
    }
}

// Function to create and open search window
void
searchwindow(struct Screen *mysc, struct StringInfo *gad_ptr[], BOOL &destdate)
{
    struct Window   *searchwin;
    struct Gadget   *searchglist, *search_gads[NO_GADS];
    void            *searchvi;
    UWORD           searchtopborder;

if (NULL == (searchvi = GetVisualInfo(mysc, TAG_END)))
{
    EasyRequest(NULL, &novisinfo, NULL);
}
else
{
    /* Here is how we can figure out ahead of time how tall the  */
    /* window's title bar will be:                               */
    searchtopborder = mysc->WBorTop + (mysc->Font->ta_YSize + 1);

    if (NULL == createSearchGadgets(&searchglist, searchvi, searchtopborder,
                                         search_gads, gad_ptr))
    {
        EasyRequest(NULL, &nogadgets, NULL);
    }
    else
    {

        if (NULL == (searchwin = OpenWindowTags(NULL,
            WA_Title,     "Search",
            WA_Gadgets,   searchglist, WA_AutoAdjust,    TRUE,
            WA_Width,       490,       WA_MinWidth,      490,
            WA_InnerHeight, 50,        WA_MinHeight,     50,
            WA_DragBar,    TRUE,       WA_DepthGadget,   TRUE,
            WA_Activate,   TRUE,       WA_CloseGadget,   TRUE,
            WA_SimpleRefresh, TRUE,
            WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW |
                      IDCMP_VANILLAKEY | IDCMP_GADGETDOWN | STRINGIDCMP,
            WA_PubScreen, mysc,
            TAG_END)))
            {
                EasyRequest(NULL, &nowindow, NULL);
            }
            else
            {
                /* After window is open, gadgets must be refreshed with a
                ** call to the GadTools refresh window function.
                */
                GT_RefreshWindow(searchwin, NULL);

                // Deal with interaction
                eventhandling(mysc, searchwin, search_gads, gad_ptr, destdate);

                CloseWindow(searchwin);
            }
        }
        /* FreeGadgets() even if createAllGadgets() fails, as some
        ** of the gadgets may have been created...If glist is NULL
        ** then FreeGadgets() will do nothing.
        */
        FreeGadgets(searchglist);
        FreeVisualInfo(searchvi);
    }
}

