#include "WINGsP.h"
#include "WUtil.h"
#include "wconfig.h"

#include <ctype.h>
#include <string.h>

#include <X11/Xft/Xft.h>
#include <fontconfig/fontconfig.h>


/* XXX TODO */
char *WMFontPanelFontChangedNotification = "WMFontPanelFontChangedNotification";




typedef struct W_FontPanel {
    WMWindow *win;

    WMFrame *upperF;
    WMTextField *sampleT;

    WMSplitView *split;

    WMFrame *lowerF;
    WMLabel *famL;
    WMList *famLs;
    WMLabel *typL;
    WMList *typLs;
    WMLabel *sizL;
    WMTextField *sizT;
    WMList *sizLs;

    WMAction2 *action;
    void *data;

    WMButton *revertB;
    WMButton *setB;

    WMPropList *fdb;
} FontPanel;


#define MIN_UPPER_HEIGHT	20
#define MIN_LOWER_HEIGHT	140


#define MAX_FONTS_TO_RETRIEVE	2000

#define BUTTON_SPACE_HEIGHT 40

#define MIN_WIDTH	250
#define MIN_HEIGHT 	(MIN_UPPER_HEIGHT+MIN_LOWER_HEIGHT+BUTTON_SPACE_HEIGHT)

#define DEF_UPPER_HEIGHT 60
#define DEF_LOWER_HEIGHT 310

#define DEF_WIDTH	320
#define DEF_HEIGHT	(DEF_UPPER_HEIGHT+DEF_LOWER_HEIGHT)




static int scalableFontSizes[] = {
    8,
    10,
    11,
    12,
    14,
    16,
    18,
    20,
    24,
    36,
    48,
    64
};



static void setFontPanelFontName(FontPanel *panel, FcChar8 *family, FcChar8 *style, double size);

static int isXLFD(char *font, int *length_ret);

static void arrangeLowerFrame(FontPanel *panel);

static void familyClick(WMWidget *, void *);
static void typefaceClick(WMWidget *, void *);
static void sizeClick(WMWidget *, void *);


static void listFamilies(WMScreen *scr, WMFontPanel *panel);


static void
splitViewConstrainCallback(WMSplitView *sPtr, int indView, int *min, int *max)
{
    if (indView == 0)
        *min = MIN_UPPER_HEIGHT;
    else
        *min = MIN_LOWER_HEIGHT;
}

static void
notificationObserver(void *self, WMNotification *notif)
{
    WMFontPanel *panel = (WMFontPanel*)self;
    void *object = WMGetNotificationObject(notif);

    if (WMGetNotificationName(notif) == WMViewSizeDidChangeNotification) {
        if (object == WMWidgetView(panel->win)) {
            int h = WMWidgetHeight(panel->win);
            int w = WMWidgetWidth(panel->win);

            WMResizeWidget(panel->split, w, h-BUTTON_SPACE_HEIGHT);

            WMMoveWidget(panel->setB, w-80, h-(BUTTON_SPACE_HEIGHT-5));

            WMMoveWidget(panel->revertB, w-240, h-(BUTTON_SPACE_HEIGHT-5));

        } else if (object == WMWidgetView(panel->upperF)) {

            if (WMWidgetHeight(panel->upperF) < MIN_UPPER_HEIGHT) {
                WMResizeWidget(panel->upperF, WMWidgetWidth(panel->upperF),
                               MIN_UPPER_HEIGHT);
            } else {
                WMResizeWidget(panel->sampleT, WMWidgetWidth(panel->upperF)-20,
                               WMWidgetHeight(panel->upperF)-10);
            }

        } else if (object == WMWidgetView(panel->lowerF)) {

            if (WMWidgetHeight(panel->lowerF) < MIN_LOWER_HEIGHT) {
                WMResizeWidget(panel->upperF, WMWidgetWidth(panel->upperF),
                               MIN_UPPER_HEIGHT);

                WMMoveWidget(panel->lowerF, 0, WMWidgetHeight(panel->upperF)
                             + WMGetSplitViewDividerThickness(panel->split));

                WMResizeWidget(panel->lowerF, WMWidgetWidth(panel->lowerF),
                               WMWidgetWidth(panel->split) - MIN_UPPER_HEIGHT
                               - WMGetSplitViewDividerThickness(panel->split));
            } else {
                arrangeLowerFrame(panel);
            }
        }
    }
}


