#include <stdio.h>
#include <time.h>
#include <string.h>
#include <ctype.h>

#include "global.h"

#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_cs_util.h"
#include "manhat-lib/shared_authenticate.h"  /* for sub_dir_name() */
#include "manhat-lib/shared_strtrm.h"


typedef struct semester_sort_node
{
   char semester[MAX_SEMESTER + 1];
   int expanded;
   int check_new;
   struct semester_sort_node  *next;
   struct semester_sort_node  *prev;
} SEMESTER_SORT_NODE;






static void
read_parameters (char *key, int *item, int *up, int *check_unread)
{
  char msg[50];

  cs_get_required_parameter ("id", key, MAX_KEY);  /* shared_cgi_util.c */
  cs_get_required_parameter ("item", msg, 10);
  *item = atoi (msg);

  cs_get_optional_parameter("up", msg, 5);
  *up = strlen(msg);
  
  cs_get_optional_parameter("check_unread", msg, 5);
  *check_unread = strlen(msg);
  
}



static void rewrite_semester_sort_file(SEMESTER_SORT_NODE *head, const char *sort_file)
{
 FILE *fp;
 SEMESTER_SORT_NODE *ptr;
 
 fp = fopen(sort_file, "w");
 if(fp)   /* ignore errors - this is not that important to interrupt the user on failure */
  {
   for(ptr=head; ptr; ptr=ptr->next)
     fprintf(fp,"%s\n%d%s\n", ptr->semester, ptr->expanded?1:0, ptr->check_new?"*":"");
   fclose(fp);
  }
}     
 

   

/** NOTE that this function make no attempt to preserve the 'prev' links
*** in the linked list!!!
***/

static
void move_semester_up(SEMESTER_SORT_NODE *head, int item, const char *sort_file)
{
 SEMESTER_SORT_NODE *sptr;
 int i;

 if (item == 1)
    return;     /* since the first item can't be moved up */
    
 /* point sptr to the correct item */   
 for(sptr=head, i = 1; sptr && (i < item); sptr=sptr->next, i++);
 
 if(!sptr)
    return;   /* since we've reached the end of the list without finding the item */
    
 if(sptr == head)  /* although we've already checked for this .. */
     return;
 
 /* if item is #2 on the list */
 if(sptr->prev == head)
   {
     head->next = sptr->next;
     sptr->next = head;
     head = sptr;
   }    
 else
   {
    sptr->prev->prev->next = sptr;
    sptr->prev->next = sptr->next;
    sptr->next = sptr->prev;
   }
    
 rewrite_semester_sort_file(head,sort_file);
}    




/** NOTE that this function make no attempt to preserve the 'prev' links
*** in the linked list!!!
***/


static
void move_semester_down( SEMESTER_SORT_NODE *head, int item, const char *sort_file)
{
 SEMESTER_SORT_NODE *sptr;
 int i;

    
 /* point sptr to the correct item */   
 for(sptr=head, i = 1; sptr && (i < item); sptr=sptr->next, i++);
 
 if(!sptr)
    return;   /* since we've reached the end of the list without finding the item */
    
 if(!sptr->next)  /* since this is already the last item in the list */
     return;
     
 if(sptr == head)
  {
   head = head->next;
   sptr->next = head->next;
   head->next = sptr;
  }
 else
  {          
   sptr->prev->next = sptr->next;
   sptr->next = sptr->next->next;   
   sptr->prev->next->next = sptr;   
  }
  
 rewrite_semester_sort_file(head,sort_file);  
}


SEMESTER_SORT_NODE *build_semester_sort_list(const char *username, char *sort_file)
{
#define MAX_LINE 100

 char line[MAX_LINE + 1];
 char dirname;
 FILE *fp;
 SEMESTER_SORT_NODE *sort_head = 0, *ptr=0;

 dirname = sub_dir_name(username);    /* shared_authenticate.c */
 
 snprintf(sort_file, MAX_PATH + 1, "../%s/%c/%s/%s",
                            USERS_DIR, dirname, username,SEMESTER_SORT_FNAME);

                            
 fp = fopen(sort_file, "r"); 
 if(fp)
  {
    while(fgets(line,MAX_LINE, fp))
     {
      strtrm(line);  /* shared_util.c*/
      if(!sort_head)
       {
        sort_head = (SEMESTER_SORT_NODE *) malloc(sizeof(SEMESTER_SORT_NODE));
        if(!sort_head)
           cs_critical_error(ERR_MALLOC_FAILED, "");
        ptr = sort_head;
        ptr->prev = 0;
       }
      else
       {
        ptr->next = (SEMESTER_SORT_NODE *) malloc(sizeof(SEMESTER_SORT_NODE));
        if(!ptr->next)
           cs_critical_error(ERR_MALLOC_FAILED, "");     
        ptr->next->prev = ptr;   
        ptr = ptr->next;
       }
       strncpy(ptr->semester, line, MAX_SEMESTER + 1);

       /* next line contains info on whether or not this semester is 'expanded' */
       if(fgets(line, MAX_LINE, fp))
        {
         ptr->expanded = (*line == '1');
         ptr->check_new = strchr(line, '*')? 1: 0;
        } 
       else
        {
         ptr->expanded = 1;
         ptr ->check_new = 0;
        } 

       ptr->next = 0;  
     } /* while (fgets..) */     
  
  fclose(fp);
 } 
 
 
 return sort_head;

#undef MAX_LINE
}


void
free_semester_sort_list(SEMESTER_SORT_NODE *head)
{
   SEMESTER_SORT_NODE  *ptr;
   while (head)
    {
      ptr = head->next;
      free (head);
      head = ptr;
    }
}
       




void
move_semester(SESSION *user, int item, int up)
{
  SEMESTER_SORT_NODE *sort_head;
  char sort_file[MAX_PATH + 1];
  
  sort_head = build_semester_sort_list(user->username, sort_file);

     
  if(up)
    move_semester_up(sort_head,item, sort_file);
  else
    move_semester_down(sort_head, item, sort_file);
         
 free_semester_sort_list(sort_head);
}



void
set_check_new(SESSION *user, int item)
{
  SEMESTER_SORT_NODE *sort_head, *ptr;
  char sort_file[MAX_PATH + 1];
  int i;
  
  sort_head = build_semester_sort_list(user->username, sort_file);

  for(ptr = sort_head, i=1; ptr; ptr = ptr->next, i++)
   {
    if(i == item)
       ptr->check_new = 1;
    else
       ptr->check_new = 0;
   }

  rewrite_semester_sort_file(sort_head,sort_file);         
 free_semester_sort_list(sort_head);
}








   

int
main (void)
{
  SESSION user;
  char key[MAX_KEY + 1];	/* from id=? command line */
  int item;                     /* from item=? command line */
  int up;                       /* from optional up=? command line - which direction to move msg? */
  int check_unread;             /* from optional check_unread=? cmd line = check unread msgs for this item? */  
  cs_cgi_init(); 

  read_parameters ( key, &item, &up, &check_unread);
  validate_server_key(key,&user);   /* shared_util.c */
  
  
  if(check_unread)
    set_check_new(&user, item);
  else  
    move_semester(&user, item, up);
  

  printf ("Location: %s?id=%s\n\n", "mymanhattan", key);
  cs_cgi_destroy(); 
  return 0;
}



