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

/// #include

#include "cw_GST.h"

///
/// #define

#define EVT_KEY_CENTER  1L
#define EVT_KEY_PARENT  2L
#define EVT_KEY_ZIP     3L

#define PRG_VERSION     "2.7"
#define PRG_TITLE       "CenterWIN"
#define PRG_AUTHOR      "Timo C. Nentwig"
#define PRG_YEAR        "1996"

///
/// proto

static VOID    ProcessMsg      (VOID);
static BOOL    AttachFilter    (const STRPTR HotKey, const ULONG Event);
static BOOL    OpenLibs        (VOID);
static VOID    CloseLibs       (VOID);

///

    // C:Version

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

    // Globals

struct    IntuitionBase   *IntuitionBase;
struct    Library         *CxBase;
struct    MsgPort         *CxPort;
CxObj                     *Broker;
ULONG                      Cx_SignalFlag;
BOOL                       FullHeight;

    // Libraries

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

    "dos.library",         LIBRARY_MINIMUM, (APTR *) &DOSBase,
    "intuition.library",   LIBRARY_MINIMUM, (APTR *) &IntuitionBase,
    "commodities.library", LIBRARY_MINIMUM, (APTR *) &CxBase,

    NULL,

};

/// main ()

ULONG
main (LONG argc, STRPTR *argv)
{

    ULONG   Result = RETURN_FAIL;

    if (OpenLibs ())
    {

        if (CxPort = CreateMsgPort ())
        {

            STRPTR   *TTypes;
            struct
            {

                STRPTR    Center;
                STRPTR    Parent;
                STRPTR    Zip;

            } Key;
            struct    NewBroker    NBroker =
            {

                NB_VERSION,
                PRG_TITLE,
                PRG_TITLE " " PRG_VERSION " © " PRG_YEAR " by " PRG_AUTHOR,
                "Center/Zip window by hotkey",
                NBU_UNIQUE | NBU_NOTIFY,
                0,
                0,
                0,
                0

            };

            NBroker . nb_Port = CxPort;

            Cx_SignalFlag    = 1L << CxPort -> mp_SigBit;

            TTypes           =  ArgArrayInit (argc, argv);
            NBroker . nb_Pri = (BYTE) ArgInt (TTypes, "CX_PRIORITY", 0);
            Key . Center     =     ArgString (TTypes, "KEY_CENTER",   "F1");
            Key . Parent     =     ArgString (TTypes, "KEY_PARENT",   "F2");
            Key . Zip        =     ArgString (TTypes, "KEY_ZIP",      "F3");

            if (stricmp (ArgString (TTypes, "FULLWIDTH", "NO"), "NO") == 0)
            {

                FullHeight = FALSE;

            }
            else
            {

                FullHeight = TRUE;

            }

            ArgArrayDone ();

            if (Broker = CxBroker (&NBroker, NULL))
            {

                CxMsg   *Cx_Msg;

                if (AttachFilter (Key . Center, EVT_KEY_CENTER) && AttachFilter (Key . Parent, EVT_KEY_PARENT) && AttachFilter (Key . Zip, EVT_KEY_ZIP))
                {

                    Result = RETURN_OK;

                    ActivateCxObj (Broker, TRUE);
                    ProcessMsg ();

                }

                DeleteCxObjAll (Broker);

                while (Cx_Msg = (CxMsg *) GetMsg (CxPort))          // Empty the port of all CxMsgs
                {

                    ReplyMsg ((struct Message *) Cx_Msg);

                }

            }

            DeletePort (CxPort);

        }

        CloseLibs ();

    }

    return (Result);

}

///
/// ProcessMsg ()

    /*
     *    FROM        /rkm/libs/commodities/hotkey.c
     *
     *    FUNCTION    Process commodity messages.
     *
     *    NOTE
     *
     *    EXAMPLE     ProcessMsg ();
     *
     */