static void
closeWindow(WMWidget *w, void *data)
{
    FontPanel *panel = (FontPanel*)data;

    WMHideFontPanel(panel);
}




static void
setClickedAction(WMWidget *w, void *data)
{
    FontPanel *panel = (FontPanel*)data;

    if (panel->action)
        (*panel->action)(panel, panel->data);
}


static void
revertClickedAction(WMWidget *w, void *data)
{
    /*FontPanel *panel = (FontPanel*)data;*/
    /* XXX TODO */
}



WMFontPanel*
WMGetFontPanel(WMScreen *scr)
{
    FontPanel *panel;
    WMColor *dark, *white;
    WMFont *font;
    int divThickness;

    if (scr->sharedFontPanel)
        return scr->sharedFontPanel;


    panel = wmalloc(sizeof(FontPanel));
    memset(panel, 0, sizeof(FontPanel));

    panel->win = WMCreateWindow(scr, "fontPanel");
    /*    WMSetWidgetBackgroundColor(panel->win, WMWhiteColor(scr));*/
    WMSetWindowTitle(panel->win, _("Font Panel"));
    WMResizeWidget(panel->win, DEF_WIDTH, DEF_HEIGHT);
    WMSetWindowMinSize(panel->win, MIN_WIDTH, MIN_HEIGHT);
    WMSetViewNotifySizeChanges(WMWidgetView(panel->win), True);

    WMSetWindowCloseAction(panel->win, closeWindow, panel);

    panel->split = WMCreateSplitView(panel->win);
    WMResizeWidget(panel->split, DEF_WIDTH, DEF_HEIGHT - BUTTON_SPACE_HEIGHT);
    WMSetSplitViewConstrainProc(panel->split, splitViewConstrainCallback);

    divThickness = WMGetSplitViewDividerThickness(panel->split);

    panel->upperF = WMCreateFrame(panel->win);
    WMSetFrameRelief(panel->upperF, WRFlat);
    WMSetViewNotifySizeChanges(WMWidgetView(panel->upperF), True);
    panel->lowerF = WMCreateFrame(panel->win);
    /*    WMSetWidgetBackgroundColor(panel->lowerF, WMBlackColor(scr));*/
    WMSetFrameRelief(panel->lowerF, WRFlat);
    WMSetViewNotifySizeChanges(WMWidgetView(panel->lowerF), True);

    WMAddSplitViewSubview(panel->split, W_VIEW(panel->upperF));
    WMAddSplitViewSubview(panel->split, W_VIEW(panel->lowerF));

    WMResizeWidget(panel->upperF, DEF_WIDTH, DEF_UPPER_HEIGHT);

    WMResizeWidget(panel->lowerF, DEF_WIDTH, DEF_LOWER_HEIGHT);

    WMMoveWidget(panel->lowerF, 0, 60+divThickness);

    white = WMWhiteColor(scr);
    dark = WMDarkGrayColor(scr);

    panel->sampleT = WMCreateTextField(panel->upperF);
    WMResizeWidget(panel->sampleT, DEF_WIDTH - 20, 50);
    WMMoveWidget(panel->sampleT, 10, 10);
    WMSetTextFieldText(panel->sampleT, _("The quick brown fox jumps over the lazy dog"));

    font = WMBoldSystemFontOfSize(scr, 12);

    panel->famL = WMCreateLabel(panel->lowerF);
    WMSetWidgetBackgroundColor(panel->famL, dark);
    WMSetLabelText(panel->famL, _("Family"));
    WMSetLabelFont(panel->famL, font);
    WMSetLabelTextColor(panel->famL, white);
    WMSetLabelRelief(panel->famL, WRSunken);
    WMSetLabelTextAlignment(panel->famL, WACenter);

    panel->famLs = WMCreateList(panel->lowerF);
    WMSetListAction(panel->famLs, familyClick, panel);

    panel->typL = WMCreateLabel(panel->lowerF);
    WMSetWidgetBackgroundColor(panel->typL, dark);
    WMSetLabelText(panel->typL, _("Typeface"));
    WMSetLabelFont(panel->typL, font);
    WMSetLabelTextColor(panel->typL, white);
    WMSetLabelRelief(panel->typL, WRSunken);
    WMSetLabelTextAlignment(panel->typL, WACenter);

    panel->typLs = WMCreateList(panel->lowerF);
    WMSetListAction(panel->typLs, typefaceClick, panel);

    panel->sizL = WMCreateLabel(panel->lowerF);
    WMSetWidgetBackgroundColor(panel->sizL, dark);
    WMSetLabelText(panel->sizL, _("Size"));
    WMSetLabelFont(panel->sizL, font);
    WMSetLabelTextColor(panel->sizL, white);
    WMSetLabelRelief(panel->sizL, WRSunken);
    WMSetLabelTextAlignment(panel->sizL, WACenter);

    panel->sizT = WMCreateTextField(panel->lowerF);
    /*    WMSetTextFieldAlignment(panel->sizT, WARight);*/

    panel->sizLs = WMCreateList(panel->lowerF);
    WMSetListAction(panel->sizLs, sizeClick, panel);

    WMReleaseFont(font);
    WMReleaseColor(white);
    WMReleaseColor(dark);

    panel->setB = WMCreateCommandButton(panel->win);
    WMResizeWidget(panel->setB, 70, 24);
    WMMoveWidget(panel->setB, 240, DEF_HEIGHT - (BUTTON_SPACE_HEIGHT-5));
    WMSetButtonText(panel->setB, _("Set"));
    WMSetButtonAction(panel->setB, setClickedAction, panel);

    panel->revertB = WMCreateCommandButton(panel->win);
    WMResizeWidget(panel->revertB, 70, 24);
    WMMoveWidget(panel->revertB, 80, DEF_HEIGHT - (BUTTON_SPACE_HEIGHT-5));
    WMSetButtonText(panel->revertB, _("Revert"));
    WMSetButtonAction(panel->revertB, revertClickedAction, panel);


    WMRealizeWidget(panel->win);

    WMMapSubwidgets(panel->upperF);
    WMMapSubwidgets(panel->lowerF);
    WMMapSubwidgets(panel->split);
    WMMapSubwidgets(panel->win);

    WMUnmapWidget(panel->revertB);

    arrangeLowerFrame(panel);

    scr->sharedFontPanel = panel;


    /* register notification observers */
    WMAddNotificationObserver(notificationObserver, panel,
                              WMViewSizeDidChangeNotification,
                              WMWidgetView(panel->win));
    WMAddNotificationObserver(notificationObserver, panel,
                              WMViewSizeDidChangeNotification,
                              WMWidgetView(panel->upperF));
    WMAddNotificationObserver(notificationObserver, panel,
                              WMViewSizeDidChangeNotification,
                              WMWidgetView(panel->lowerF));


    listFamilies(scr, panel);


    return panel;
}


