static Boole
Print_ILV_Header(FILE * ilv_file,
                 char * file_name,
                 char * block_name,
                 int num_ui,
                 int num_gui)
{
    char time_str[MAX_STR] = "";
    time_t now;
    struct tm *stm;
    
    int num_inputs;
    int num_objects;
    int frame_size;
    
    num_inputs = num_ui + num_gui;
    num_objects = num_ui + 2 * num_gui + 1 /* frame */ + 3 /* buttons */;
    frame_size = ( num_inputs * SEPARATION ) + FRAME_SIZE_OFFSET;
    
    time(&now);
    stm = localtime((time_t *)&now);
    strftime(time_str, 1000, "%y%m%d%H%M", stm);
    
    fprintf(ilv_file,"// Ilv Version: 3.1\n");
    fprintf(ilv_file,"// File generated: %s\n", time_str);
    fprintf(ilv_file,"// Creator class: IlvGadgetManagerOutput\n");
    fprintf(ilv_file,"FileName \"%s\"\n", file_name);
    fprintf(ilv_file,"PathName \"%s\"\n", file_name);
    fprintf(ilv_file,"Palettes 3\n");
    fprintf(ilv_file,"0 \"wheat\" \"black\" \"button\" \"%%helvetica-12-B\" 0 solid solid 0 0 0\n");
    fprintf(ilv_file,"\"IlvStText\" 1 \"wheat\" \"black\" \"normal\" \"%%helvetica-12-\" 0 solid solid 0 0 0\n");
    fprintf(ilv_file,"2 \"Wheat\" 0 0 0 \"normal\" \"%%helvetica-12-\" 0 solid solid 0 0 0");
    fprintf(ilv_file,"IlvObjects %d\n", num_objects);
    fprintf(ilv_file,"1 { 0 0 IlvFrame %d %d %d %d F8 0 25 16 4 \"%s\"   } 0\n",
            FRAME_LOCATION_X,
            FRAME_LOCATION_Y,
            FRAME_WIDTH,
            frame_size,
            block_name);
    fprintf(ilv_file,"0\n");

    return(TRUE);
}


/* ****************************************************************** * 
 * Function        : Print_ILV_Tail
 * 
 * Description     : 
 * 
 * Arguments       :   
 *                     ,
 *                     ,
 * 
 * Returns         :  
 * 
 * Modifies        :  
 * 
 * ******************************************************************* */
static Boole
Print_ILV_Tail(FILE * ilv_file,
               char * file_name,
               char * block_name,
               int num_ui,
               int num_gui)
{
    int num_objects;
    int num_inputs;
    int max_y_size;
    int frame_size;
    int ok_button_pos;
    int cancel_button_pos;
    int help_button_pos;
    int button_line;

    num_inputs = num_ui + num_gui;
    num_objects = num_ui + 2* num_gui + 1 /* frame */ + 3 /* buttons */;
    frame_size = ( num_inputs * SEPARATION ) + FRAME_SIZE_OFFSET;
    button_line = frame_size + FRAME_LOCATION_Y + BUTTON_BORDER;
    max_y_size = button_line + BUTTON_HEIGHT + BUTTON_BORDER;

    ok_button_pos = num_objects - 3;
    cancel_button_pos = num_objects - 2;
    help_button_pos = num_objects - 1;

    fprintf(ilv_file,"1 { %d 0 IlvButton %d %d %d %d F9 2 1 16 4 \"OK\"   } 512\n",
            ok_button_pos,
            OK_LOCATION_X,
            button_line,
            BUTTON_WIDTH,
            BUTTON_HEIGHT);
    fprintf(ilv_file,"1\n");
    fprintf(ilv_file,"1 \"__ilvCallback\" \"ok\"\n");
    fprintf(ilv_file,"0\n");
    fprintf(ilv_file,"1 { %d 0 IlvButton %d %d %d %d F9 2 1 16 4 \"Cancel\"   } 512\n",
            cancel_button_pos,
            CANCEL_LOCATION_X,
            button_line,
            BUTTON_WIDTH,
            BUTTON_HEIGHT);
    fprintf(ilv_file,"1\n");
    fprintf(ilv_file,"1 \"__ilvCallback\" \"cancel\"\n");
    fprintf(ilv_file,"0\n");
    fprintf(ilv_file,"1 { %d 0 IlvButton %d %d %d %d F9 2 1 16 4 \"Help\"   } 512\n",
            help_button_pos,
            HELP_LOCATION_X,
            button_line,
            BUTTON_WIDTH,
            BUTTON_HEIGHT);
    fprintf(ilv_file,"1\n");
    fprintf(ilv_file,"1 \"__ilvCallback\" \"help\"\n");
    
    fprintf(ilv_file,"0\n");
    fprintf(ilv_file,"Size %d %d\n",
            DIALOG_WIDTH,
            max_y_size);
    fprintf(ilv_file,"Background \"wheat\"\n");
    fprintf(ilv_file,"EOF\n");

    return(TRUE);
}

