#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/gadgetclass.h>
#include <workbench/icon.h>
#include <workbench/workbench.h>
#include <dos/dosextens.h>

#include "amigan.h" // before icon protos

#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/icon_protos.h>
#include <clib/dos_protos.h>
#include <pragmas/icon_pragmas.h>
#include <reaction/reaction.h>
#include <utility/hooks.h>

#include <gadgets/chooser.h>
#include <pragmas/chooser_pragmas.h>
#include <gadgets/string.h>
#include <pragmas/string_pragmas.h>
#include <gadgets/checkbox.h>
#include <pragmas/checkbox_pragmas.h>
#include <gadgets/layout.h>
#include <pragmas/layout_pragmas.h>
#include <gadgets/button.h>
#include <pragmas/button_pragmas.h>
#include <images/label.h>
#include <pragmas/layout_pragmas.h>
#include <proto/label.h>
#include <classes/window.h>
#include <pragmas/window_pragmas.h>

#include <stdlib.h>
#include <string.h>

MODULE ULONG icon_VanillaKeyHook(struct Hook* h, void* o, void* m);

AGLOBAL struct Object*     object            = NULL;
AGLOBAL ULONG              app, signal;
AGLOBAL ABOOL              quit              = FALSE;
AGLOBAL struct Gadget*     gadgets[GIDS_12 + 1];
MODULE  ABOOL              stop;

// from rp.c
IMPORT ABOOL               fillwindows, pal;
IMPORT SBYTE               page;
IMPORT TEXT                asldir[VLONGFIELD + 1];
IMPORT ULONG               fillcolour;
IMPORT struct Gadget      *BU99_Left,
                          *BU99_Right,
                          *PrevGadPtr;
IMPORT struct Window*      MainWindowPtr;
IMPORT struct Screen*      ScreenPtr;
IMPORT struct SharedStruct shared;
IMPORT struct Library*    *ButtonBase,
                          *CheckBoxBase,
                          *ChooserBase,
                          *IconBase,
                          *LabelBase,
                          *LayoutBase,
                          *StringBase,
                          *WindowBase;
IMPORT struct Menu*        MenuPtr;
IMPORT ABOOL               done;
IMPORT TEXT                aslresult[VLONGFIELD + 1];

AGLOBAL struct IconStruct  icon =
{   TRUE, FALSE, FALSE, WBTOOL - 1
};

MODULE STRPTR IconOptions[9] =
{   "Disk",
    "Drawer",
    "Tool",
    "Project",
    "Trashcan",
    "Device",
    "Kickstart",
    "AppIcon",
    NULL
};
/* icon.type is 1 less than the actual value used by the system (those
start from 1, ours start from 0). */