void
WMFreeFontPanel(WMFontPanel *panel)
{
    if (panel == WMWidgetScreen(panel->win)->sharedFontPanel) {
        WMWidgetScreen(panel->win)->sharedFontPanel = NULL;
    }
    WMRemoveNotificationObserver(panel);
    WMUnmapWidget(panel->win);
    WMDestroyWidget(panel->win);
    wfree(panel);
}


void
WMShowFontPanel(WMFontPanel *panel)
{
    WMMapWidget(panel->win);
}


void
WMHideFontPanel(WMFontPanel *panel)
{
    WMUnmapWidget(panel->win);
}


WMFont*
WMGetFontPanelFont(WMFontPanel *panel)
{
    return WMGetTextFieldFont(panel->sampleT);
}


void
WMSetFontPanelFont(WMFontPanel *panel, char *fontName)
{
    int fname_len;
    FcPattern *pattern;
    FcChar8 *family, *style;
    double size;

    if (!isXLFD(fontName, &fname_len)) {
        /* maybe its proper fontconfig and we can parse it */
        pattern = FcNameParse(fontName);
    } else {
        /* maybe its proper xlfd and we can convert it to an FcPattern */
        pattern = XftXlfdParse(fontName, False, False);
        /*//FcPatternPrint(pattern);*/
    }

    if (!pattern)
        return;

    if (FcPatternGetString(pattern, FC_FAMILY, 0, &family)==FcResultMatch)
        if (FcPatternGetString(pattern, FC_STYLE, 0, &style)==FcResultMatch)
            if (FcPatternGetDouble(pattern, "pixelsize", 0, &size)==FcResultMatch)
                setFontPanelFontName(panel, family, style, size);

    FcPatternDestroy(pattern);
}


