#include<stdio.h>
#include<stdlib.h>

typedef struct node
{
	void *ptr;
	struct node *next;
}queue_node;

typedef struct info
{
	int count;
	queue_node *front;
	queue_node *rear;
}queue;

void enqueue(queue *Q,void *dataptr)
{
	queue_node *newq;
	newq=(queue_node*)malloc(sizeof(queue_node));
	
	newq->ptr=dataptr;
	newq->next=NULL;
	
	if(Q->count==0)	Q->front=newq; 
	else	Q->rear->next=newq;
	
	Q->rear=newq;
	Q->count ++; 
}

void *dequeue(queue *Q)
{
	int *data;
	data=(int*)malloc(sizeof(int));
	queue_node *fre;
	
	fre=Q->front;
	data=fre->ptr;
	
	if(Q->count==1)	Q->front=Q->rear=NULL;
	else	Q->front=fre->next;
	
	Q->count --;
	free(fre);
	return data;
}

queue *create_queue()
{
	queue *Q;
	Q=(queue*)malloc(sizeof(queue));
	if(Q)
	{
		Q->count=0;
		Q->front=NULL;
		Q->rear=NULL;
	}
	return Q;
}

void destroy(queue *Q)
{
	queue_node *del;
	while(Q->front=NULL)
	{
		del=Q->front;
		Q->front=Q->front->next;
		free(del);
	}
}

int main()
{
	queue *Q;
	Q=create_queue();
	int *x,num;
	//int *data=(int*)malloc(sizeof(int));
	char input;
	printf("A> Enqueue data into queue\n");
	printf("B> Dequeue and print data\n");
	printf("C> Print data at the front\n");
	printf("D> Print data at the rear\n");
	printf("E> Print entire queue\n");
	printf("F> Print queue status(Empty or Non-empty)\n");
	printf("G> Print number of elements\n");
	printf("H> Destroy queue and quit\n");
	while(1)
	{
		printf("Please enter a letter:");
		scanf("%s",&input);
		switch(input)
		{
			case 'A':
			case 'a':
				{
					int *data=(int*)malloc(sizeof(int));      //*打在這才可以(?) 
					printf("please enter a number:");
					scanf("%d",data);
					enqueue(Q,data);
					break;
				}
			case 'B':
			case 'b':
				{
					if(Q->count==0) printf("Error,the queue is empty.\n");
					else
					{
						x=dequeue(Q);
						printf("the dequeue data is %d\n",*x);
					}
					break;
				}
			case 'C':
			case 'c':
				{
					if(Q->count==0) printf("The queue is empty.\n");
					else
					{
						x=Q->front->ptr;
						printf("the data at the front is %d\n",*x);
					}
					break;
				}
			case 'D':
			case 'd':
				{
					if(Q->count==0) printf("The queue is empty.\n");
					else
					{
						x=Q->rear->ptr;
						printf("the data at the rear is %d\n",*x);
					}
					break;
				}
			case 'E':
			case 'e':
				{
					printf("The entire queue have : ");
					queue_node *temp;
					temp=Q->front;
					while(temp!= NULL)
					{
						x=temp->ptr;
						printf("%d ",*x);
						if(temp->next!=NULL) printf("->");
						temp=temp->next;
					}
					printf("\n");
					break;
				}
			case 'F':
			case 'f':
				{
					if(Q->count==0) printf("the queue is empty.\n");
					else printf("the queue is non-empty.\n");
					break;
				}
			case 'G':
			case 'g':
				{
					num=Q->count;
					printf("the number of queue is %d\n",num);
					break;
				}
			case 'H':
			case 'h':
					destroy(Q);
					printf("the queue is destroyed.");
					return 0;
			default:
					printf("error input,enter again.\n");
					break; 
		}
	}
}