AGLOBAL void icon1(void)
{   struct MsgPort*     AppPort;
    ULONG               i, TheTag;
    struct List         ChooserList;
    struct ChooserNode *ChooserNodePtr[7];
    struct Hook         hook;

    shared.pathname[0] = 0;

    NewList(&ChooserList);
    for (i = 0; i <= 7; i++)
    {   if (!(ChooserNodePtr[i] = (struct ChooserNode *) AllocChooserNode(CNA_Text, IconOptions[i], TAG_DONE)))
        {   rq("Can't allocate chooser node!");
        }
        AddTail(&ChooserList, (struct Node *) ChooserNodePtr[i]);
    } // automatically freed by ReAction at DisposeObject() time

    InitHook(&hook, (ULONG (*) ()) icon_VanillaKeyHook, NULL);
    if (!(AppPort = CreateMsgPort()))
    {   rq("Can't create ReAction message port!");
    }
    /* Create the window object. */

    if (pal)
    {   TheTag = WA_CustomScreen;
    } else
    {   if (!(ScreenPtr = LockPubScreen(NULL)))
            rq("Can't lock default public screen!");
        TheTag = WA_PubScreen;
    }

    gadtools();

    if (!(object =                                    NewObject(WINDOW_GetClass(), NULL,
            // window
            TheTag,                                   ScreenPtr,
            WA_ScreenTitle,                           "Report+",
            WA_Title,                                 "Report+: Icon Processor",
            WA_Activate,                              TRUE,
            WA_DepthGadget,                           TRUE,
            WA_DragBar,                               TRUE,
            WA_CloseGadget,                           TRUE,
            WA_SizeGadget,                            TRUE,
            WINDOW_AppPort,                           AppPort,
            WINDOW_MenuStrip,                         MenuPtr,
            WINDOW_Position,                          WPOS_CENTERSCREEN,
            WINDOW_IDCMPHook,                         &hook,
            WINDOW_IDCMPHookBits,                     IDCMP_VANILLAKEY,
            WINDOW_ParentGroup,                       gadgets[GID_12_WI1] =
                                                      NewObject(LAYOUT_GetClass(), NULL,
                // root-layout
                LAYOUT_Orientation,                   LAYOUT_ORIENT_VERT,
                LAYOUT_SpaceOuter,                    TRUE,
                LAYOUT_DeferLayout,                   TRUE,
                LAYOUT_AddChild,          gadgets[GID_12_CH1] =
                                          NewObject(CHOOSER_GetClass(), NULL,
                    // chooser
                    GA_ID,                GID_12_CH1,
                    CHOOSER_PopUp,        TRUE,
                    CHOOSER_Labels,       &ChooserList,
                    CHOOSER_Selected,     icon.type,
                    TAG_END),
                CHILD_WeightedHeight,     0,
                LAYOUT_AddChild,          gadgets[GID_12_CB1] =
                                          NewObject(CHECKBOX_GetClass(), NULL,
                    // checkbox
                    GA_ID,                GID_12_CB1,
                    GA_RelVerify,         TRUE,
                    GA_Text,              "_Optimize colours?",
                    GA_Selected,          (BOOL) icon.optimize,
                    TAG_END),
                CHILD_WeightedHeight,     0,
                LAYOUT_AddChild,          gadgets[GID_12_CB2] =
                                          NewObject(CHECKBOX_GetClass(), NULL,
                    // checkbox
                    GA_ID,                GID_12_CB2,
                    GA_RelVerify,         TRUE,
                    GA_Text,              "Preserve p_lanar data?",
                    GA_Selected,          (BOOL) icon.planar,
                    TAG_END),
                CHILD_WeightedHeight,     0,
                LAYOUT_AddChild,              NewObject(LAYOUT_GetClass(), NULL,
                    // layout
                    LAYOUT_Orientation,       LAYOUT_ORIENT_HORIZ,
                    GA_BackFill,              NULL,
                    LAYOUT_SpaceOuter,        TRUE,
                    LAYOUT_VertAlignment,     LALIGN_CENTER,
                    LAYOUT_HorizAlignment,    LALIGN_CENTER,
                    LAYOUT_BevelStyle,        BVS_FIELD,
                    LAYOUT_AddImage,          NewObject(LABEL_GetClass(), NULL,
                        // label
                        LABEL_Text,           "_Pathname(s):",
                        LABEL_Justification,  LJ_LEFT,
                        TAG_END),
                    LAYOUT_AddChild,          gadgets[GID_12_ST1] =
                                              NewObject(STRING_GetClass(), NULL,
                        // string        
                        GA_ID,                GID_12_ST1,
                        STRINGA_TextVal,      shared.pathname,
                        STRINGA_MinVisible,   35,
                        TAG_END),
                    LAYOUT_AddChild,          gadgets[GID_12_BU1] =
                                              NewObject(NULL, "button.gadget",
                        // button
                        GA_ID,                GID_12_BU1,
                        GA_RelVerify,         TRUE,
                        BUTTON_AutoButton,    BAG_POPFILE,
                        TAG_END),
                    CHILD_WeightedWidth,      0,
                    TAG_END),
                CHILD_WeightedHeight,         0,
                LAYOUT_AddChild,          gadgets[GID_12_ST2] =
                                          NewObject(STRING_GetClass(), NULL,
                    // string        
                    GA_ReadOnly,          TRUE,
                    GA_ID,                GID_12_ST2,
                    STRINGA_TextVal,      "Ready.",
                    TAG_END),
                CHILD_WeightedHeight,     0,
                LAYOUT_AddChild,              NewObject(LAYOUT_GetClass(), NULL,
                    // layout
                    LAYOUT_Orientation,       LAYOUT_ORIENT_HORIZ,
                    GA_BackFill,              NULL,
                    LAYOUT_SpaceOuter,        TRUE,
                    LAYOUT_VertAlignment,     LALIGN_CENTER,
                    LAYOUT_HorizAlignment,    LALIGN_CENTER,
                    LAYOUT_BevelStyle,        BVS_FIELD,
                    LAYOUT_AddChild,      gadgets[GID_12_BU3] =
                                          NewObject(NULL, "button.gadget",
                        // button
                        GA_ID,            GID_12_BU3,
                        GA_RelVerify,     TRUE,
                        GA_Text,          "Pro_cess",
                    TAG_END),
                    CHILD_WeightedWidth,  50,
                    LAYOUT_AddChild,      gadgets[GID_12_BU4] =
                                          NewObject(NULL, "button.gadget",
                        // button
                        GA_ID,            GID_12_BU2,
                        GA_RelVerify,     TRUE,
                        GA_Text,          "Stop",
                        GA_Disabled,      TRUE,
                        TAG_END),
                    CHILD_WeightedWidth,  50,
                    TAG_END),
                CHILD_WeightedHeight,     0,
                LAYOUT_AddChild,          gadgets[GID_12_BU2] =
                                          NewObject(NULL, "button.gadget",
                    // button
                    GA_ID,                GID_12_BU2,
                    GA_RelVerify,         TRUE,
                    GA_Text,              "Menu",
                    TAG_END),
                CHILD_WeightedHeight,     0,
                TAG_END),
            TAG_END)
    ))
    {   rq("Can't create ReAction objects!");
    }
    // Open the window.

    if (!(MainWindowPtr = (struct Window *) DoMethod((Object *) object, WM_OPEN, NULL)))
    {   rq("Can't open ReAction window!");        
    }
    app = (1L << AppPort->mp_SigBit);
    // Obtain the window wait signal mask.
    GetAttr(WINDOW_SigMask, object, &signal);
    ActivateLayoutGadget(gadgets[GID_12_WI1], MainWindowPtr, NULL, (Object) gadgets[GID_12_ST1]);
    reaction_loop();

    /* Disposing of the window object will also close the window if it is
     * already opened, and it will dispose of the layout object attached to it.
     */
    DisposeObject(object);
    MainWindowPtr = NULL;
    DeleteMsgPort(AppPort);

    if (quit)
    {   cleanexit(EXIT_SUCCESS);
}   }