static VOID
ProcessMsg (VOID)
{

    ULONG     Signal;
    UWORD     Plus   = 0;
    BOOL      Result = TRUE;
    struct    Window   *Win;
    struct
    {

        CxMsg   *Cx;
        ULONG    ID;
        ULONG    Type;

    } Msg;

    while (Result)
    {

        Signal = Wait (SIGBREAKF_CTRL_C | Cx_SignalFlag);

        while (Msg . Cx = (CxMsg *) GetMsg (CxPort))
        {

            Msg . ID   = CxMsgID   (Msg . Cx);
            Msg . Type = CxMsgType (Msg . Cx);

            ReplyMsg ((struct Message *) Msg . Cx);

            switch (Msg . Type)
            {

                case CXM_IEVENT:

                    switch (Msg . ID)
                    {

                        case EVT_KEY_CENTER:        if (Win = IntuitionBase -> ActiveWindow)
                                                    {

                                                            // Accept titlebar ?

                                                        if (FullHeight)
                                                        {

                                                            Plus = Win -> Parent -> WScreen -> Font -> ta_YSize + 3;

                                                        }
                                                        else
                                                        {

                                                            Plus = 0;

                                                        }


                                                        MoveWindow (Win, (LONG)   ( ( (Win -> WScreen -> Width          - Win -> Width ) / 2) - Win -> LeftEdge),
                                                                         (LONG) ( ( ( (Win -> WScreen -> Height - Plus) - Win -> Height) / 2) - Win ->  TopEdge));

                                                    }
                                                    break;


                        case EVT_KEY_PARENT:        if (Win = IntuitionBase -> ActiveWindow)
                                                    {

                                                        if (Win -> Parent)
                                                        {

                                                                // Parent has a dragbar ?

                                                            if (Win -> Parent -> Flags & WFLG_DRAGBAR)
                                                            {

                                                                Plus = Win -> Parent -> WScreen -> Font -> ta_YSize + 3;

                                                            }
                                                            else
                                                            {

                                                                Plus = 0;

                                                            }

                                                            MoveWindow (Win, (LONG)  Win -> Parent -> LeftEdge - Win -> LeftEdge,
                                                                             (LONG) (Win -> Parent -> TopEdge  - Win -> TopEdge) + Plus);

                                                        }

                                                    }
                                                    break;


                        case EVT_KEY_ZIP:           if (Win = IntuitionBase -> ActiveWindow)
                                                    {

                                                            // Only windows that can be zipped

                                                        if (Win -> Flags & WFLG_HASZOOM)
                                                        {

                                                            ZipWindow (Win);

                                                        }

                                                    }
                                                    break;

                    }
                    break;

                case CXM_COMMAND:

                    switch (Msg . ID)
                    {

                        case CXCMD_DISABLE:         ActivateCxObj (Broker, FALSE);
                                                    break;

                        case CXCMD_ENABLE:          ActivateCxObj (Broker, TRUE);
                                                    break;

                        case CXCMD_KILL:            Result = FALSE;
                                                    break;

                        case CXCMD_UNIQUE:          Result = FALSE;
                                                    break;

                    }
                    break;

            }

        }

        if (Signal & SIGBREAKF_CTRL_C)
        {

            Result = FALSE;

        }

    }

}

///
/// AttachFilter ()

    /*
     *    FUNCTION    Attach a filter.
     *
     *    NOTE
     *
     *    EXAMPLE     AttachFilter ("LALT b", HOTKEY);
     *
     */


static BOOL
AttachFilter (const STRPTR HotKey, const ULONG Event)
{

    CxObj   *Filter;
    CxObj   *Sender;
    CxObj   *Translator;

    if (Filter = CxFilter (HotKey))
    {

        AttachCxObj (Broker, Filter);

       if (Sender = CxSender (CxPort, Event))
       {

           AttachCxObj (Filter, Sender);

           if (Translator = CxTranslate (NULL))
           {

               AttachCxObj (Filter, Translator);

               if ( ! (CxObjError (Filter)))
               {

                   return (TRUE);

               }

           }

       }

    }

    return (FALSE);

}

///

/// 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);

    }

}

///

