/************************************************************
Author Lawrence Gold
Handles resending missed packets.

Modified 12-30-1998 for use with GtkICQ by Jeremy Wise
*************************************************************/
#include "msg_queue.h"
#include "gtkicq.h"
#include <stdlib.h>
#include <assert.h>
#include <limits.h>

static struct msg_queue *queue= NULL;


void msg_queue_init( void )
{
    queue = malloc( sizeof( *queue ) );
    queue->entries = 0;
    queue->head = queue->tail = NULL;
}


struct msg *msg_queue_peek( void )
{
    if ( NULL != queue->head )
    {
        return queue->head->msg;
    }
    else
    {
        return NULL;
    }
}


struct msg *msg_queue_pop( void )
{
    struct msg *popped_msg;
    struct msg_queue_entry *temp;

    if ( ( NULL != queue->head ) && ( queue->entries > 0 ) )
    {
        popped_msg = queue->head->msg;    
        temp = queue->head->next;
        free(queue->head);
        queue->head = temp;
        queue->entries--;
        if ( NULL == queue->head )
        {
            queue->tail = NULL;
        }
        return popped_msg;
    }
    else
    {
        return NULL;
    }
}


void msg_queue_push( struct msg *new_msg)
{
    struct msg_queue_entry *new_entry;

    assert( NULL != new_msg );
    
    if ( NULL == queue ) return;

    new_entry = malloc(sizeof(struct msg_queue_entry));

    new_entry->next = NULL;
    new_entry->msg = new_msg;

    if (queue->tail)
    {
        queue->tail->next = new_entry;
        queue->tail = new_entry;
    }
    else
    {
        queue->head = queue->tail = new_entry; 
    }

    queue->entries++;
}

void msg_queue_clear( void )
{
   int i;
	
   assert( queue != NULL );
   assert( 0 <= queue->entries );
   
   for (i = 0; i < queue->entries; i++)
   {
       msg_queue_pop();
   }
}

void Check_Queue( WORD seq )
{
   int i;
   struct msg *queued_msg;
	
   assert( 0 <= queue->entries );
   
   for (i = 0; i < queue->entries; i++)
   {
       queued_msg = msg_queue_pop();
       if (queued_msg->seq != seq)
       {
           msg_queue_push( queued_msg );
       }
       else
       {
           free(queued_msg->body);
           free(queued_msg);

           if ((queued_msg = msg_queue_peek()) != NULL)
           {
               next_resend = queued_msg->exp_time;
           }
           else
           {
               next_resend = INT_MAX;
           }
           break;
       }
   }
}
