/*
**    OBPP (ObtainBestPenPatch)
**
**        © 1996 by Timo C. Nentwig
**        All Rights Reserved !
**
**        Tcn@oxygen.in-berlin.de
**
*/

/// #include

#include "GST.h"
#include "Protos.h"

///
/// proto

static BOOL    OpenLibs     (VOID);
static VOID    CloseLibs    (VOID);

///

    // Settings

struct Settings   *Set;

    // Libraries

struct Library    *CxBase;
struct Library    *IconBase;
struct GfxBase    *GfxBase;
struct Library    *UtilityBase;

static const struct { STRPTR Name; ULONG Version; APTR *Library; } Table [] =
{

    "commodities.library", LIBRARY_MINIMUM, (APTR *) &CxBase,
    "dos.library",         LIBRARY_MINIMUM, (APTR *) &DOSBase,
    "icon.library",        LIBRARY_MINIMUM, (APTR *) &IconBase,
    "graphics.library",    LIBRARY_MINIMUM, (APTR *) &GfxBase,
    "utility.library",     LIBRARY_MINIMUM, (APTR *) &UtilityBase,

    NULL,

};

    // C:Version

const STRPTR    __ver = "$VER: " PRG_TITLE " " PRG_VERSION " " __AMIGADATE__;

/// main()

LONG
main (VOID)
{

    LONG    Result = RETURN_FAIL;

        // Open libraries

    if (OpenLibs())
    {

            // Alloc mem for settings struct

        if (Set = AllocStruct (Settings))
        {

                // Initialize settings

            InitSettings();

                // Evaluate ToolTypes

            EvalTTypes();

                // Evaluate Shell arguments

            EvalArgs();

                // Setup commodity

            if (SetupCx())
            {

                BOOL     Done = FALSE;
                ULONG    Signals;

                    // Install the patch

                if (InstallWedge())
                {

                    Result = RETURN_OK;

                    Signals = PortMask (CxPort);

                    do
                    {

                            // Got commodity signal

                        if (Signals & PortMask (CxPort))
                        {

                            CxMsg   *GMsg;

                            while (GMsg = (CxMsg *) GetMsg (CxPort))
                            {

                                if (HandleCx (GMsg))
                                {

                                    Done = TRUE;
                                    break;

                                }

                            }

                        }

                            // Got DOS signal: CTRL-C

                        if (Signals & SIGBREAKF_CTRL_C)
                        {

                            Done = TRUE;

                        }

                            // Wait for signals

                        if ( ! (Done))
                        {

                            Signals = Wait (SIGBREAKF_CTRL_C | PortMask (CxPort));

                        }

                    }
                    while ( ! (Done));


                        // Remove the patch

                    RemoveWedge();

                }
                else
                {

                    FPrintf (Output(), "Failed to install patch !\n");

                }

            }

                // Quit program

            QuitCx();

                // Free settings structure

            FreeStruct (Set);

        }
        else
        {

            FPrintf (Output(), "Out of memory !\n");

        }

        CloseLibs();

    }

    return (Result);

}

///
/// OpenLibs ()

    /*
     *    FUNCTION    Open a required libraries.
     *
     *    NOTE        <Table> is defined above.
     *
     *    EXAMPLE     OpenLibs ();
     *
     */


static BOOL
OpenLibs (VOID)
{

    LONG    i;

        // Open libraries

    for (i = 0; Table [i] . Name; i ++)
    {

            // Failed to open a library

        if ( ! (*Table [i] . Library = OpenLibrary (Table [i] . Name, Table [i] . Version)))
        {

            FPrintf (Output(), PRG_TITLE ": Failed to open \"%s\" v%ld+ !\n", Table [i] . Name, Table [i] . Version);
            return (FALSE);

        }

    }

    return (TRUE);

}

///
/// CloseLibs ()

    /*
     *    FUNCTION    Close all opened libraries.
     *
     *    NOTE        <Table> is defined above.
     *
     *    EXAMPLE     CloseLibs ();
     *
     */


static VOID
CloseLibs (VOID)
{

    LONG    i;

        // Close libraries

    for (i = 0; Table [i] . Library; i ++)
    {

        CloseLib (*Table [i] . Library);

    }

}

///