void
WMSetFontPanelAction(WMFontPanel *panel, WMAction2 *action, void *data)
{
    panel->action = action;
    panel->data = data;
}





static void
arrangeLowerFrame(FontPanel *panel)
{
    int width = WMWidgetWidth(panel->lowerF) - 55 - 30;
    int height = WMWidgetHeight(panel->split) - WMWidgetHeight(panel->upperF);
    int fw, tw, sw;

#define LABEL_HEIGHT 20

    height -= WMGetSplitViewDividerThickness(panel->split);


    height -= LABEL_HEIGHT + 8;

    fw = (125*width) / 235;
    tw = (110*width) / 235;
    sw = 55;

    WMMoveWidget(panel->famL, 10, 0);
    WMResizeWidget(panel->famL, fw, LABEL_HEIGHT);

    WMMoveWidget(panel->famLs, 10, 23);
    WMResizeWidget(panel->famLs, fw, height);

    WMMoveWidget(panel->typL, 10+fw+3, 0);
    WMResizeWidget(panel->typL, tw, LABEL_HEIGHT);

    WMMoveWidget(panel->typLs, 10+fw+3, 23);
    WMResizeWidget(panel->typLs, tw, height);

    WMMoveWidget(panel->sizL, 10+fw+3+tw+3, 0);
    WMResizeWidget(panel->sizL, sw+4, LABEL_HEIGHT);

    WMMoveWidget(panel->sizT, 10+fw+3+tw+3, 23);
    WMResizeWidget(panel->sizT, sw+4, 20);

    WMMoveWidget(panel->sizLs, 10+fw+3+tw+3, 46);
    WMResizeWidget(panel->sizLs, sw+4, height-23);
}



#define NUM_FIELDS 14


static int
isXLFD(char *font, int *length_ret)
{
    int c = 0;

    *length_ret = 0;
    while (*font) {
        (*length_ret)++;
        if (*font++ == '-')
            c++;
    }

    return c==NUM_FIELDS;
}


typedef struct {
    char *typeface;
    WMArray *sizes;
} Typeface;

typedef struct {
    char *name; /* gotta love simplicity */
    WMArray *typefaces;
} Family;


static int
compare_int(const void *a, const void *b)
{
    int i1 = *(int*)a;
    int i2 = *(int*)b;

    if (i1 < i2)
        return -1;
    else if (i1 > i2)
        return 1;
    else
        return 0;
}


static void
addSizeToTypeface(Typeface *face, int size)
{
    if (size == 0) {
        int j;

        for (j = 0; j < sizeof(scalableFontSizes)/sizeof(int); j++) {
            size = scalableFontSizes[j];

            if (!WMCountInArray(face->sizes, (void*)size)) {
                WMAddToArray(face->sizes, (void*)size);
            }
        }
        WMSortArray(face->sizes, compare_int);
    } else {
        if (!WMCountInArray(face->sizes, (void*)size)) {
            WMAddToArray(face->sizes, (void*)size);
            WMSortArray(face->sizes, compare_int);
        }
    }
}

static void
addTypefaceToXftFamily(Family *fam, char *style)
{
    Typeface *face;
    WMArrayIterator i;

    if(fam->typefaces) {
        WM_ITERATE_ARRAY(fam->typefaces, face, i) {
            if(strcmp(face->typeface, style) != 0)
                continue; /* go to next interation */
            addSizeToTypeface(face, 0);
            return;
        }
    } else {
        fam->typefaces = WMCreateArray(4);
    }

    face = wmalloc(sizeof(Typeface));
    memset(face, 0 , sizeof(Typeface));

    face->typeface = wstrdup(style);
    face->sizes = WMCreateArray(4);
    addSizeToTypeface(face, 0);

    WMAddToArray(fam->typefaces, face);
}

/*
 * families (same family name) (Hashtable of family -> array)
 * 	registries (same family but different registries)
 *
 */
static void
addFontToXftFamily(WMHashTable *families, char *name, char *style)
{
    WMArrayIterator i;
    WMArray *array;
    Family *fam;

    array = WMHashGet(families, name);
    if(array) {
        WM_ITERATE_ARRAY(array, fam, i) {
            if(strcmp(fam->name, name) == 0 )
                addTypefaceToXftFamily(fam, style);
            return;
        }
    }

    array = WMCreateArray(8);

    fam = wmalloc(sizeof(Family));
    memset(fam, 0, sizeof(Family));

    fam->name = wstrdup(name);

    addTypefaceToXftFamily(fam, style);

    WMAddToArray(array, fam);

    WMHashInsert(families, fam->name, array);
}


