#include <stdio.h>
#include <sys/time.h>

#include "main.h"
#include "widget.h"
#include "game.h"
#include "score.h"
#include "data_neighb.h"

#include "callbacks.h"




void quit_button_cb ()
{
    if (global_state != STATE_PRESENT && !discovery_mode)
	save_score (nb_items_taken + (has_won != 0), nb_lives, time_cnt/1000,
		    has_won ? SCORE_DEAD : SCORE_ACTIVE);
    if (global_state != STATE_PRESENT && !has_won) {
	if (!save_game (0)) {
	    fprintf (stderr, "Couldn't save the game\n");
	    return;
	}
    }
    print_scores (0);
    exit (0);
}

void set_play_state ()
{
    XtVaSetValues (play_button,
                   XtNlabel, (XtArgVal) ((global_state == STATE_PRESENT) ?
					 "Play" : "Die"),
                   NULL);
}


void play_button_cb ()
{
    static unsigned long prevusec = 0;

    if (global_state == STATE_PRESENT) {
	new_game ();
    } else {					  /* wait for a double click */
	struct timeval t;
	unsigned long usec, diff;

	gettimeofday (&t, NULL);
	usec = t.tv_sec * 1000000 + t.tv_usec;
	diff = usec - prevusec;
	prevusec = usec;
	if (diff > 500000) /* 1/2 s */
	    return;

	die ();
    }
}


void set_discovery_state ()
{
    if (!discovery_mode)
	XtVaSetValues (discovery_widget,
		       XtNlabel, (XtArgVal) "Enter Discovery Mode",
		       XtNsensitive, (XtArgVal) ((global_state == STATE_PRESENT
						  || has_won)
						 ? False
						 : True),
		       NULL);
    else
	XtVaSetValues (discovery_widget,
		       XtNlabel, (XtArgVal) "Discovery Mode is ON",
		       XtNsensitive, (XtArgVal) False,
		       NULL);
}

void discovery_cb ()
{
    static unsigned long prevusec = 0;

    if (global_state != STATE_PRESENT && !discovery_mode) {
	struct timeval t;
	unsigned long usec, diff;

	gettimeofday (&t, NULL);
	usec = t.tv_sec * 1000000 + t.tv_usec;
	diff = usec - prevusec;
	prevusec = usec;
	if (diff > 500000) /* 1/2 s */
	    return;

	discovery_mode = 1;
	save_score (0, 0, 0, SCORE_REMOVE);
	set_discovery_state ();
	{
	    extern void show_time (int);
	    extern void show_nb_items_taken (void);
	    extern void show_nb_lives (void);
	    show_time (0);			    /* clear time indication */
	    show_nb_items_taken ();
	    show_nb_lives ();
	}
    }
}


#if 0
int slider_pos = 0;

extern Widget slider;
extern Widget slider_val;

void set_slider (w)
    Widget w;
{
    float top;
    char buf[30];

    top = ((float)(slider_pos + 0.45)) / (SLIDERSIZE+SLIDERTHUMB);
    XawScrollbarSetThumb (w, top, -1.0);

    sprintf (buf, "%02x", slider_pos);
    XtVaSetValues (slider_val,
                   XtNlabel, (XtArgVal) buf,
                   NULL);
}

void slider_jump_cb (w, client_data, percent_ptr)
    Widget w;
    XtPointer client_data;
    XtPointer percent_ptr;
{
    float fpos = *((float *) percent_ptr);
    float top;

    slider_pos = (fpos * (SLIDERSIZE+SLIDERTHUMB) + 0.5);
    if (slider_pos < 0)
	slider_pos = 0;
    if (slider_pos > SLIDERSIZE)
	slider_pos = SLIDERSIZE;
    set_slider (slider);
}


void slider_scroll_cb (w, client_data, position)
    Widget w;
    XtPointer client_data;
    XtPointer position;
{
    int delta = (((int) position) > 0) ? -1 : 1;
    if (slider_pos + delta >= 0 && slider_pos + delta <= SLIDERSIZE)
	slider_pos += delta;
    room_no = slider_pos;
    change_room ();
}
#endif





static XtIntervalId timeout_id = -1;

static void timeout_proc (client_data, idp)
    XtPointer client_data;
    XtIntervalId *idp;
{
    timeout_id = -1;
    set_timeout ();				  /* BEFORE or AFTER ??? XXX */
    move ();
}

void set_timeout ()
{
#define GAMESPEED 60
#define SCROLLSPEED 20
    if (timeout_id == -1) {
	static long prevusec = 0;
	static long set = SCROLLSPEED*1000;
	static long preverr = 0;
	long usec, diff;
	long target, absd;
	long tmp;
	struct timeval t;

	if (global_state == STATE_PRESENT) {
	    target = SCROLLSPEED*1000;
	    
	    gettimeofday (&t, NULL);
	    usec = t.tv_sec * 1000000 + t.tv_usec;
	    diff = usec - prevusec;
	    prevusec = usec;
	    
	    tmp = preverr;
	    preverr = diff-target;
	    tmp += preverr;
	    
	    if ((absd = tmp/2) < 0)
		absd = -absd;
	    
	    if (absd < 2000)
		;
	    else if (absd > 1000000)
		set = target;
	    else
		set += (target-diff)/4;
	    
	    if (set <= 0)
		set = 1;
	} else
	    set = GAMESPEED*1000;

	timeout_id = XtAppAddTimeOut (application_context,
				      set/1000,
				      timeout_proc,
				      NULL);
    }
}


void MoveLeft (MyWidget w, XEvent *event,
	       String *params, Cardinal *num_params)
{
    if (event->type == KeyPress)
	goleft = 1;
    else
	goleft = 0;
}

void MoveRight (MyWidget w, XEvent *event,
		String *params, Cardinal *num_params)
{
    if (event->type == KeyPress)
	goright = 1;
    else
	goright = 0;
}

void Jump (MyWidget w, XEvent *event,
	   String *params, Cardinal *num_params)
{
    if (event->type == KeyPress)
	dojump = 1;
    else
	dojump = 0;
}

