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

#include "global.h"
#include "custom.h"		/* for date FORMAT strings, etc. */

#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_cs_util.h"
#include "manhat-lib/shared_news_util.h"
#include "manhat-lib/shared_lock.h"


#define NOTEAM '!'		/* flag meaning that there was no 'team' parameter sent to this program */




static void
read_parameters (char *course, char *key, int *grp, int *up, int *target_msg, char *team)
{
  char msg[50];

  cs_get_required_parameter ("crs", course, MAX_PATH);	/* shared_cgi_util.c */
  cs_get_required_parameter ("id", key, MAX_KEY);

  cs_get_required_parameter ("grp", msg, 5);
  *grp = atoi (msg);

  cs_get_required_parameter ("msg", msg, 40);
  *target_msg = atoi (msg);
  
  cs_get_optional_parameter("up", msg, 5);
  *up = strlen(msg);
  
  if(*grp == TEAM_TEACH)
    {
     cs_get_required_parameter("team", msg, 5);
     *team = *msg;
    }
  else
     *team = NOTEAM;   

}



static
void write_new_sort_file(char team, int grp)
{
FILE *fp;
int fd;

MSG_TREE_NODE *ptr;
char sort_file[MAX_PATH + 1];
char teamstring[5];


 snprintf(sort_file, MAX_PATH + 1, "%s%s", central_discussion_path,TOPIC_SORT_FNAME);
 if( (grp == TEAM_DISCUSSION) || (grp == TEAM_TEACH) )
  {
    snprintf(teamstring, 5, ".%c", team);
    strcat(sort_file,teamstring);
  }  
 fp=fopen(sort_file,"w");
 if(!fp)
    cs_critical_error(ERR_FOPEN_WRITE_FAILED,sort_file);
 
 fd = fileno(fp);
 get_exclusive_lock(fd,1);  
 for(ptr=tree_head; ptr; ptr=ptr->next)
 {
   if(fwrite(&(ptr->data.info.msg_id),sizeof(int),1,fp) != 1)
     cs_critical_error(ERR_FWRITE_FAILED,sort_file);
 }    
 
 release_lock(fd);
 fclose(fp);
} 

     

   



static
void move_msg_up(char team, int grp, int target_msg)
{
 MSG_TREE_NODE *target_ptr, *prev_ptr, *next_ptr;
 int found;
  
  
 for(target_ptr=tree_head, found = 0; target_ptr && !found; target_ptr=target_ptr->next)
  {
   found = target_ptr->data.info.msg_id == target_msg;
   if(found)
      break;
  }
  
 if(!found || (target_ptr == tree_head) )
    return;
 
 
 prev_ptr = target_ptr->prev;
 next_ptr = target_ptr->next;
 
 prev_ptr->next = next_ptr;
 
 target_ptr->next = prev_ptr;
 
 if(!prev_ptr->prev)
   tree_head = target_ptr;
 else
   prev_ptr->prev->next = target_ptr;

 write_new_sort_file(team, grp);
}





static
void move_msg_down(char team, int grp, int target_msg)
{
 MSG_TREE_NODE *target_ptr, *prev_ptr, *next_ptr;
 int found;
  
 for(target_ptr=tree_head, found = 0; target_ptr && !found; target_ptr=target_ptr->next)
  {
   found = target_ptr->data.info.msg_id == target_msg;
   if(found)
      break;
  }
  
 if(!found || (!target_ptr->next) )
    return;
         
 prev_ptr = target_ptr->prev;
 next_ptr = target_ptr->next;
 
 if(target_ptr == tree_head)
   tree_head = next_ptr;
 else  
   prev_ptr->next = next_ptr;
 
 target_ptr->next = next_ptr->next;
 next_ptr->next = target_ptr;
   
 write_new_sort_file(team, grp);
}



       




void
move_msg(SESSION *user, int grp, CONFIG_STRUCT *conf, int target_msg, int up)
{

  set_discussion_names (conf->course_path, user->username, grp);	/* shared_news_util.c */
  build_topic_only_tree(user,grp);   /* shared_news_util.c */
  if(!tree_head)
     return;
     
  if(up)
    move_msg_up(user->team, grp, target_msg);
  else
    move_msg_down(user->team, grp, target_msg);
         
 free_msg_tree(tree_head);  /* shared_news_util.c */
}



   

int
main (void)
{
  SESSION user;
  CONFIG_STRUCT conf;		/* the configuration read from config file */
  char course[MAX_PATH + 1];	/* from crs=? command line */
  char key[MAX_KEY + 1];	/* from id=? command line */
  int grp;                      /* from grp=? command line */
  int up;                       /* from up=? command line - which direction to move msg? */
  int target_msg;               /* from msg=? command line */
  char team;                    /* from optional team=? command line */
  
  
  cs_cgi_init();

  read_parameters (course, key, &grp, &up, &target_msg, &team);

  
  read_configuration_file (course, &conf);	/* shared_util.c */
  validate_key (key, &user, &conf);	/* shared_util.c */

  if(user.group != FACULTY)
     cs_critical_error(ERR_REQUEST_DENIED, "");

  if(team != NOTEAM)
     user.team = team;
          
  move_msg(&user, grp, &conf, target_msg, up);
  
  if(team == NOTEAM)
     printf ("Location: %s?crs=%s&id=%s&grp=%d#%d\n\n", "news_manage_topic_list", course, key,grp, target_msg);  
  else
     printf ("Location: %s?crs=%s&id=%s&grp=%d&team=%c#%d\n\n", "news_manage_topic_list", course, key,grp,team, target_msg);       

  cs_cgi_destroy();
  return 0;
}



