/* gui2.c 27/9/97 (c) R.Downer */

/// Includes
#include <stdlib.h>
#include <string.h>
#include <proto/intuition.h>
#include <proto/muimaster.h>
#include <libraries/mui.h>
#include "protos.h"
#include "a_gui.h"
#include "config.h"
#include "tagfile.h"
///
/// Prototypes
Prototype BOOL DoGUI (void);
Local void GUI_CleanUp (void);
Local void GUI_RefreshMsgView (void);
Local BOOL GUI_ChangePart (int part);
Local BOOL GUI_Part_Select (struct TagFile **clonetf, int part);
Local void GUI_RefreshTaglineView (struct TagFile *tf);
Local void GUI_RefreshPreview (struct TagFile *tf);
///

struct ObjApp *objApp = NULL;

/// DoGUI
/* ----------------------------------- DoGUI -----------------------------------

 Comment: GUI main routine

*/

BOOL DoGUI (void)
{
    BOOL running = TRUE, status = TRUE;

    atexit (GUI_CleanUp);

    objApp = CreateApp ();
    if (!objApp) {
        AlertUser ("Couldn't open window (1)\nUsing random selections", "_OK");
        return TRUE;
    }

    GUI_RefreshMsgView ();
    set(objApp->WI_MainWindow,MUIA_Window_Open,TRUE);

    while (running)
    {
        ULONG signal = 0, rid;

        switch (rid = DoMethod(objApp->App, MUIM_Application_Input, &signal))
        {
            case ID_CANCEL:
            case MUIV_Application_ReturnID_Quit:
                status = FALSE;
            case ID_OK:
                running = FALSE;
                break;

            case ID_CHMOOD:
            case ID_CHHEADER:
            case ID_CHNP:
            case ID_CHSIG:
            case ID_CHTAG:
                if (GUI_ChangePart (rid-1)) GUI_RefreshMsgView ();
                break;

            case ID_EDITMSG:
                DoEdit ();
                GUI_RefreshMsgView ();
                break;
        }
        if (running && signal) {
            signal = Wait(signal|SIGBREAKF_CTRL_F);
            if (signal&SIGBREAKF_CTRL_F) status = running = FALSE;
        }
    }

    return status;
}
///
/// GUI_CleanUp
/* -------------------------------- GUI_CleanUp --------------------------------

 Comment: atexit() function for GUI

*/

void GUI_CleanUp (void)
{
    if (objApp) {
        DisposeApp (objApp);
        objApp = NULL;
    }
}
///
/// GUI_RefreshMsgView
/* ---------------------------- GUI_RefreshMsgView -----------------------------

 Comment: Update the message listview

*/

void GUI_RefreshMsgView (void)
{
    char *buf1, *buf2, *linebuf, **linearray;
    int linecount = 0, p = 0, size;

    set(objApp->App, MUIA_Application_Sleep, TRUE);

    buf1 = buf2 = GenerateMessage ();
    if (buf1) {
        while (ReadLineFromMemory (&buf2))
            linecount++;

        if (linecount) {
            size = linecount * sizeof (char *);
            linearray = malloc (size);
            if (linearray) {
                buf2 = buf1;
                while (p < linecount) {
                    linebuf = ReadLineFromMemory (&buf2);
                    linearray[p++] = strdup (linebuf);
                }
                set (objApp->LV_Message, MUIA_List_Quiet, TRUE);
                DoMethod (objApp->LV_Message, MUIM_List_Clear);
                DoMethod (objApp->LV_Message, MUIM_List_Insert, linearray, linecount, MUIV_List_Insert_Bottom);
                set (objApp->LV_Message, MUIA_List_Quiet, FALSE);
                for (p = 0; p < linecount; p++)
                    free (linearray[p]);
                free (linearray);
            }
        }
        free (buf1);
    }


    set(objApp->App, MUIA_Application_Sleep, FALSE);
    return;
}
///

/// GUI_ChangePart
/* ----------------------------------- GUI_ChangePart -----------------------------------

 Comment: Change a part

*/

