/*
 *   MediaMVP Server
 *
 *   (C) 2004 Dominic Morris
 *
 *   $Id: windowlive.c,v 1.9 2004/08/30 11:21:05 ravelox Exp $
 *   $Date: 2004/08/30 11:21:05 $
 *
 *
 *   Implements the skeleton application
 * 
 */

#include "mvpwindow.h"




typedef struct {
    dongle_t     *dongle;


    window_t     *root;
    window_t     *sub;

} program_t;;


window_t *box, *label;

int zorder = 0;

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 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));

    /* 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");
    surface_clear(window_get_draw_surface(program->root),0x00000000);
	program->sub = new_box(program->root, 100,100, 300,300);
	window_set_fill_col(program->sub, 0x00FF00);
	window_set_border_col(program->sub, 0xFF0000);
	window_set_border_size(program->sub, 20); 
	window_set_name(program->sub, "Box");

	label = new_label(program->sub, 50,50, 200,200, "Hello\nWorld");
	window_set_fgcol(label, 0xFFFFFF);
	window_set_bgcol(label, 0x0000DD);
	label_set_align(label, LABEL_ALIGN_CENTRE);
	label_set_valign(label, LABEL_VALIGN_MIDDLE);
	window_set_name(label, "Label");

	box = new_box(program->root, 200,200,300,300);
	window_set_fill_col(box, 0x0000FF);
	window_set_name(box, "New Box");

    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;
    int  x,y;

    x = window_get_xpos(program->sub);
    y = window_get_ypos(program->sub);

    switch ( keycode ) {
    case keyVolDn:
        if ( x > 10 ) 
            x-=10;
        break;
    case keyVolUp:
        if ( x < c_gui_width - 100 - 10)
            x+=10;
        break;
    case keyChanUp:
        if ( y > 10 ) 
            y-=10;
        break;
    case keyChanDn:
        if ( y < c_gui_depth - 100 - 10)
            y+=10;
        break;
	case keyBlank:
		fprintf(stderr, "zorder flag: %d\n", zorder);
		if(zorder == 0) {
			window_set_focus(program->sub);
			zorder = 1;
		} else {
			window_set_focus(box);
			zorder = 0;
		}
		break;
	 case key1:
		fprintf(stderr, "Label: LEFT\n");
		label_set_align(label, LABEL_ALIGN_LEFT);
		break;
	 case key2:
		fprintf(stderr, "Label: CENTRE\n");
		label_set_align(label, LABEL_ALIGN_CENTRE);
		break;
	 case key3:
		fprintf(stderr, "Label: RIGHT\n");
		label_set_align(label, LABEL_ALIGN_RIGHT);
		break;
	 case key4:
		fprintf(stderr, "Label: TOP\n");
		label_set_valign(label, LABEL_VALIGN_TOP);
		break;
	 case key5:
		fprintf(stderr, "Label: MIDDLE\n");
		label_set_valign(label, LABEL_VALIGN_MIDDLE);
		break;
	 case key6:
		fprintf(stderr, "Label: BOTTOM\n");
		label_set_valign(label, LABEL_VALIGN_BOTTOM);
		break;
    }
    printf("Set position %d,%d\n",x,y);
	window_set_pos(program->sub, x, y);
}

/** \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 = 0;

    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:
 */
