#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#if defined(lint) && defined(HAVE_NOTE_H)
#include <note.h>
#endif /* lint && HAVE_NOTE_H */

#include <iiimp-data.h>

#include "iiimp-dataP.h"

HOTKEY_LIST *
iiimp_hotkey_list_new(
    IIIMP_data_s *	data_s,
    int			count,
    HOTKEY *	        hk)
{
    HOTKEY_LIST *               data;
    size_t                      nbyte = 0;
    int                         i;

    data = (HOTKEY_LIST *) malloc(sizeof (HOTKEY_LIST));
    if (NULL == data) {
	data_s->status = IIIMP_DATA_MALLOC_ERROR;
	return NULL;
    }

    for(i=0 ; i < count ; i++){
	nbyte += (4 +                  // size of HOTKEYCTL
		  4 +                  // size of N:length of HOTKEY keyevent
		  hk[i].hotkeylist->nbyte +
		  hk[i].label->nbyte ) ;
    }

    data->nbyte = nbyte ;
    data->count = count;

    if (0 == data) {
	data->hotkey = NULL;
    } else {
	data->hotkey = (HOTKEY *)malloc(nbyte);
	if (NULL == data->hotkey) {
	    return NULL;
	}
    }
                                                                                
    if (NULL != hk) {
	for (i=0 ; i < count ; i++) {
	    data->hotkey[i].hotkeyctrl = hk[i].hotkeyctrl ;
	    data->hotkey[i].nbyte = hk[i].hotkeylist->nbyte ;
	    data->hotkey[i].hotkeylist = hk[i].hotkeylist;
	    data->hotkey[i].label = hk[i].label;
	}
    }

    return data;
}

void
iiimp_hotkey_list_pack(
    IIIMP_data_s *		data_s,
    HOTKEY_LIST  *	        m,
    size_t *			nbyte,
    uchar_t **			ptr)
{
    size_t	rest;
    uchar_t *	p;
    int         i;

    rest = *nbyte;
    p = *ptr;

    for (i = 0; i < m->count; i++) {
	PUTU16(m->hotkey[i].hotkeyctrl.hotkey_id, rest, p, data_s->byte_swap);
	PUTU8(m->hotkey[i].hotkeyctrl.state_flag, rest, p, data_s->byte_swap);
	PUTU8(m->hotkey[i].hotkeyctrl.action_flag, rest, p, data_s->byte_swap);
	PUTU32(m->hotkey[i].nbyte, rest, p, data_s->byte_swap);
	iiimp_keyevent_list_pack(data_s, m->hotkey[i].hotkeylist, &rest, &p);
	iiimp_string_pack(data_s, m->hotkey[i].label, &rest, &p);
    }

    *nbyte = rest;
    *ptr = p;

    return;
}

void
iiimp_hotkey_list_delete(IIIMP_data_s * data_s, HOTKEY_LIST * m)
{
    int i;
    if (NULL == m) return;

    for (i = 0; i < m->count; i++) {
	iiimp_keyevent_list_delete(data_s, m->hotkey[i].hotkeylist);
	iiimp_string_delete(data_s, m->hotkey[i].label);
    }
    if (m->hotkey) free (m->hotkey);
    free(m);
}

HOTKEY_LIST *
iiimp_hotkey_list_unpack(
    IIIMP_data_s *	data_s,
    size_t *		nbyte,
    const uchar_t **	ptr,
    size_t		nbyte_max)
{
    HOTKEY_LIST *       data;
    HOTKEY *            hk;
    int                 count = 0;
    int                 len;
    size_t		rest;
    const uchar_t *	p;
  
    hk = NULL;

    rest = nbyte_max;
    p = *ptr;

    if ((*nbyte < rest) || (rest < 4)) {
	data_s->status = IIIMP_DATA_INVALID;
	return NULL;
    }

    data = (HOTKEY_LIST *)malloc(nbyte_max);
    if (NULL == data) {
	data_s->status = IIIMP_DATA_MALLOC_ERROR;
	return NULL;
    }
    data->nbyte = nbyte_max;
    data->hotkey = NULL;

    while (0 < rest) {
	if (!data->hotkey)
	    data->hotkey = (HOTKEY *)malloc(sizeof(HOTKEY));
	else
	    data->hotkey = (HOTKEY *)realloc((HOTKEY *)data->hotkey,(count+1) * sizeof(HOTKEY));
	if (NULL == data->hotkey) {
	    data_s->status = IIIMP_DATA_MALLOC_ERROR;
	    return NULL;
	}
	GETU16(data->hotkey[count].hotkeyctrl.hotkey_id, rest, p, data_s->byte_swap);
	GETU8(data->hotkey[count].hotkeyctrl.state_flag, rest, p, data_s->byte_swap);
	GETU8(data->hotkey[count].hotkeyctrl.action_flag, rest, p, data_s->byte_swap);
	GETU32(len, rest, p, data_s->byte_swap);
	data->hotkey[count].nbyte = len;
	data->hotkey[count].hotkeylist = iiimp_keyevent_list_unpack(data_s, &rest, &p, len);
	if (NULL == data->hotkey[count].hotkeylist) {
	    free(data->hotkey);
	    return NULL;
	}
	data->hotkey[count].label = iiimp_string_unpack(data_s, &rest, &p, rest);
	count++;
    }
    data->count = count;

    *nbyte -= (nbyte_max - rest);
    *ptr += nbyte_max; 

    return data;
}

void
iiimp_hotkey_list_print(
    IIIMP_data_s *     data_s,
    HOTKEY_LIST *      m)
{
    int i;

    if (NULL == m) return;

    for (i = 0; i < m->count; i++) {
	(void)fprintf(data_s->print_fp, "\tHOTKEY ID = ");
	(void)fprintf(data_s->print_fp, "(%d)\n", m->hotkey[i].hotkeyctrl.hotkey_id);
	(void)fprintf(data_s->print_fp, "\tSTATE FLAG = ");
	(void)fprintf(data_s->print_fp, "(%d)\n", m->hotkey[i].hotkeyctrl.state_flag);
	(void)fputc('\n', data_s->print_fp);
	(void)fprintf(data_s->print_fp, "\tACTION FLAG = ");
	(void)fprintf(data_s->print_fp, "(%d)\n", m->hotkey[i].hotkeyctrl.action_flag);
	(void)fputc('\n', data_s->print_fp);
	(void)fprintf(data_s->print_fp, "\tHOTKEY List = \n");
	iiimp_keyevent_list_print(data_s, m->hotkey[i].hotkeylist);
	(void)fprintf(data_s->print_fp, "\tText Label = ");
	iiimp_string_print(data_s, m->hotkey[i].label);
	(void)fputc('\n', data_s->print_fp);
    }
}


/* Local Variables: */
/* c-file-style: "iiim-project" */
/* End: */