BOOL GUI_ChangePart (int part)
{
    BOOL running = TRUE, status = TRUE;
    ULONG cursor, dblclick;
    struct TagFile *clonetf;
    ULONG signal = 0, rid;
    char *newFile;

    if (TagFile[part]) {
        clonetf = tagfile_clone (TagFile[part]);
        if(!clonetf) {
            AlertF("Insufficient memory");
            return;
        }
    } else {
        clonetf = tagfile_openfile (NULL, Config.Part[part].File);
        if(!clonetf) {
            AlertUser("Couldn't open file\n%s", "_OK", Config.Part[part].File);
            return;
        }
    }

    tagfile_bufferfile(clonetf);
    GUI_RefreshTaglineView (clonetf);
    set(objApp->STR_PA_Tagfile, MUIA_String_Contents, clonetf->Filename);
    set(objApp->WI_TagWindow,MUIA_Window_Open,TRUE);

    while (running)
    {
        rid = DoMethod(objApp->App, MUIM_Application_Input, &signal);
        switch (rid)
        {
            case ID_CANCEL:
            case MUIV_Application_ReturnID_Quit:
                status = FALSE;
                running = FALSE;
                tagfile_closeall (clonetf);
                break;

            case ID_OK:
                running = GUI_Part_Select (&clonetf, part);
                break;

            case ID_NONE:
                tagfile_closeall (TagFile[part]);
                tagfile_closeall (clonetf);
                TagFile[part] = NULL;
                running = FALSE;
                break;

            case ID_LISTVIEW:
                get (objApp->LV_Taglist, MUIA_List_Active, &cursor);
                if (cursor != MUIV_List_Active_Off) {
                    tagfile_goto (clonetf, cursor);
                    GUI_RefreshPreview (clonetf);
                }
                /*****/get (objApp->LV_Taglist, MUIA_Listview_DoubleClick, &dblclick);
                if (dblclick)
                    running = GUI_Part_Select (&clonetf, part);
                break;

            case ID_BACK:
                if (clonetf->Previous) {
                    clonetf = tagfile_closefile (clonetf);
                    GUI_RefreshTaglineView (clonetf);
                } else {
                    DisplayBeep (0L);
                }
                break;

            case ID_RANDOM:
                tagfile_random (clonetf);
                set (objApp->LV_Taglist, MUIA_List_Active, tagfile_ordinal (clonetf));
                GUI_RefreshPreview (clonetf);
                break;

            case ID_LOAD:
                get(objApp->STR_PA_Tagfile, MUIA_String_Contents, &newFile);
                clonetf = tagfile_openfile(clonetf, newFile);
                GUI_RefreshTaglineView(clonetf);
                break;
        }
        if (running && signal) {
            signal = Wait(signal|SIGBREAKF_CTRL_F);
            if (signal&SIGBREAKF_CTRL_F) status = running = FALSE;
        }
    }

    return status;
}
///
/// GUI_Part_Select
/* ------------------------------ GUI_Part_Select ------------------------------

 Comment: Actions taken when doubleclicking a tagline

*/

BOOL GUI_Part_Select (struct TagFile **clonetf, int part)
{
    char *buf, *file, *buf2;
    BOOL running = TRUE;
    struct TagFile *newtf;

    set(objApp->App, MUIA_Application_Sleep, TRUE);

    buf = tagfile_get (*clonetf);
    if (strncmp (buf, "[ALTLIST]", 9) == 0) {
        buf2 = &buf[9];
        file = ReadLineFromMemory (&buf2);
        if (file) {
            newtf = tagfile_openfile (*clonetf, file);
            if (!newtf) {
                AlertUser ("Couldn't open %s\nCheck that the name is correct and\n"
                           "that there is sufficient memory.", "_OK");
            } else {
                *clonetf = newtf;
                GUI_RefreshTaglineView (*clonetf);
            }
        } else {
            AlertUser ("Couldn't get filename.\nCheck that the line in the tagfile\n"
                       "is correct.", "_OK");
        }
    } else if (strncmp (buf, "[COMMENT]", 9) == 0) {
        /* Comment, so we do nothing */
    } else {
        tagfile_closeall (TagFile[part]);
        TagFile[part] = *clonetf;
        set(objApp->WI_TagWindow, MUIA_Window_Open, FALSE);
        running = FALSE;
    }

    set(objApp->App, MUIA_Application_Sleep, FALSE);

    return running;
}
///
/// GUI_RefreshTaglineView
/* ---------------------------- GUI_RefreshTaglineView -----------------------------

 Comment: Update the tagline listview

*/

void GUI_RefreshTaglineView (struct TagFile *tf)
{
    char *buf1, *buf2, *linebuf;
    int save;

    set(objApp->App, MUIA_Application_Sleep, TRUE);

    save = tagfile_ordinal (tf);
    tagfile_goto (tf, 0);

    set (objApp->LV_Taglist, MUIA_List_Quiet, TRUE);
    DoMethod (objApp->LV_Taglist, MUIM_List_Clear);
    while (!tagfile_eof (tf)) {
        buf1 = buf2 = tagfile_get (tf);
        if (buf1 != NULL && buf1 != (char *)(-1L)) {
            if (linebuf = ReadLineFromMemory (&buf2))
                DoMethod (objApp->LV_Taglist, MUIM_List_InsertSingle, linebuf, MUIV_List_Insert_Bottom);
            free (buf1);
        }
        tagfile_next (tf);
    }

    set (objApp->LV_Taglist, MUIA_List_Active, save);
    set (objApp->LV_Taglist, MUIA_List_Quiet, FALSE);

    tagfile_goto (tf, save);
    GUI_RefreshPreview (tf);
    set(objApp->App, MUIA_Application_Sleep, FALSE);
    return;
}
///
/// GUI_RefreshPreview
/* ---------------------------- GUI_RefreshTaglineView -----------------------------

 Comment: Update the preview listview

*/

void GUI_RefreshPreview (struct TagFile *tf)
{
    char *buf1, *buf2, *linebuf;

    set(objApp->App, MUIA_Application_Sleep, TRUE);

    DoMethod (objApp->LV_Preview, MUIM_List_Clear);
    buf1 = buf2 = ExpandMacros (tagfile_get (tf));
    if (buf1 != NULL && buf1 != (void *)(-1)) {
        while (linebuf = ReadLineFromMemory (&buf2))
            DoMethod (objApp->LV_Preview, MUIM_List_InsertSingle, linebuf, MUIV_List_Insert_Bottom);
        free (buf1);
    }

    set(objApp->App, MUIA_Application_Sleep, FALSE);
    return;
}
///

