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

static int object_radius = 2;

static spBool clear_flag = SP_TRUE;
static spGraphics graphics = NULL;
static spComponent image = NULL;
static int image_width = 0;
static int image_height = 0;

static void canvasCB(spComponent component, void *data)
{
    int width = 0, height = 0;
    int x, y;
    spCallbackReason reason;

    reason = spGetCallbackReason(component);
    spDebug(20, "canvasCB", "reason = %d\n", reason);
    
    spGetSize(component, &width, &height);
    spDebug(20, "canvasCB", "width = %d, height = %d, image_width = %d, image_height = %d\n",
            width, height, image_width, image_height);

    if (reason == SP_CR_RESIZE) {
        if (image != NULL) {
            if (image_width > 0 && image_height > 0) {
                spDebug(20, "canvasCB", "call spStretchImage\n");
                spStretchImage(image, component,
                               0, 0, image_width, image_height,
                               0, 0, width, height);
            }
        } else {
            clear_flag = SP_TRUE;
        }
    }
    
    if (clear_flag == SP_TRUE) {
        spSetGraphicsParams(graphics, SppForeground, "white", NULL);
        spFillRectangle(component, graphics, 0, 0, width, height);
        clear_flag = SP_FALSE;
    }

    if (reason == SP_CR_LBUTTON_MOTION || reason == SP_CR_LBUTTON_PRESS) {
        if (spGetCallbackMousePosition(component, &x, &y) == SP_TRUE) {
            spDebug(20, "canvasCB", "x = %d, y = %d\n", x, y);
            spSetGraphicsParams(graphics, SppForeground, "black", NULL);
            spFillArc(component, graphics, x - object_radius, y - object_radius,
                      object_radius * 2, object_radius * 2, 0.0, 360.0);
        }
    } else if (reason == SP_CR_LBUTTON_RELEASE) {
        if (image != NULL) {
            spDebug(20, "canvasCB", "call spDestroyComponent\n");
            spDestroyComponent(image);
        }
        spDebug(20, "canvasCB", "call spCreateImage\n");
        image = spCreateImage(component, "offlineImage", width, height, NULL);

        spDebug(20, "canvasCB", "call spCopyImage\n");
        spCopyImage(component, image, 0, 0, width, height, 0, 0);
        image_width = width;
        image_height = height;
    }
    
    spDebug(20, "canvasCB", "call spRefreshCanvas\n");
    spRefreshCanvas(component);
    
    spDebug(20, "canvasCB", "done\n");
    
    return;
}

int spMain(int argc, char *argv[])
{
    spTopLevel toplevel;
    spComponent frame;
    spComponent menu, menu_bar;
    spComponent canvas;

    /* initialize toolkit */
    toplevel = spInitialize(&argc, &argv, NULL);
    
    /* create main window */
    frame = spCreateMainFrame("Simple Paint", NULL);

    /* create menu bar */
    menu_bar = spCreateMenuBar(frame, "menuBar", NULL);
    
    /* create menu */
    menu = spCreatePulldownMenu(menu_bar, "fileMenu",
                                SppTitle, "File",
                                NULL);
    
    /* add menu item */
    spAddMenuItem(menu, SP_QUIT_MENU_ITEM_NAME,
                  SppCallbackFunc, spQuitCB,
                  SppTitle, "Quit",
                  SppShortcut, "A-q",
                  NULL);

    /* create canvas */
    canvas = spCreateCanvas(frame, "canvas", 300, 300,
                            SppBorderOn, SP_TRUE,
                            SppCallbackFunc, canvasCB,
                            NULL);
    spAddCallback(canvas, SP_BUTTON_MOTION_CALLBACK | SP_BUTTON_PRESS_CALLBACK | SP_BUTTON_RELEASE_CALLBACK, canvasCB, NULL);

    graphics = spCreateGraphics("graphics1",
                                NULL);
    
    /* popup window */
    spPopupWindow(frame);
    
    /* main loop */
    return spMainLoop(toplevel);
}
