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

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;
}

static void callbackFunc(spComponent component, void *data)
{
    spDebug(-10, "callbackFunc", "%s: reason = %d\n", spGetName(component), spGetCallbackReason(component));

    if (spIsComponentTrackBar(component) == SP_TRUE) {
        int value;

        if (spGetSliderValue(component, &value) == SP_TRUE) {
            spDisplayMessage(component, NULL, "value = %d\n", value);
        }
    } else {
        char *string;

        if ((string = xspGetTextString(component)) != NULL) {
            spDisplayMessage(component, NULL, string);
            xspFree(string);
        }
    }
    
    return;
}

int spMain(int argc, char *argv[])
{
    spTopLevel toplevel;
    spComponent frame;
    spComponent param_field;
    static char *list_strings[] =
    {
        "Item 1",
        "Item 2",
        "Item 3",
        "Item 4",
        "Item 5",
        NULL,
    };
    static char *file_filters[] =
    {
        "*.txt",
        "*.c",
        "*.h",
        "*",
        NULL,
    };

    /*spSetDebugLevel(50);*/
    
    /* 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("Parameter Field", NULL);

    /* create param field */
    param_field = spCreateParamField(frame, "Text Field", 0,
                                     SppDimension, "dimension",
                                     SppFieldOffset, 140,
                                     SppFieldSize, 180,
                                     SppEditable, SP_TRUE,
                                     SppCallbackFunc, callbackFunc,
                                     NULL);
    param_field = spCreateParamField(frame, "Combo Box", 0,
                                     SppFieldType, SP_FIELD_TYPE_COMBO_BOX,
                                     SppDimension, "dimension",
                                     SppFieldOffset, 140,
                                     SppFieldSize, 180,
                                     SppFieldStrings, list_strings,
                                     SppFieldSelectedIndex, 2,
                                     SppEditable, SP_TRUE,
                                     SppCallbackFunc, callbackFunc,
                                     NULL);

    param_field = spCreateParamField(frame, "Directory Text", 0,
                                     SppFieldType, SP_FIELD_TYPE_DIR_TEXT,
                                     SppFieldOffset, 140,
                                     SppFieldSize, 180,
                                     SppEditable, SP_TRUE,
                                     SppUseCheckBox, SP_TRUE,
                                     SppCallbackFunc, callbackFunc,
                                     NULL);
    param_field = spCreateParamField(frame, "Open File Text", 0,
                                     SppFieldType, SP_FIELD_TYPE_OPEN_FILE_TEXT,
                                     SppFieldOffset, 140,
                                     SppFieldSize, 180,
                                     SppEditable, SP_TRUE,
                                     SppUseCheckBox, SP_TRUE,
                                     SppFileFilters, file_filters,
                                     SppCallbackFunc, callbackFunc,
                                     NULL);
    param_field = spCreateParamField(frame, "Save File Text", 0,
                                     SppFieldType, SP_FIELD_TYPE_SAVE_FILE_TEXT,
                                     SppFieldOffset, 140,
                                     SppFieldSize, 180,
                                     SppEditable, SP_TRUE,
                                     SppUseCheckBox, SP_TRUE,
                                     SppFileFilters, file_filters,
                                     SppCallbackFunc, callbackFunc,
                                     NULL);
    param_field = spCreateParamField(frame, "Color Text", 0,
                                     SppFieldType, SP_FIELD_TYPE_COLOR_TEXT,
                                     SppFieldOffset, 140,
                                     SppFieldSize, 180,
                                     SppEditable, SP_FALSE,
                                     SppInitialColor, "white",
                                     SppCallbackFunc, callbackFunc,
                                     NULL);
    param_field = spCreateParamField(frame, "Font Text", 0,
                                     SppFieldType, SP_FIELD_TYPE_FONT_TEXT,
                                     SppFieldOffset, 140,
                                     SppFieldSize, 180,
                                     SppEditable, SP_FALSE,
                                     SppInitialFont, "-*-*-medium-r-normal--24-*-*-*-*-*-*-*",
                                     SppCallbackFunc, callbackFunc,
                                     NULL);
    
    param_field = spCreateParamField(frame, "Track Bar with Text", 0,
                                     SppFieldType, SP_FIELD_TYPE_TRACK_BAR_WITH_TEXT,
                                     SppFieldOffset, 140,
                                     SppFieldSize, 180,
                                     SppDecimalPoints, 3,
                                     SppMinimum, -5000,
                                     SppMaximum, 5000,
                                     SppValue, 100,
                                     SppTrackCallbackOn, SP_FALSE,
                                     SppCallbackFunc, callbackFunc,
                                     NULL);
    
    {
        static char *numeral_strings[] =
        {
            "0.0",
            "0.1",
            "0.2",
            "0.4",
            "0.6",
            "0.8",
            "1.0",
            NULL,
        };
        param_field = spCreateParamField(frame, "Track Bar with Combo", 0,
                                         SppFieldType, SP_FIELD_TYPE_TRACK_BAR_WITH_COMBO_BOX,
                                         SppFieldOffset, 140,
                                         SppFieldSize, 180,
                                         SppDecimalPoints, 2,
                                         SppFieldStrings, numeral_strings,
                                         SppFieldSelectedIndex, 3,
                                         SppTrackCallbackOn, SP_FALSE,
                                         SppCallbackFunc, callbackFunc,
                                         NULL);
    }
    
    param_field = spCreateParamField(frame, "Track Bar", 0,
                                     SppFieldType, SP_FIELD_TYPE_TRACK_BAR,
                                     SppFieldOffset, 140,
                                     SppFieldSize, 180,
                                     SppShowValue, SP_TRUE,
                                     SppDecimalPoints, 1,
                                     SppMinimum, -1000,
                                     SppMaximum, 1000,
                                     SppTrackCallbackOn, SP_FALSE,
                                     SppCallbackFunc, callbackFunc,
                                     NULL);

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