static void
listFamilies(WMScreen *scr, WMFontPanel *panel)
{
    FcObjectSet *os = 0;
    FcFontSet	*fs;
    FcPattern	*pat;
    WMHashTable *families;
    WMHashEnumerator enumer;
    WMArray *array;
    int i;

    pat = FcPatternCreate();
    os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, 0);
    fs = FcFontList(0, pat, os);
    if (!fs) {
        WMRunAlertPanel(scr, panel->win, _("Error"),
                        _("Could not init font config library\n"), _("OK"), NULL, NULL);
        return;
    }
    if (pat)
        FcPatternDestroy (pat);

    families = WMCreateHashTable(WMStringPointerHashCallbacks);

    if(fs) {
        for (i = 0; i < fs->nfont; i++) {
            FcChar8 *family;
            FcChar8 *style;

            if (FcPatternGetString(fs->fonts[i],FC_FAMILY,0,&family)==FcResultMatch)
                if (FcPatternGetString(fs->fonts[i],FC_STYLE,0,&style)==FcResultMatch)
                    addFontToXftFamily(families, family, style);
        }
        FcFontSetDestroy(fs);
    }

    enumer = WMEnumerateHashTable(families);

    while ((array = WMNextHashEnumeratorItem(&enumer))) {
        WMArrayIterator i;
        Family *fam;
        char buffer[256];
        WMListItem *item;

        WM_ITERATE_ARRAY(array, fam, i) {
            strcpy(buffer, fam->name);
            item = WMAddListItem(panel->famLs, buffer);

            item->clientData = fam;
        }

        WMFreeArray(array);
    }

    WMSortListItems(panel->famLs);

    WMFreeHashTable(families);
}


static void
getSelectedFont(FontPanel *panel, char buffer[], int bufsize)
{
    WMListItem *item;
    Family *family;
    Typeface *face;
    char *size;


    item = WMGetListSelectedItem(panel->famLs);
    if (!item)
        return;
    family = (Family*)item->clientData;

    item = WMGetListSelectedItem(panel->typLs);
    if (!item)
        return;
    face = (Typeface*)item->clientData;

    size = WMGetTextFieldText(panel->sizT);

    snprintf(buffer, bufsize, "%s:style=%s:pixelsize=%s",
             family->name,
             face->typeface,
             size);

    wfree(size);
}



static void
preview(FontPanel *panel)
{
    char buffer[512];
    WMFont *font;

    getSelectedFont(panel, buffer, sizeof(buffer));
    font = WMCreateFont(WMWidgetScreen(panel->win), buffer);
    if (font) {
        WMSetTextFieldFont(panel->sampleT, font);
        WMReleaseFont(font);
    }
}



static void
familyClick(WMWidget *w, void *data)
{
    WMList *lPtr = (WMList*)w;
    WMListItem *item;
    Family *family;
    Typeface *face;
    FontPanel *panel = (FontPanel*)data;
    WMArrayIterator i;
    /* current typeface and size */
    char *oface = NULL;
    char *osize = NULL;
    int facei = -1;
    int sizei = -1;

    /* must try to keep the same typeface and size for the new family */
    item = WMGetListSelectedItem(panel->typLs);
    if (item)
        oface = wstrdup(item->text);

    osize = WMGetTextFieldText(panel->sizT);


    item = WMGetListSelectedItem(lPtr);
    family = (Family*)item->clientData;

    WMClearList(panel->typLs);


    WM_ITERATE_ARRAY(family->typefaces, face, i) {
        char buffer[256];
        int top=0;
        WMListItem *fitem;

        strcpy(buffer, face->typeface);
        if(strcasecmp(face->typeface, "Roman") == 0)
            top = 1;
        if(strcasecmp(face->typeface, "Regular") == 0)
            top = 1;
        if (top)
            fitem = WMInsertListItem(panel->typLs, 0, buffer);
        else
            fitem = WMAddListItem(panel->typLs, buffer);
        fitem->clientData = face;
    }

    if (oface) {
        facei = WMFindRowOfListItemWithTitle(panel->typLs, oface);
        wfree(oface);
    }
    if (facei < 0) {
        facei = 0;
    }
    WMSelectListItem(panel->typLs, facei);
    typefaceClick(panel->typLs, panel);

    if (osize) {
        sizei = WMFindRowOfListItemWithTitle(panel->sizLs, osize);
    }
    if (sizei >= 0) {
        WMSelectListItem(panel->sizLs, sizei);
        sizeClick(panel->sizLs, panel);
    }

    if (osize)
        wfree(osize);


    preview(panel);
}


