#!/bin/sh
if [ $# -ne 1 ]; then
	echo "Wrong # of args arg1 = widget name"
	exit
fi

widgetName=$1
WidgetName=$1

if [ -d $widgetName ]; then
	echo $widgetName exists.......
	exit
fi

mkdir $widgetName
cd $widgetName


# ------------------------------------------------------ #
cat > Makefile < ${widgetName}.c <

int ${WidgetName}Cmd(ClientData clientData, Tcl_Interp *interp,
		int argc, char *argv[]) {
	Tk_Window main = (Tk_Window) clientData;
	${WidgetName} *${widgetName}Ptr;
	Tk_Window tkwin;

	if (argc < 2) {
		Tcl_AppendResult(interp, "wrong # args: should be \"",
				argv[0], " pathName ?options?\"", (char *) NULL);
		return TCL_ERROR;
	}

	tkwin = Tk_CreateWindowFromPath(interp, main, argv[1],
			(char *) NULL);
	if (tkwin == NULL) {
		return TCL_ERROR;
	}
	Tk_SetClass(tkwin, "${WidgetName}");

	${widgetName}Ptr = (${WidgetName} *) malloc(sizeof(${WidgetName}));
	${widgetName}Ptr->tkwin = tkwin;
	${widgetName}Ptr->display = Tk_Display(tkwin);
	${widgetName}Ptr->interp = interp;
	${widgetName}Ptr->itself = ${widgetName}Ptr;
	${widgetName}Ptr->name = (char *) strdup(argv[1]);

	Tk_CreateEventHandler(tkwin,
			ExposureMask|StructureNotifyMask, ${WidgetName}EventProc,
			(ClientData) ${widgetName}Ptr);
	Tcl_CreateCommand(interp, Tk_PathName(tkwin), 
		${WidgetName}WidgetCmd, (ClientData) ${widgetName}Ptr,
		(Tcl_CmdDeleteProc *) NULL);

	if (${WidgetName}Configure(interp, ${widgetName}Ptr, argc-2, argv+2, 0)
			!= TCL_OK) {
		Tk_DestroyWindow(${widgetName}Ptr->tkwin);
		return TCL_ERROR;
	}
	interp->result = Tk_PathName(tkwin);
	return TCL_OK;
}


void ${WidgetName}Destroy(ClientData clientData) {
	${WidgetName} *${widgetName}Ptr = (${WidgetName} *) clientData;
	Tk_FreeOptions(${WidgetName}ConfigSpecs, (char *) ${widgetName}Ptr,
			${widgetName}Ptr->display, 0);

	free(${widgetName}Ptr->name);
	free((char *) ${widgetName}Ptr);
}


int ${WidgetName}_Init(Tcl_Interp *interp){
  Tcl_CreateCommand(interp,"`echo ${WidgetName} | tr "[A-Z]" "[a-z]"`",
		     ${widgetName}Cmd,
		    (ClientData) Tk_MainWindow(interp),
		    (Tcl_CmdDeleteProc *) NULL);
  return TCL_OK;
}






END_OF_FILE

# ------------------------------------------------------ #

cat > ${widgetName}.h <
#include 
#include 
#include 
#include 

typedef struct {
        /* dont change order till Tcl_Interp */
	void     *itself;
	char     *name;

	Tk_Window tkwin;
	Display *display;
	Tcl_Interp *interp;
        int        updatePending;

} ${WidgetName};


extern Tk_ConfigSpec ${WidgetName}ConfigSpecs[];

int ${WidgetName}Cmd(ClientData clientData, Tcl_Interp *interp,
		int argc, char *argv[]);

void ${WidgetName}Destroy(ClientData clientData) ;

int ${WidgetName}_Init(Tcl_Interp *interp);


int ${WidgetName}WidgetCmd(ClientData clientData, Tcl_Interp *interp,
		int argc, char *argv[]);


void ${WidgetName}Display(ClientData clientData) ;
  

void ${WidgetName}EventProc(ClientData clientData, XEvent *eventPtr);


void ${WidgetName}EventProc(ClientData clientData, XEvent *eventPtr);



#endif
END_OF_FILE

# ------------------------------------------------------ #

cat > ${widgetName}Config.c <

Tk_ConfigSpec ${WidgetName}ConfigSpecs[] = {
  {TK_CONFIG_SYNONYM, "-bd", "borderWidth", (char *) NULL,
     (char *) NULL, 0, 0, (Tk_CustomOption *) NULL},

  {TK_CONFIG_SYNONYM, "-bg", "background", (char *) NULL,
     (char *) NULL, 0, 0, (Tk_CustomOption *) NULL},

  {TK_CONFIG_SYNONYM, "-fg", "foreground", (char *) NULL,
     (char *) NULL, 0, 0, (Tk_CustomOption *) NULL},

  {TK_CONFIG_END, (char *) NULL, (char *) NULL,
     (char *) NULL, (char *) NULL, 0, 0,
     (Tk_CustomOption *) NULL}
};


int ${WidgetName}Configure(Tcl_Interp *interp, ${WidgetName} *${widgetName}Ptr,
		int argc, char *argv[], int flags) {
	if (Tk_ConfigureWidget(interp, ${widgetName}Ptr->tkwin, ${WidgetName}ConfigSpecs,
			argc, argv, (char *) ${widgetName}Ptr, flags) != TCL_OK) {
		return TCL_ERROR;
	}

	return TCL_OK;
}

END_OF_FILE


# ------------------------------------------------------ #

cat > ${widgetName}Display.c <


void ${WidgetName}Display(ClientData clientData) {
	${WidgetName} *${widgetName}Ptr = (${WidgetName} *) clientData;
	Tk_Window tkwin = ${widgetName}Ptr->tkwin;
	Display *display = Tk_Display(tkwin);
	${widgetName}Ptr->updatePending = 0;
	if (!Tk_IsMapped(tkwin)) {
		return;
	}
}

END_OF_FILE

# ------------------------------------------------------ #

cat >${widgetName}Event.c <

void ${WidgetName}EventProc(ClientData clientData, XEvent *eventPtr) {
	${WidgetName} *${widgetName}Ptr = (${WidgetName} *) clientData;
	if (eventPtr->type == Expose) {
	} else if (eventPtr->type == ConfigureNotify) {
	} else if (eventPtr->type == DestroyNotify) {
		Tcl_DeleteCommand(${widgetName}Ptr->interp,
				Tk_PathName(${widgetName}Ptr->tkwin));
		${widgetName}Ptr->tkwin = NULL;
		Tk_EventuallyFree((ClientData) ${widgetName}Ptr, ${WidgetName}Destroy);
	}
}

END_OF_FILE

# ------------------------------------------------------ #

cat > ${widgetName}Widget.c <

int ${WidgetName}WidgetCmd(ClientData clientData, Tcl_Interp *interp,
		    int argc, char *argv[]) {
  ${WidgetName} *${widgetName}Ptr = (${WidgetName} *) clientData;
  int result = TCL_OK;
  
  if (argc < 2) {
    Tcl_AppendResult(interp, "wrong # args: should be \"",
		     argv[0], " option ?arg arg ...?\"",
		     (char *) NULL);
    return TCL_ERROR;
  }
  
  Tk_Preserve((ClientData) ${widgetName}Ptr);
  if (strcmp(argv[1], "configure") == 0) {
    if (argc == 2) {
      result = Tk_ConfigureInfo(interp, ${widgetName}Ptr->tkwin,
		     ${WidgetName}ConfigSpecs, (char *) ${widgetName}Ptr, (char *) NULL, 0);
    } else if (argc == 3) {
      result = Tk_ConfigureInfo(interp, ${widgetName}Ptr->tkwin,
		       	${WidgetName}ConfigSpecs, (char *) ${widgetName}Ptr, argv[2], 0);
    } else {
      result = ${WidgetName}Configure(interp, ${widgetName}Ptr, argc-2,
				       argv+2, TK_CONFIG_ARGV_ONLY);
    }	
   } else if (! strcmp(argv[1],"itself")) {
       sprintf(interp->result,"%d",(int)${widgetName}Ptr->itself);
   } else if (! strcmp(argv[1],"type")) {
       interp->result="${widgetName}";
   } else {
    Tcl_AppendResult(interp, "bad option \"", argv[1],
		     "\": must be configure, position, or size",
		     (char *) NULL);
    goto error;
  }

  Tk_Release((ClientData) ${widgetName}Ptr);
  return result;
  
 error:
  Tk_Release((ClientData) ${widgetName}Ptr);
  return TCL_ERROR;
}

END_OF_FILE

# ------------------------------------------------------ #

cat > tclAppInit.c <
#include 

int Tcl_AppInit(Tcl_Interp *interp) {
  if (Tcl_Init(interp) == TCL_ERROR)
    return TCL_ERROR;
  if (${WidgetName}_Init(interp) == TCL_ERROR)
    return TCL_ERROR;
}
END_OF_FILE

make 
etags *.[ch]
cd ..