#include <stdio.h>
#include <sp/spBaseLib.h>
#include <sp/spComponentLib.h>
#include <sp/spComponentMain.h>

static char *file_filters[] =
{
    "*.txt",
    "*.c",
    "*.h",
    "*",
    NULL,
};

static char *file_types[] =
{
    "Text Files",
    "C source files",
    "C header files",
    "All files",
    NULL,
};

static void fileDialogCB(spComponent component, int dialog_type)
{
    char *filename;
    char *readable;
    int filter_index = 0;

    spDebug(50, "fileDialogCB", "dialog_type = %d\n", dialog_type);
    
    if (dialog_type == 0) {
        filename = xspGetOpenFileName(component, NULL,
                                      SppFileFilters, file_filters,
                                      SppFileTypes, file_types,
                                      SppFileFilterIndex, &filter_index,
                                      SppPathMustExist, SP_TRUE,
                                      SppFileMustExist, SP_TRUE,
                                      SppOverwritePrompt, SP_FALSE,
                                      NULL);
        if (filename != NULL) {
            if ((readable = xspGetReadablePath(filename)) != NULL) {
                spDisplayMessage(component, NULL, "Open File: %s (file type: %s)", readable, file_types[filter_index]);
                xspFree(readable);
            }
            xspFree(filename);
        }
    } else if (dialog_type == 1) {
        filename = xspGetSaveFileName(component, NULL,
                                      SppFileFilters, file_filters,
                                      SppFileTypes, file_types,
                                      SppFileFilterIndex, &filter_index,
                                      SppPathMustExist, SP_TRUE,
                                      SppFileMustExist, SP_FALSE,
                                      SppOverwritePrompt, SP_TRUE,
                                      SppInitialFileName, "test",
                                      NULL);
        if (filename != NULL) {
            if ((readable = xspGetReadablePath(filename)) != NULL) {
                spDisplayMessage(component, NULL, "Save File: %s (file type: %s)", readable, file_types[filter_index]);
                xspFree(readable);
            }
            xspFree(filename);
        }
    } else if (dialog_type == 2) {
        filename = xspGetSelectedDirName(component, NULL,
                                         SppPathMustExist, SP_TRUE,
                                         NULL);
        if (filename != NULL) {
            if ((readable = xspGetReadablePath(filename)) != NULL) {
                spDisplayMessage(component, NULL, "Selected Directory: %s", readable);
                xspFree(readable);
            }
            xspFree(filename);
        }
    } else if (dialog_type == 3) {
        filename = xspChooseColor(component, NULL,
                                  SppInitialColor, "Blue",
                                  NULL);
        if (filename != NULL) {
            spDisplayMessage(component, NULL, "Selected Color: %s", filename);
            xspFree(filename);
        }
    } else if (dialog_type == 4) {
        static char *fontname = NULL/*"-*-*-medium-r-normal--24-*-*-*-*-*-*-*"*/;

        filename = xspChooseFont(component, NULL,
                                 SppInitialFont, fontname,
                                 NULL);
        if (filename != NULL) {
            spDisplayMessage(component, NULL, "Selected Font: %s", filename);
            
            if (fontname != NULL) xspFree(fontname);
            fontname = filename;
        }
    }

    spDebug(50, "fileDialogCB", "done\n");

    return;
}

static spBool toplevelCB(spTopLevel toplevel, spTopLevelCallbackReason reason, void *data)
{
    spDebug(10, "toplevelCB", "reason = %d\n", reason);

    if (reason == SP_TL_CR_PERMISSION_RATIONALE_ASKED) {
        unsigned long asked_permissions = 0L;
        
        spGetTopLevelParams(toplevel,
                            SppAskedPermissions, &asked_permissions, 
                            NULL);

        spDebug(10, "toplevelCB", "asked_permissions = %lx\n", asked_permissions);
        
        if (asked_permissions) {
            if (spCreateMessageBox(NULL,
                                   NULL,
                                   "File dialog requires permission to access external directories.\nProceed?",
                                   SppDialogType, SP_QUESTION_DIALOG,
                                   SppMessageBoxButtonType, SP_MB_YES_NO,
                                   NULL) == SP_DR_NO) {
                return SP_FALSE;
            }
        }
    } else if (reason == SP_TL_CR_PERMISSION_CHANGED) {
        unsigned long accepted_permissions = 0L;
        unsigned long disabled_permissions = 0L;
        
        spGetTopLevelParams(toplevel,
                            SppAcceptedPermissions, &accepted_permissions, 
                            SppDisabledPermissions, &disabled_permissions, 
                            NULL);

        spDebug(10, "toplevelCB", "accepted_permissions = %lx, disabled_permissions = %lx\n",
                accepted_permissions, disabled_permissions);

        if (!(accepted_permissions & SP_PERMISSION_READ_EXTERNAL_STORAGE)
            || !(accepted_permissions & SP_PERMISSION_WRITE_EXTERNAL_STORAGE)) {
            spDisplayWarning(NULL, NULL, "Access to external directories is restricted.");
        }
    }
    
    return SP_TRUE;
}

int spMain(int argc, char *argv[])
{
    spTopLevel toplevel;
    spComponent frame;
    spComponent open_button, save_button, quit_button;
    spComponent dir_button;
    spComponent color_button, font_button;

    /*spSetDebugLevel(100);*/
    
    /* initialize toolkit */
    toplevel = spInitialize(&argc, &argv,
                            SppPermissions, SP_PERMISSION_READ_EXTERNAL_STORAGE | SP_PERMISSION_WRITE_EXTERNAL_STORAGE,
                            SppTopLevelCallbackFunc, toplevelCB,
                            NULL);

    /* create main window */
    frame = spCreateMainFrame("File Dialog", NULL);

    /* create push buttons */
    open_button = spCreatePushButton(frame, "Open...",
                                     SppCallbackFunc, fileDialogCB,
                                     SppCallbackData, 0,
                                     SppInitialWidth, 200,
                                     SppDescription, "Create open file dialog",
                                     NULL);
    save_button = spCreatePushButton(frame, "Save...",
                                     SppCallbackFunc, fileDialogCB,
                                     SppCallbackData, 1,
                                     SppInitialWidth, 200,
                                     SppDescription, "Create save file dialog",
                                     NULL);
    dir_button = spCreatePushButton(frame, "Directory...",
                                    SppCallbackFunc, fileDialogCB,
                                    SppCallbackData, 2,
                                    SppInitialWidth, 200,
                                    SppDescription, "Create directory selection dialog",
                                    NULL);
    color_button = spCreatePushButton(frame, "Color...",
                                      SppCallbackFunc, fileDialogCB,
                                      SppCallbackData, 3,
                                      SppInitialWidth, 200,
                                      SppDescription, "Create choose color dialog",
                                      NULL);
    font_button = spCreatePushButton(frame, "Font...",
                                     SppCallbackFunc, fileDialogCB,
                                     SppCallbackData, 4,
                                     SppInitialWidth, 200,
                                     SppDescription, "Create choose font dialog",
                                     NULL);
    
    quit_button = spCreatePushButton(frame, "Quit",
                                     SppCallbackFunc, spQuitCB,
                                     SppInitialWidth, 200,
                                     SppDescription, "Quit program",
                                     NULL);

    /* popup window */
    spPopupWindow(frame);
    
    /* main loop */
    return spMainLoop(toplevel);
}