AGLOBAL void icon_do(void)
{   STRPTR stringptr;

    if (!(GetAttr
    (   CHOOSER_Selected, gadgets[GID_12_CH1], (ULONG *) &(icon.type)
    )))
    {   rq("Unsupported inquiry!"); // should never happen
    }
    if (!(GetAttr
    (   STRINGA_TextVal, gadgets[GID_12_ST1], (ULONG *) &stringptr
    )))
    {   rq("Unsupported inquiry!"); // should never happen
    }
    strcpy(shared.pathname, stringptr);
    // to other similar parts of f12.c
    if (!(GetAttr
    (   GA_Selected, gadgets[GID_12_CB1], (ULONG *) &(icon.optimize)
    )))
    {   rq("Unsupported inquiry!"); // should never happen
    }
    if (!(GetAttr
    (   GA_Selected, gadgets[GID_12_CB2], (ULONG *) &(icon.planar)
    )))
    {   rq("Unsupported inquiry!"); // should never happen
    }

    SetGadgetAttrs
    (   gadgets[GID_12_CH1], MainWindowPtr, NULL,
        GA_Disabled, TRUE,
        TAG_END
    );
    SetGadgetAttrs
    (   gadgets[GID_12_CB1], MainWindowPtr, NULL,
        GA_Disabled, TRUE,
        TAG_END
    );
    SetGadgetAttrs
    (   gadgets[GID_12_CB2], MainWindowPtr, NULL,
        GA_Disabled, TRUE,
        TAG_END
    );
    SetGadgetAttrs
    (   gadgets[GID_12_ST1], MainWindowPtr, NULL,
        GA_Disabled, TRUE,
        TAG_END
    );
    SetGadgetAttrs
    (   gadgets[GID_12_BU1], MainWindowPtr, NULL,
        GA_Disabled, TRUE,
        TAG_END
    );
    SetGadgetAttrs
    (   gadgets[GID_12_BU2], MainWindowPtr, NULL,
        GA_Disabled, TRUE,
        TAG_END
    );
    SetGadgetAttrs
    (   gadgets[GID_12_BU3], MainWindowPtr, NULL,
        GA_Disabled, TRUE,
        TAG_END
    );
    SetGadgetAttrs
    (   gadgets[GID_12_BU4], MainWindowPtr, NULL,
        GA_Disabled, FALSE,
        TAG_END
    );
                          
    convert(TRUE);

    if (!stop)
    {   SetGadgetAttrs
        (   gadgets[GID_12_ST2], MainWindowPtr, NULL,
            STRINGA_TextVal, "All done.",
            TAG_END
        );
    }
    SetGadgetAttrs
    (   gadgets[GID_12_CH1], MainWindowPtr, NULL,
        GA_Disabled, FALSE,
        TAG_END
    );
    SetGadgetAttrs
    (   gadgets[GID_12_CB1], MainWindowPtr, NULL,
        GA_Disabled, FALSE,
        TAG_END
    );
    SetGadgetAttrs
    (   gadgets[GID_12_CB2], MainWindowPtr, NULL,
        GA_Disabled, FALSE,
        TAG_END
    );
    SetGadgetAttrs
    (   gadgets[GID_12_ST1], MainWindowPtr, NULL,
        GA_Disabled, FALSE,
        TAG_END
    );
    SetGadgetAttrs
    (   gadgets[GID_12_BU1], MainWindowPtr, NULL,
        GA_Disabled, FALSE,
        TAG_END
    );
    SetGadgetAttrs
    (   gadgets[GID_12_BU2], MainWindowPtr, NULL,
        GA_Disabled, FALSE,
        TAG_END
    );
    SetGadgetAttrs
    (   gadgets[GID_12_BU3], MainWindowPtr, NULL,
        GA_Disabled, FALSE,
        TAG_END
    );
    SetGadgetAttrs
    (   gadgets[GID_12_BU4], MainWindowPtr, NULL,
        GA_Disabled, TRUE,
        TAG_END
    );
}