static void
typefaceClick(WMWidget *w, void *data)
{
    FontPanel *panel = (FontPanel*)data;
    WMListItem *item;
    Typeface *face;
    WMArrayIterator i;
    char buffer[32];

    char *osize = NULL;
    int sizei = -1;
    void *size;

    osize = WMGetTextFieldText(panel->sizT);


    item = WMGetListSelectedItem(panel->typLs);
    face = (Typeface*)item->clientData;

    WMClearList(panel->sizLs);

    WM_ITERATE_ARRAY(face->sizes, size, i) {
        if ((int)size != 0) {
            sprintf(buffer, "%i", (int)size);

            WMAddListItem(panel->sizLs, buffer);
        }
    }

    if (osize) {
        sizei = WMFindRowOfListItemWithTitle(panel->sizLs, osize);
    }
    if (sizei < 0) {
        sizei = WMFindRowOfListItemWithTitle(panel->sizLs, "12");
    }
    if (sizei < 0) {
        sizei = 0;
    }
    WMSelectListItem(panel->sizLs, sizei);
    WMSetListPosition(panel->sizLs, sizei);
    sizeClick(panel->sizLs, panel);

    if (osize)
        wfree(osize);

    preview(panel);
}

static void
sizeClick(WMWidget *w, void *data)
{
    FontPanel *panel = (FontPanel*)data;
    WMListItem *item;

    item = WMGetListSelectedItem(panel->sizLs);
    WMSetTextFieldText(panel->sizT, item->text);

    WMSelectTextFieldRange(panel->sizT, wmkrange(0, strlen(item->text)));

    preview(panel);
}


static void
setFontPanelFontName(FontPanel *panel, FcChar8 *family, FcChar8 *style, double size)
{
    int famrow;
    int stlrow;
    int sz;
    char asize[64];
    void *vsize;
    WMListItem *item;
    Family *fam;
    Typeface *face;
    WMArrayIterator i;

    famrow = WMFindRowOfListItemWithTitle(panel->famLs, family);
    if (famrow < 0 ){
        famrow = 0;
        return;
    }
    WMSelectListItem(panel->famLs, famrow);
    WMSetListPosition(panel->famLs, famrow);

    WMClearList(panel->typLs);

    item = WMGetListSelectedItem(panel->famLs);

    fam = (Family*)item->clientData;
    WM_ITERATE_ARRAY(fam->typefaces, face, i) {
        char buffer[256];
        int top=0;
        WMListItem *fitem;

        strcpy(buffer, face->typeface);
        if(strcasecmp(face->typeface, "Roman") == 0)
            top = 1;
        if (top)
            fitem = WMInsertListItem(panel->typLs, 0, buffer);
        else
            fitem = WMAddListItem(panel->typLs, buffer);
        fitem->clientData = face;
    }


    stlrow = WMFindRowOfListItemWithTitle(panel->typLs, style);

    if (stlrow < 0) {
        stlrow = 0;
        return;
    }

    WMSelectListItem(panel->typLs, stlrow);

    item = WMGetListSelectedItem(panel->typLs);

    face = (Typeface*)item->clientData;

    WMClearList(panel->sizLs);


    WM_ITERATE_ARRAY(face->sizes, vsize, i) {
        char buffer[32];
        if ((int)vsize != 0) {
            sprintf(buffer, "%i", (int)vsize);

            WMAddListItem(panel->sizLs, buffer);
        }
    }

    snprintf(asize, sizeof(asize)-1, "%d",(int)(size+0.5));

    sz = WMFindRowOfListItemWithTitle(panel->sizLs, asize);

    if (sz < 0) {
        sz = 4;
        return;
    }

    WMSelectListItem(panel->sizLs, sz);
    sizeClick(panel->sizLs, panel);

    return;
}




syntax highlighted by Code2HTML, v. 0.9.1