/*
 * OpenMRCP - Open Source Media Resource Control Protocol Stack
 * Copyright (C) 2007, Cepstral LLC
 *
 * Version: MPL 1.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Author(s):
 * Arsen Chaloyan <achaloyan@yahoo.com>
 *
 * Contributor(s):
 *
 */

#ifdef WIN32
#pragma warning(disable: 4127)
#endif
#include <apr_ring.h>
#include "apt_ptr_queue.h"

typedef struct queue_elem_t queue_elem_t;

struct queue_elem_t {
	APR_RING_ENTRY(queue_elem_t) link;
	void                        *data;
};

struct apt_ptr_queue_t {
	APR_RING_HEAD(queue_head_t, queue_elem_t) head;
	apr_pool_t                               *pool;
};


APT_DECLARE(apt_ptr_queue_t*) apt_ptr_queue_create(apr_pool_t *pool)
{
	apt_ptr_queue_t *queue = apr_palloc(pool, sizeof(apt_ptr_queue_t));
	queue->pool = pool;
	APR_RING_INIT(&queue->head, queue_elem_t, link);
	return queue;
}

APT_DECLARE(void) apt_ptr_queue_destroy(apt_ptr_queue_t *queue)
{
	/* nothing to do */
}

APT_DECLARE(apt_bool_t) apt_ptr_queue_push(apt_ptr_queue_t *queue, void *data)
{
	queue_elem_t *elem = apr_palloc(queue->pool,sizeof(queue_elem_t));
	elem->data = data;

	APR_RING_INSERT_TAIL(&queue->head,elem,queue_elem_t,link);
	return TRUE;
}

APT_DECLARE(void*) apt_ptr_queue_pop(apt_ptr_queue_t *queue)
{
	queue_elem_t *elem;
	if(APR_RING_EMPTY(&queue->head,queue_elem_t,link)) {
		return NULL;
	}
	elem = APR_RING_FIRST(&queue->head);
	APR_RING_REMOVE(elem,link);
	return elem->data;
}

APT_DECLARE(void*) apt_ptr_queue_head(apt_ptr_queue_t *queue)
{
	queue_elem_t *elem;
	if(APR_RING_EMPTY(&queue->head,queue_elem_t,link)) {
		return NULL;
	}
	elem = APR_RING_FIRST(&queue->head);
	return elem->data;
}

APT_DECLARE(void*) apt_ptr_queue_tail(apt_ptr_queue_t *queue)
{
	queue_elem_t *elem;
	if(APR_RING_EMPTY(&queue->head,queue_elem_t,link)) {
		return NULL;
	}
	elem = APR_RING_LAST(&queue->head);
	return elem->data;
}