/* ****************************************************************** * 
 * Function        : Print_ILV_ui
 * 
 * Description     : 
 * 
 * Arguments       :   
 *                     ,
 *                     ,
 * 
 * Returns         :  
 * 
 * Modifies        :  
 * 
 * ******************************************************************* */


static Boole
Print_ILV_ui(FILE * ilv_file,
             int level,
             char * label_txt)
{
    int  box_start, label_level, field_level;
    
    box_start = (level - 1) * SEPARATION + FIRST;
    label_level = level * 2 - 1;
    field_level = level * 2;

    fprintf(ilv_file,"1 { %d 1 IlvMessageLabel %d %d %d %d F8 0 9 16 4 \"%s:\" } 0\n",
           label_level,
           LABEL_LOCATION_X,
           box_start,
           LABEL_WIDTH,
           FIELD_HEIGHT,
           label_txt);
    
    fprintf(ilv_file,"0\n");
    
    return(0);
    
}

/* ****************************************************************** * 
 * Function        : Print_ILV_gui
 * 
 * Description     : 
 * 
 * Arguments       :   
 *                     ,
 *                     ,
 * 
 * Returns         :  
 * 
 * Modifies        :  
 * 
 * ******************************************************************* */

static Boole
Print_ILV_gui(FILE * ilv_file,
              int level,
              char * label_txt,
              char * field_label,
              DxNmsFieldType_e  field_type,
              char * default_string,
              const struct enumeraldescriptor * enumlist,
              int num_enums)
{
    int box_start, label_level, field_level;

    box_start = (level - 1) * SEPARATION + FIRST;
    label_level = level * 2 - 1;
    field_level = level * 2;

    fprintf(ilv_file,"1 { %d 1 IlvMessageLabel %d %d %d %d F8 0 9 16 4 \"%s:\" } 0\n",
           label_level,
           LABEL_LOCATION_X,
           box_start,
           LABEL_WIDTH,
           FIELD_HEIGHT,
           label_txt);
    
    fprintf(ilv_file,"0\n");
    
    fprintf(ilv_file,"1 { %d 2 %s %d %d %d %d", 
            field_level,
            DxNMSFieldTypeToIlvType(field_type),
            FIELD_LOCATION_X,
            box_start,
            FIELD_WIDTH,
            FIELD_HEIGHT);
    
    switch(field_type)
    {
    case FieldString:
        fprintf(ilv_file," F6 2  1 -1 0 \"%s\" } 32 \"%s\"\n",
                default_string,
                field_label);

        break;

    case FieldInt:
        fprintf(ilv_file," F6 2 2 -1 0 \"%s\" . , 2 0 -2147483648 2147483647 }  32 \"%s\"\n",
                default_string,
                field_label);
        
        break;
    case FieldEnum:
    {
        char * cur_enum;
        int i = 0;

        cur_enum = enumlist[0].enumstring;
        
        fprintf(ilv_file," F807 2  \"%s\" %d ",
                cur_enum,
                num_enums);
        for(i = 0; i < num_enums; i++)
        {
            cur_enum = enumlist[i].enumstring;
            fprintf(ilv_file,"\nIlvGadgetItem 1 2 4 \"%s\"",
                    cur_enum);
        }
        
        fprintf(ilv_file," 4 0 } 32 \"%s\"\n",
                field_label);
        break;
    }
    default:
        
    }
    fprintf(ilv_file,"0\n");
    
    /*    fprintf(ilv_file,"6144 \"host1\" \"protocol\"\n");*/
    return(0);
    
}