AGLOBAL void iconconvert(ABOOL gui)
{   TEXT               saystring[LONGFIELD + 1];
    ULONG              length = strlen(shared.thisfile);
    struct DiskObject* IconPtr;

    if (length <= 5) // in case we get passed an empty string
    {   return;
    }
    if (!stricmp(&(shared.thisfile[length - 5]), ".info"))
    {   shared.thisfile[length - 5] = 0;
    }
   
    strcpy(saystring, "Processing ");
    strcat(saystring, shared.thisfile);
    strcat(saystring, ".info...");
    if (gui)
    {   SetGadgetAttrs
        (   gadgets[GID_12_ST2], MainWindowPtr, NULL,
            STRINGA_TextVal, saystring,
            TAG_END
        );
    } else
    {   Printf("%s", saystring);
        Flush(Output());
        saystring[0] = 0;
    }

    if (IconPtr = GetIconTags(shared.thisfile, TAG_END))
    {   IconPtr->do_Type = icon.type + 1;
        if (PutIconTags
        (   shared.thisfile, IconPtr,
            ICONPUTA_OptimizeImageSpace,  (BOOL) icon.optimize,
            ICONPUTA_DropPlanarIconImage, (BOOL) (!icon.planar),
            TAG_END
        ))
        {   strcat(saystring, "done.");
        } else strcat(saystring, "failed to write!");
    } else strcat(saystring, "failed to read!");

    if (gui)
    {   SetGadgetAttrs
        (   gadgets[GID_12_ST2], MainWindowPtr, NULL,
            STRINGA_TextVal, saystring,
            TAG_END
        );
    } else
    {   Printf("%s\n", saystring);
    }

    checkabort(gui);
}

AGLOBAL void icon_loop(ULONG gid)
{   STRPTR stringptr;

    switch (gid)
    {
    case GID_12_CH1:
        if (!(GetAttr
        (   CHOOSER_Selected, gadgets[GID_12_CH1], (ULONG *) &(icon.type)
        )))
        {   rq("Unsupported inquiry!"); // should never happen
        }
    break;
    case GID_12_ST1:
        if (!(GetAttr
        (   STRINGA_TextVal, gadgets[GID_12_ST1], (ULONG *) &stringptr
        )))
        {   rq("Unsupported inquiry!"); // should never happen
        }
    break;
    case GID_12_BU1:
        multiasl("#?.info");
        SetGadgetAttrs
        (   gadgets[GID_12_ST1], MainWindowPtr, NULL,
            STRINGA_TextVal,  shared.pathname,
            TAG_END
        );
    break;
    case GID_12_BU2:
        page = 0;
    break;
    case GID_12_BU3:
        icon_do();
    break;
    case GID_12_CB1:
        if (!(GetAttr
        (   GA_Selected, gadgets[GID_12_CB1], (ULONG *) &(icon.optimize)
        )))
        {   rq("Unsupported inquiry!"); // should never happen
        }
    break;
    case GID_12_CB2:
        if (!(GetAttr
        (   GA_Selected, gadgets[GID_12_CB2], (ULONG *) &(icon.planar)
        )))
        {   rq("Unsupported inquiry!"); // should never happen
        }
    break;
    default:
    break;
}   }

MODULE ULONG icon_VanillaKeyHook(struct Hook* h, void* o, void* m)
{      UWORD code = ((struct IntuiMessage *) m)->Code;
    // UWORD qual = ((struct IntuiMessage *) m)->Qualifier;

    // get access to the global data segment
    // geta4();

    switch(code)
    {
    case 'P':
        ActivateLayoutGadget(gadgets[GID_12_WI1], MainWindowPtr, NULL, (Object) gadgets[GID_12_ST1]);
    break;
    case ESCAPE:
        page = 0;
    break;
    default:
    break;
    }     
    return(0);
}
