#include <tcl.h>

static Tcl_ObjCmdProc Parse_Cmd;
static Tcl_ArgvGenFuncProc ParseMedia;

static int
Parse_Cmd(
    ClientData clientData,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const objv[])
{
    Tcl_Size count;

    const char *media = NULL, *color = NULL;

    const Tcl_ArgvInfo argTable[] = {
	{TCL_ARGV_STRING,  "-colormode" ,  NULL, &color,  "color mode", NULL},
	{TCL_ARGV_GENFUNC, "-media", ParseMedia, &media,  "media page size", NULL},
	TCL_ARGV_TABLE_END
    };

    if (objc%2 != 1) {
	Tcl_WrongNumArgs(interp, 1, objv, "?-opt arg ...?");
	return TCL_ERROR;
    }

    count = objc;

    if (Tcl_ParseArgsObjv(interp, argTable, &count, objv, NULL)!=TCL_OK) {
	return TCL_ERROR;
    }

    /* show color and media parsed values */
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("Color: |%d|%s|, Media: |%d|%s|",
	color?1:0, color?color:"NO COLOR",
	media?1:0, media?media:"NO MEDIA"
    ));

    return TCL_OK;
}

static int
ParseMedia(
    ClientData clientData,
    Tcl_Interp *interp,
    int objc,
    Tcl_Obj *const *objv,
    void *dstPtr)
{
    static const char *const mediaOpts[] = {"A4", "Legal", "Letter", NULL};
    static const char *const ExtendedMediaOpts[] = {
	"Paper size is ISO A4", "Paper size is US Legal",
	"Paper size is US Letter", NULL};
    int index;
    const char **media = (const char **) dstPtr;

    if (Tcl_GetIndexFromObjStruct(interp, objv[0], mediaOpts,
	    sizeof(char *), "media", 0, &index) != TCL_OK) {
	return -1;
    }

    *media = ExtendedMediaOpts[index];
    return 1;
}

int DLLEXPORT
Parse_Init(Tcl_Interp *interp)
{
    if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL) {
	return TCL_ERROR;
    }

    Tcl_CreateObjCommand(interp, "parse", Parse_Cmd, NULL, NULL);
    return TCL_OK;
}
