/*
 *   MediaMVP Server
 *
 *   (C) 2004 Dominic Morris
 *
 *   $Id: menulive.c,v 1.2 2004/08/30 08:55:24 ravelox Exp $
 *   $Date: 2004/08/30 08:55:24 $
 *
 *
 *   Implements the skeleton application
 * 
 */

#include "mvpwindow.h"




typedef struct {
    dongle_t     *dongle;


    window_t     *root;
    window_t     *sub;

} program_t;;

mvpinit_t          init = MVPINIT_INITIALISER;

static int         c_gui_width       = 640;   
static int         c_gui_depth       = 480;   
static int         c_screen_width    = 720;   
static int         c_screen_depth    = 576;  

static int      program_open(dongle_t *dongle, application_t *application);
static void     program_close(application_t *application);
static uint8_t *program_get_surface(application_t *application, int *size);
static void     program_keypress(application_t *application, int keycode);
static void     program_ack(application_t *application, int ackcode, unsigned char *buf, int buflen);
static int      program_authorise(char *mac_address, uint32_t ipaddr, int connected);


void menu_focus_event(window_t *window, event_t event, void *cb_ptr, void *param)
{
	fprintf(stderr, "WINDOW [%s] Focus Event [%d]\n", window_get_name(window), event);
}

void menu_highlight_event(window_t *window, event_t event, void *cb_ptr, void *param)
{
	fprintf(stderr, "WINDOW [%s] Highlight Event [%d]\n", window_get_name(window), event);
}

void menu1_select_event(window_t *window, event_t event, void *cb_ptr, void *param) {
	fprintf(stderr, "Menu 1: Item %d selected\n", *(int *)param);
}

void menu2_select_event(window_t *window, event_t event, void *cb_ptr, void *param) {
	fprintf(stderr, "Menu 2: Item %d selected\n", *(int *)param);
}

void menu3_select_event(window_t *window, event_t event, void *cb_ptr, void *param) {
	fprintf(stderr, "Menu 3: Item %d selected\n", *(int *)param);
}

void program_init(mvpinit_t *init)
{
    /* Set up the initial callbacks */
    init->open = program_open;
    init->authorise = program_authorise;
    

}

/** \brief Populate the provide application with our callbacks
 *
 *  \param dongle The dongle this is being setup for
 *  \param application Parameter block to populate
 *
 *  \return 0 on success, -1 on failure
 *
 *  This function is called via a callback from the library.
 *  We allocate our surface here and startup our menu system here.
 */
static int program_open(dongle_t *dongle, application_t *application)
{
    program_t   *program = (program_t *) calloc(1,sizeof(*program));
	window_t *menu2, *menu3;
	char item_text[30];
	int i;

    /* We should pick up appropriate parameters for the dongle here, or
       alternatively refuse the connection?
    */

    program->dongle = dongle;

  

    application->data = (void *) program;

    /* Set up the appropriate callback functions */
    application->close = program_close;
    application->get_yvuy_surface = program_get_surface;
    application->keypress = program_keypress;
    application->ack = program_ack;

    application->gui_width = c_gui_width;
    application->gui_depth = c_gui_depth;
    application->screen_width = c_screen_width;
    application->screen_depth = c_screen_depth;


    
    /* Finally, startup our application */
    program->root = new_root(c_gui_width,c_gui_depth,8);    
    window_set_name(program->root,"ROOT");
    window_clear(program->root,0x00000000);
	program->sub = new_menu(program->root, 100,100, 300,300);
	window_set_name(program->sub, "Menu 1");

	for(i = 0 ; i < 30 ; i++ ) {
		memset(item_text, 0, 30);
		sprintf(item_text, "A %d", i + 1);
		menu_add_item(program->sub, item_text);
	}

	menu2 = new_menu(program->root, 150,150, 300, 300);
	window_set_name(menu2, "Menu 2");
	for(i = 0; i < 20 ; i++) {
		memset(item_text, 0 , 30);
		sprintf(item_text, "B %d", i + 1);
		menu_add_item(menu2, item_text);
	}

	menu3 = new_menu(program->root, 300, 50, 300, 300);
	window_set_name(menu3, "Menu 3");
	for(i = 0; i < 25 ; i++) {
		memset(item_text, 0, 30);
		sprintf(item_text, "C %d", i + 1);
		menu_add_item(menu3, item_text);
	}

	menu_set_title(program->sub, "First Menu");
	menu_set_title(menu2, "Second Menu");
	menu_set_title(menu3, "Third Menu");

	window_register_callback(menu2, event_focus, menu_focus_event, NULL);
	window_register_callback(program->sub, event_blur, menu_focus_event, NULL);
	window_register_callback(menu3, event_highlight, menu_highlight_event, NULL);

	window_register_callback(program->sub, event_select, menu1_select_event, NULL);
	window_register_callback(menu2, event_select, menu2_select_event, NULL);
	window_register_callback(menu3, event_select, menu3_select_event, NULL);

    return 0;
}