/*-------------------------------------------------------------------------
 *
 * Function:    shortName
 *
 * Description: Removes the typically common header between table name
 *              and attribute. If there is nothing left, then output
 *              the full name!
 *
 * Arguments:   Attribute name
 *
 * Returns:     char * Pointer to base attribute name' (in static memory)
 *
 * Modifies:    Reads CurrMOC
 *
 *------------------------------------------------------------------------*/

static char *
shortName(char	*a, char * mp /* current entry name */)
{
#define STRIP_TYPE "entry"
    
    static char	buf[500];
    int		ip = 0;	/* in pointer */
    int		op = 0;	/* out pointer */

    
    memset(buf, 0, sizeof(buf));
    
    if(a)
    {
        if (mp)
        {
            /*
             * see if the MOC is of type "Entry"
             * if so then find the leading part (up to entry)
             * and strip this part wholy off the begining of the attribute.
             * if this does not match, then use the full attribute.
             *
             * if not entry type, then do previous processing
             */
            int entry_pos = strlen(mp) - strlen(STRIP_TYPE);
            if ( 0 == strcasecmp(&mp[entry_pos], STRIP_TYPE))
            {
                /* matched entry part - so now can we match at begining
                 * of the attribute name?
                 */
                if (0 == strncasecmp(mp,a,entry_pos))
                {
                    /* matched
                    * must start ip at entry pos*/
                    ip = entry_pos;
                }
            }
            else
            {
                /* not entry type - so use old matching */
                for(ip = 0; toupper(a[ip]) == toupper(*mp); ip++, mp++) {
                }
            }
            
        }
        /* copy remainder of attribute name to output */
        for(op = 0; a[ip]; ip++, op++) {
            buf[op] = a[ip];
        }
        if (0 == strlen(buf))
        {
            /*
             * the input name was totally consumed,
             * we shall just output what was input
             */
            strcpy(buf,a);
        }
        
    }
    return (buf);
}

static struct MOs *
lookup_table(const char* identifier)
{
    int index;
   

    /* Search the mos[] (from the ".X" file) of the
       MibMaster generated code for a matching table entry name. */

    if ( (NULL == identifier))
    {

        return(NULL);
    }
    
    for (index = 0; mos[index].name; index++)
    {
        if (strcasecmp(mos[index].name, identifier) == 0)
        {
            return( &mos[index]);
            break;
        }
    }
   
    
    return(NULL);
}
static void
list_tables(void)
{
     int index;
   

    
    for (index = 0; mos[index].name; index++)
    {
       printf("\t%s\n",mos[index].name);
       
    }
   
    

}
/*----------------------------------------------------------------*/
static Boole
IsIndex(struct MOs* table_entry_mo,
        int id)
{
    int i;

    for (i = 0; i < table_entry_mo->no_indexes; i++)
    {
        if (id == table_entry_mo->indexes[i])
        {
            return(TRUE);
        }
    }
    return(FALSE);
}


