Index: playlist.c
===================================================================
--- playlist.c	(revision 3675)
+++ playlist.c	(working copy)
@@ -79,6 +79,10 @@
 } Playlist;
 
 static Playlist playlist;
+
+/*WHATAH*/
+extern Queue *q;
+/*END*/
 static int playlist_state = PLAYLIST_STATE_STOP;
 static int playlist_max_length = DEFAULT_PLAYLIST_MAX_LENGTH;
 static int playlist_stopOnError;
@@ -127,6 +131,12 @@
 static void incrPlaylistCurrent() {
 	if(playlist.current < 0) return;
 
+        /*WHATAH*/
+        if (is_empty_q(q) > 0) {
+            playlist.current = pop_next_in_q(q);
+            return;
+        }
+        /*END*/
 	if(playlist.current >= playlist.length-1) {
 		if(playlist.repeat) playlist.current = 0;
 		else playlist.current = -1;
@@ -134,11 +144,18 @@
 	else playlist.current++;
 }
 
+/*WHATAH*/
+void initQueue() {
+    q = malloc(sizeof(*q));
+    init_queue(q);
+}
+/*END*/
+
 void initPlaylist() {
 	char * test;
 	int i;
 	ConfigParam * param;
-
+        
 	playlist.length = 0;
 	playlist.repeat = 0;
 	playlist.version = 1;
@@ -255,6 +272,19 @@
 	return 0;
 }
 
+/*WHATAH*/
+int showQueue(FILE *fp, int *citer) {
+    int i;
+
+    for (i = 0; *citer != -1; citer++, i++) {
+        myfprintf(fp, "%i:%s\n", i, getSongUrl(playlist.songs[*citer]));
+    }
+
+    return 0;
+
+}
+/*END*/
+
 void savePlaylistState() {
 	char * stateFile = getStateFile();
 	
@@ -524,7 +554,24 @@
 }
 
 void queueNextSongInPlaylist() {
-	if(playlist.current<playlist.length-1) {
+        /*WHATAH*/
+        if (is_empty_q(q) > 0) {
+            
+            playlist.queued = next_in_q(q);
+            DEBUG("playlist: queue song %i:\"%s\"\n",
+                            playlist.queued,
+                            getSongUrl(playlist.songs[playlist.idToPosition[playlist.queued]]));
+            if (queueSong(playlist.songs[playlist.idToPosition[playlist.queued]]) < 0) {
+                playlist.queued = -1;
+                playlist_queueError = 1;
+            }
+
+            return;
+
+        } 
+        /*END*/
+
+        if(playlist.current<playlist.length-1) {
 		playlist.queued = playlist.current+1;
 		DEBUG("playlist: queue song %i:\"%s\"\n",
 				playlist.queued,
@@ -567,7 +614,27 @@
 		setQueueState(PLAYER_QUEUE_BLANK);
 		if(playlist.queued>=0) {
 			DEBUG("playlist: now playing queued song\n");
-			playlist.current = playlist.queued;
+                        /*WHATAH*/
+                        if (is_empty_q(q) > 0) {
+                            int local_queue = pop_next_in_q(q);
+                            if (local_queue > 0) {
+                                playlist.queued = local_queue;
+                                playlist.current = playlist.idToPosition[playlist.queued];
+                                DEBUG("queue: %i pos: %i\n", playlist.queued, playlist.current);
+                                if (playlist.random) {
+                                    int i;
+                                    for(i=0;playlist.order[playlist.idToPosition[i]]!=playlist.queued;i++);                            
+                                    playlist.current = i;
+                                }
+                            } else {
+                                DEBUG("queue popped a -1\n");
+                                playlist.current = playlist.queued;
+                            }
+                        } else {
+                            playlist.current = playlist.queued;
+                        }
+                        /*END*/
+
 		}
 		playlist.queued = -1;
 		if(queue) queueNextSongInPlaylist();
@@ -778,6 +845,10 @@
 	/* now take care of other misc stuff */
 	playlist.songs[playlist.length-1] = NULL;
 	playlist.length--;
+        /*WHATAH*/
+        /* Remove the song from the queue */
+        remove_q(q, playlist.positionToId[song]);
+        /*END*/
 
 	incrPlaylistVersion();
 
@@ -946,6 +1017,13 @@
 
 	playlist_stopOnError = 0;
 
+        /*WHATAH*/
+//        if (playlist.current == next_in_q(q)) pop_next_in_q(q);
+        if (is_empty_q(q) > 0) {
+            int i = pop_next_in_q(q);
+            return playPlaylistOrderNumber(fp, playlist.order[i]);
+        }
+        /*END*/
 	syncPlaylistWithQueue(0);
 
 	if(playlist.current>= 0 && playlist.current<playlist.length) {
@@ -962,8 +1040,14 @@
 	syncPlaylistWithQueue(0);
 	
 	playlist_stopOnError = 0;
-
-	if(playlist.current<playlist.length-1) {
+        
+        /*WHATAH*/
+        if (is_empty_q(q) > 0) {
+            playlist.queued = pop_next_in_q(q);
+            return playPlaylistById(fp, playlist.queued, 0);
+        } 
+        if(playlist.current<playlist.length-1) {
+        /*END*/
 		return playPlaylistOrderNumber(fp,playlist.current+1);
 	}
 	else if(playlist.length && playlist.repeat) {
@@ -1463,6 +1547,12 @@
 	return playlist.version;
 }
 
+/*WHATAH*/
+unsigned long getQueueVersion() {
+        return q->version;
+}
+/*END*/
+
 int getPlaylistLength() {
 	return playlist.length;
 }
Index: playlist.h
===================================================================
--- playlist.h	(revision 3675)
+++ playlist.h	(working copy)
@@ -103,6 +103,9 @@
 int getPlaylistLength();
 
 unsigned long getPlaylistVersion();
+/*WHATAH*/
+unsigned long getQueueVersion();
+/*END*/
 
 void playPlaylistIfPlayerStopped();
 
Index: command.c
===================================================================
--- command.c	(revision 3675)
+++ command.c	(working copy)
@@ -33,6 +33,10 @@
 #include "log.h"
 #include "dbUtils.h"
 
+/*WHATAH*/
+Queue *q;
+/*END*/
+
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
@@ -89,6 +93,13 @@
 #define COMMAND_COMMANDS	"commands"
 #define COMMAND_NOTCOMMANDS	"notcommands"
 
+/*WHATAH*/
+#define COMMAND_QUEUE           "queue"
+#define COMMAND_DEQUEUE         "dequeue"
+#define COMMAND_GETQUEUE        "getqueue"
+#define COMMAND_QUEUEINFO       "getqueueinfo"
+/*END*/
+
 #define COMMAND_STATUS_VOLUME           "volume"
 #define COMMAND_STATUS_STATE            "state"
 #define COMMAND_STATUS_REPEAT           "repeat"
@@ -103,7 +114,9 @@
 #define COMMAND_STATUS_CROSSFADE	"xfade"
 #define COMMAND_STATUS_AUDIO		"audio"
 #define COMMAND_STATUS_UPDATING_DB	"updating_db"
-
+/*WHATAH*/
+#define COMMAND_STATUS_QUEUE            "queue"
+/*END*/
 typedef struct _CommandEntry CommandEntry;
 
 typedef int (* CommandHandlerFunction)(FILE *, unsigned int *, int, char **);
@@ -251,6 +264,9 @@
         myfprintf(fp,"%s: %i\n",COMMAND_STATUS_REPEAT,getPlaylistRepeatStatus());
         myfprintf(fp,"%s: %i\n",COMMAND_STATUS_RANDOM,getPlaylistRandomStatus());
         myfprintf(fp,"%s: %li\n",COMMAND_STATUS_PLAYLIST,getPlaylistVersion());
+        /*WHATAH*/
+        myfprintf(fp,"%s: %li\n", COMMAND_STATUS_QUEUE, getQueueVersion());
+        /*END*/
         myfprintf(fp,"%s: %i\n",COMMAND_STATUS_PLAYLIST_LENGTH,getPlaylistLength());
 	myfprintf(fp,"%s: %i\n",COMMAND_STATUS_CROSSFADE,
 			(int)(getPlayerCrossFade()+0.5));
@@ -598,6 +614,86 @@
         return setPlaylistRandomStatus(fp,status);
 }
 
+/*WHATAH*/
+int handleQueue(FILE *fp, unsigned int *permission, int argArrayLength,
+                char ** argArray)
+{
+    int status;
+    char *test;
+    status = strtol(argArray[1], &test, 10);
+    if (*test != '\0') {
+        commandError(fp, ACK_ERROR_ARG, "need an integer", NULL);
+        return -1;
+    }
+    insert_q(q, status);
+    clearPlayerQueue();
+    return 0;
+}
+
+int handleDequeue(FILE *fp, unsigned int *permission, int argArrayLength,
+                char ** argArray)
+{
+    int status;
+    char *test;
+    status = strtol(argArray[1], &test, 10);
+    if (*test != '\0') {
+        commandError(fp, ACK_ERROR_ARG, "need an integer", NULL);
+        return -1;
+    }
+
+    remove_q(q, status);
+    return 0;
+}
+int handleGetqueue(FILE *fp, unsigned int *permission, int argArrayLength,
+                char ** argArray)
+{
+    int **contents = malloc(sizeof(contents));
+    if (q->size <= 0) {
+        return 0;
+    }
+    view_q(q, contents);
+    int *citer = *contents;
+    showQueue(fp, citer);
+    free(contents);
+    
+    return 0;
+}
+
+int handleQueueInfo(FILE *fp, unsigned int *permission, int argArrayLength,
+                char ** argArray)
+{
+    int status = -1;
+    char *test;
+
+    if(argArrayLength == 2) {
+            status = strtol(argArray[1],&test,10);
+            if(*test!='\0') {
+                    commandError(fp, ACK_ERROR_ARG,
+                                    "need a positive integer", NULL);
+                    return -1;
+            }
+    }
+    if (q->size <= status && status != -1) {
+        return 0;
+    }
+    int **contents = malloc(sizeof(contents));
+    view_q(q, contents);
+    int *citer = *contents;
+    if (status == -1) {
+        while (*citer != -1) {
+            playlistId(fp, *citer);
+            citer++;
+        }
+    } else {
+        playlistId(fp, citer[status]);
+    }
+
+    free(contents);
+    
+    return 0;
+}
+/*END*/
+
 int handleStats(FILE * fp, unsigned int * permission, int argArrayLength, 
 		char ** argArray) 
 {
@@ -963,7 +1059,12 @@
         addCommand(COMMAND_DEVICES     ,PERMISSION_ADMIN,   0, 0,handleDevices,NULL);
         addCommand(COMMAND_COMMANDS    ,0,                  0, 0,handleCommands,NULL);
         addCommand(COMMAND_NOTCOMMANDS ,0,                  0, 0,handleNotcommands,NULL);
-
+        /*WHATAH*/
+        addCommand(COMMAND_QUEUE       ,PERMISSION_CONTROL, 1, 1, handleQueue, NULL);
+        addCommand(COMMAND_DEQUEUE     ,PERMISSION_CONTROL, 1, 1, handleDequeue, NULL);
+        addCommand(COMMAND_GETQUEUE    ,PERMISSION_READ,    0, 0, handleGetqueue, NULL);
+        addCommand(COMMAND_QUEUEINFO   ,PERMISSION_READ,    0, 1, handleQueueInfo, NULL);
+        /*END*/
         sortList(commandList);
 }
 
Index: command.h
===================================================================
--- command.h	(revision 3675)
+++ command.h	(working copy)
@@ -26,6 +26,10 @@
 #include "log.h"
 #include "ack.h"
 
+/*WHATAH*/
+#include "queue.h"
+/*END*/
+
 #include <stdio.h>
 
 #define COMMAND_RETURN_KILL	10
@@ -34,6 +38,10 @@
 extern char * current_command;
 extern int command_listNum;
 
+/*WHATAH*/
+//extern Queue *q;
+/*END*/
+
 int proccessListOfCommands(FILE * fp, int * permission, int * expired, 
 		int listOK, List * list);
 
Index: main.c
===================================================================
--- main.c	(revision 3675)
+++ main.c	(working copy)
@@ -525,6 +525,9 @@
 	initPermissions();
 
         initPlaylist();
+        /*WHATAH*/
+        initQueue();
+        /*END*/
 
         openDB(&options, argv[0]);
 
Index: queue.c
===================================================================
--- queue.c	(revision 0)
+++ queue.c	(revision 0)
@@ -0,0 +1,193 @@
+#include "queue.h"
+
+void init_queue(Queue *q) {
+/*      Allocate memory for our Queue  */
+     q->tail = malloc(sizeof(*q->tail));
+     q->head = malloc(sizeof(*q->head));
+
+     q->tail->next = NULL;
+     q->tail->value = -1;
+
+     q->head->prev = NULL;
+     q->head->value = -1;
+     
+     q->head->next = q->tail;
+     q->tail->prev = q->head;
+
+     q->size = 0;
+     q->version = 0;
+     q->id = 0;
+
+     print_q(q);
+}
+
+
+void insert_q(Queue *q, int value) {
+    if (q == NULL) {
+       return;
+    }
+    q_node *prev;
+    q_node *inserted = malloc(sizeof(*inserted));
+    prev = q->tail->prev;
+    prev->next = inserted;
+
+    inserted->next = q->tail;
+    inserted->prev = prev;
+    inserted->value = value;
+    inserted->id = q->id;
+
+    q->tail->prev = inserted;
+
+    q->size++;
+    q->version++;
+    q->id++;
+
+}
+
+void remove_q(Queue *q, int value) {
+    if (q == NULL) {
+        return;
+    }
+    q_node *iter = q->tail->prev;
+    while (iter->prev != NULL) {
+        if (iter->value == value) { // Found the first instance of the value
+            q_node *prev = iter->prev;
+            
+            prev->next = iter->next;
+            iter->next->prev = prev;
+
+            free(iter);
+            
+            q->size--;
+            q->version++;
+
+            return;
+            
+        }
+        iter = iter->prev;
+    }
+    
+
+}
+
+void remove_all_q(Queue *q, int value) {
+    if (q == NULL) {
+        return;
+    }
+    q_node *iter = q->tail->prev;
+    while (iter->prev != NULL) {
+        if (iter->value == value) { // Found the first instance of the value
+            q_node *prev = iter->prev;
+            
+            prev->next = iter->next;
+            iter->next->prev = prev;
+
+            free(iter);
+            
+            q->size--;
+            q->version++;
+
+        }
+        iter = iter->prev;
+    }
+    
+
+}
+
+void remove_by_id_q(Queue *q, int id) {
+    if (q == NULL) {
+        return;
+    }
+    q_node *iter = q->tail->prev;
+    while (iter->prev != NULL) {
+        if (iter->id == id) { // Found the first instance of the value
+            q_node *prev = iter->prev;
+            
+            prev->next = iter->next;
+            iter->next->prev = prev;
+
+            free(iter);
+            
+            q->size--;
+            q->version++;
+            return;
+
+        }
+        iter = iter->prev;
+    }
+
+
+    }
+
+
+    
+
+int next_in_q(Queue *q) {
+    if (q == NULL) {
+       return;
+    }
+    return q->head->next->value;
+}
+
+int is_empty_q(Queue *q) {
+    if (q == NULL) {
+       return;
+    }
+    return q->size;
+}
+
+int pop_next_in_q(Queue *q) {
+    if (q == NULL) {
+       return;
+    }
+    if (is_empty_q(q) > 0) {
+        int value = next_in_q(q);
+        q_node *removed = q->head->next;
+        q_node *next = removed->next;
+
+        q->head->next = next;
+        next->prev = q->head;
+
+        free(removed);
+        q->size--;
+        q->version++;
+
+        return value;
+    }
+    return -1;
+}
+
+    
+
+void print_q(Queue *q) {
+    if (q == NULL) {
+       return;
+    }
+    q_node *iter = q->head;
+    printf("Contents of Queue:\n");
+    while (iter != NULL) {
+        printf("Value: %x Pointer: %p\n", iter->value, iter);
+        iter = iter->next;
+    }
+}
+
+void view_q(Queue *q, int **contents) {
+    if (q == NULL) {
+       return;
+    }
+
+    *contents = malloc(q->size + 1);
+    int *citer = *contents;
+    q_node *iter = q->head->next;
+    while (iter != NULL) {
+        *citer = iter->value;
+        iter = iter->next;
+        citer++;
+    }
+    
+    return ;
+}
+
+int get_version_q(Queue *q) {
+    return q->version;
+}
Index: Makefile.am
===================================================================
--- Makefile.am	(revision 3675)
+++ Makefile.am	(working copy)
@@ -50,6 +50,7 @@
 	player.h \
 	playerData.h \
 	playlist.h \
+	queue.h \
 	replayGain.h \
 	signal_check.h \
 	sig_handlers.h \
@@ -94,6 +95,7 @@
 	player.c \
 	playerData.c \
 	playlist.c \
+	queue.c \
 	replayGain.c \
 	sig_handlers.c \
 	signal_check.c \
Index: queue.h
===================================================================
--- queue.h	(revision 0)
+++ queue.h	(revision 0)
@@ -0,0 +1,51 @@
+#include <stdlib.h>
+#include <stdio.h>
+
+
+/* Doubly Linked List to use as the Queue */
+typedef struct _q_node {
+        int value;
+        unsigned long id;
+        struct _q_node *prev;
+        struct _q_node *next;
+} q_node;
+
+typedef struct _Queue {
+        q_node *head;
+        q_node *tail;
+        unsigned long size;
+        unsigned long id;
+        unsigned long version;
+} Queue;
+
+void init_queue(Queue *q); 
+
+/* Insert value at the end of q.*/
+void insert_q(Queue *q, int value);
+
+/* Remove value from the end of q*/
+void remove_q(Queue *q, int value);
+
+/* Remove value from whole q */
+void remove_all_q(Queue *q, int value);
+
+/* Remove by queue ID from queue */
+void remove_by_id_q(Queue *q, int id);
+
+/*Return the value of the first in queue.*/
+int next_in_q(Queue *q);
+
+/* Returns the size of the queue (if > 0, queue is not empty)*/
+int is_empty_q(Queue *q);
+
+/* Returns the value of the first in queue and deletes it from the queue.*/
+int pop_next_in_q(Queue *q);
+
+/* Prints out the contents of the queue.*/
+void print_q(Queue *q);
+
+/* Returns an int array of the values in q (excluding the head and tail)*/
+void view_q(Queue *q, int **contents);
+
+/* Returns the queue version */
+int get_version_q(Queue *q);