/** \brief Delete the application
 *
 *  \param application Application to delete for
 */
static void program_close(application_t *application)
{
    program_t   *program = (program_t *)application->data;

  
    /* Delete the dinwos */


    free(program);
}

/** \brief Return the yvuy surface
 *
 *  \param application
 *  \param size Pointer to place the surface size
 *
 *  \return a rendered surface, or NULL if it's not been updated recently
 */
static uint8_t *program_get_surface(application_t *application, int *size)
{
    program_t  *program = (program_t *)application->data;
    surface_t  *sfc = window_get_draw_surface(program->root);

    if( window_draw(program->root) > 0) {
		return (uint8_t *) surface_map(sfc,MAP_YVU,size);  	
	}

	return NULL;
}

/** \brief Handle a keypress
 *
 *  \param application
 *  \param keycode Key code from the MVP
 *
 */
static void program_keypress(application_t *application, int keycode)
{
    program_t  *program = (program_t *)application->data;

	switch(keycode) {
		case key1:
			if(window_is_visible(program->sub)) {
				window_set_visible(program->sub, 0);
			} else {
				window_set_visible(program->sub, 1);
			}
			break;
	}

	window_dispatch_event(program->root, keycode);
}

/** \brief Handle an ack
 *
 *  \param application
 *  \param ackcode Type of ack
 *  \param buf Ack message
 *  \param buflen Length of ack message
 */
static void program_ack(application_t *application, int ackcode, unsigned char *buf, int buflen)
{
    program_t  *program = (program_t *)application->data;
}



/** \brief Check to see whether we should permit this dongle to connect
 *  
 *  \param mac_address The mac address of the dongle trying to connect
 *  \param ipaddr      The ipv4 ip address of the dongle trying to connect
 *  \param connected   Number of dongles already connected
 *
 *  \return 0 do not allow to connect, 1 permit to connect
 *
 *  This is a callback from the library and is called when the service
 *  locator message is received by the server
 */
static int program_authorise(char *mac_address, uint32_t ipaddr, int connected)
{
    /* We always permit dongles to connect */
    return 1;
}

int main(int argc, char *argv[])
{
    char hostbuf[2048];


    if ( gethostname(hostbuf,sizeof(hostbuf)-1) == -1 ) {
        perror("gethostbyname");
        exit(1);
    }
   
    if ( ( init.main_interfaceip = host_resolve(hostbuf) ) == - 1 ) {
        fprintf(stderr,"Cannot resolve host <%s>\n",hostbuf);
        exit(1);
    }

    event_init();
    
    init.logfile = stderr;
    init.dongle_version = 22050;
	init.debug_level = 2;

    program_init(&init);

    if ( mediamvp_server_init(&init) ) {
        exit(1);
    }

   
    event_dispatch();


    return 0;
}

/*
 * Local Variables:
 *  indent-tabs-mode:nil
 *  require-final-newline:t
 *  c-basic-offset: 4
 * End:
 */