int
CountNumGui(struct MOs * table)
{
    int i;
    int num_gui = 0;
    
    for (i = 0; TRUE; i ++)
    {
        MOField* ptr = NULL;
        ptr = &table->list[i];

        if (NULL == ptr->label)
        {
            break;
        }


        if (MOFrw == ptr->editable)
        {
            num_gui ++;
        }
    }
    return(num_gui);
}
int
CountNumUi(struct MOs * table)
{
    int i;
    int num_ui = 0;
    
    for (i = 0; TRUE; i ++)
    {
        MOField* ptr = NULL;
        ptr = &table->list[i];

        if (NULL == ptr->label)
        {
            break;
        }

        if ( (MOFrw != ptr->editable)
             && (IsIndex(table, i)))
        {
            
            num_ui ++;
        }
    }
    return(num_ui);
}


        
int
main(int argc, char ** argv)
{

    struct MOs * table;

    int i;

    int level = 1;
    
    int num_gui;
    int num_ui;
    FILE * ilv_file = stdout;
    
    int c;

    char * table_name = "";
    char * display_name = "";
    char * title = "No Title";

    while ((c = getopt(argc, argv, "e:E:t:T:f:i:s:n:o:p:d:l:IARNWLh")) != EOF)
    {
        
        switch (c)
        {
        case 'd':
            /* debugging */
            citr_trace_flag = strtol(optarg,NULL,0);
            break;

        case 't':
            /* table name */
            table_name = optarg;
            break;
            
        case 'T':
            /* title */
            title = optarg;
            break;
            
        case 'n':
            /* Display name */
            display_name = optarg;
            break;
            
        case 'h':
            fprintf(stderr,"Known tables \n");
            
            list_tables();
            /* fall thru */
        default:
            fprintf(stderr,"%s:%d: main usage:\n%s  \n\t"
                    " table name t \n\t"
                    " title T \n\t"
                    " debug d \n\t"
                    " help h"
                    ,
                    __FILE__,__LINE__,
                    argv[0]);
            exit(1);
            

        }
    }
    
    
    table = lookup_table(table_name);
    if (NULL == table)
    {
        fprintf(stderr,"%s:%d: main did not find %s \n",
                __FILE__,__LINE__,
                table_name);
        list_tables();
        
        exit(1);
    }
    num_gui = CountNumGui(table);
    num_ui = CountNumUi(table);


    /* need to
     * 1. Calculate the number of GUI and UI (ro rw) fields
     * 2. Print header
     * 3. print attributes
     * 4. print trailer
    
     */

    Print_ILV_Header(ilv_file,
                     display_name,
                     title,
                     num_ui,
                     num_gui);
    
    /* print each attribute */
    for (i = 0; TRUE; i ++)
    {
        MOField* ptr = NULL;
        ptr = &table->list[i];

        if (NULL == ptr->label)
        {
            break;
        }


        if ( (MOFrw != ptr->editable)
             && (IsIndex(table, i)))
        {
            /* read only index field - UI */
             Print_ILV_ui(ilv_file,
                          level,
                          shortName(ptr->label,table->name));
             
             level ++;
             
        }
        
            
        if (MOFrw == ptr->editable)
        {
            /* editable field - so part of the gui */
         
            /* determine current format */
            switch (ptr->type)
            {
            case MOFenumeral:                /* Attribute value is a enum type */
            {
                const struct enumeraldescriptor * enumlist;
                int enum_pos;

                
                enumlist = ptr->enumlist;
                /* enum */
                for (enum_pos = 0;
                     enumlist[enum_pos].enumstring != NULL;
                     ++enum_pos)
                {
                    /* just count */
                }
                Print_ILV_gui(ilv_file,
                              level,
                              shortName(ptr->label,table->name),
                              shortName(ptr->label,table->name),
                              FieldEnum,
                              "",
                              enumlist,
                              enum_pos);
             
            }
             break;
         
            case MOFinteger:                 /* Attribute value is an integer */
            case MOFcounter:                 /* RFC1155 Counter - value is integer */
            case MOFgauge:                   /* Gauge - value is integer */
            case MOFtimeticks:               /* TimeTicks - value is integer */
                Print_ILV_gui(ilv_file,
                              level,
                              shortName(ptr->label,table->name),
                              shortName(ptr->label,table->name),
                              FieldInt,
                              "",
                              NULL,
                              0);

                break;
            
            case MOFipaddress:               /* an internet IP address */

            case MOFstring_fixed:            /* Attribute value is a string */
            case MOFstring:                  /* string of variable length */
        
    
            case MOFnetworkaddress:	    	    	/* An internet NetworkAddress */
            case MOFe164address:             /* Attrib value is an E.164 address */
            case MOFmacaddress:              /* Attribute value is a MAC address */
            case MOFphysaddress_fixed:       /* Attrib value is a binary string */
            case MOFphysaddress:             /* variable length binary string */

            case MOFcmotsystemid:            /* a CMOTSystemID */
                /* strings */
            case MOFobjectid:
                /* oid */
                Print_ILV_gui(ilv_file,
                              level,
                              shortName(ptr->label,table->name),
                              shortName(ptr->label,table->name),
                              FieldString,
                              "",
                              NULL,
                              0);
                break;
            
            
            default:

            }

            level ++;
            
        }
    }
    Print_ILV_Tail(ilv_file,
                   display_name,
                   title,
                   num_ui,
                   num_gui);
    

        
    return(0);
    
}