#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_news_util.h"
#include "manhat-lib/shared_translate_url.h"
#include "manhat-lib/shared_access.h"
#include "manhat-lib/shared_system_data.h"


#define NO_INDENT 0   
#define INDENT 1

int global_indent = 0;
int global_topic_count = -1;
int global_msg_count = - 1;


static void
read_parameters (char *course, char *key,
		 int *topic, char *student, char *realname, long *offset, int *grp)
{
  char msg[80];
  char *cptr;


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

  cs_get_required_parameter ("realname", realname, MAX_NAME);		/* shared_cs_util.c */
  /* convert underscores to spaces */
  while ((cptr = strchr (realname, '_')))
    *cptr = ' ';

  cs_get_required_parameter ("topic", msg, 79);		/* shared_cs_util.c */
  *topic = atoi (msg);

  cs_get_required_parameter ("loc", msg, 79);		/* shared_cs_util.c */
  *offset = atol (msg);
  cs_get_required_parameter ("grp", msg, 79);		/* shared_cs_util.c */
  *grp = atoi (msg);

}





static void
set_command_data (const char *course, const char *key, int topic,
			      const char *student_realname, const char *student, long offset, int can_write, const char *fromstring, int grp)
{
#define LONG_URL 512

 char url[LONG_URL + 1];
 
 
   /* set a url to be used for a 'back' button */
  snprintf (url, LONG_URL + 1, "%s?crs=%s&amp;id=%s&amp;topic=%d&amp;loc=%ld&grp=%d",
	  "assign_fac_expand", course, key, topic, offset, grp);
  cs_set_value("back_url", url);

  /* set a url to be used for a 'main menu' button */
  snprintf (url, LONG_URL + 1, "%s?crs=%s&amp;id=%s", "main_menu", course, key);
  cs_set_value("main_url", url);

  cs_set_value("realname", student_realname);

  /** If we're not read-only, set a url to send a new memo to this
  *** student
  */
  if(can_write)
  {
  snprintf
    (url, LONG_URL + 1, "%s?crs=%s&amp;id=%s&amp;topic=%d&amp;to=%s&amp;realname=%s&amp;grp=%d&amp;reply_to=%d&amp;from=%s",
     "news_new_memo", course, key, topic, student, student_realname, grp, topic, fromstring);
  
     cs_set_value("newmemo_url", url);
  }

    
#undef LONG_URL    
}






static void
set_message_data (MSG_TREE_NODE * msg, const char *course, const char *key, long offset, int topic,
			const char *student, const char *realname, const char *fromstring, int grp)
{
  char timestring[MAX_TIMESTRING + 1];
  char name[MAX_PATH + 1];
  char url[MAX_PATH + 1];
  char *new_str = 0;    
  

 if(msg->data.info.reply_to == -1)  /* if this is a topic */
 {
   global_topic_count++;
   global_msg_count = 0;
   snprintf(name, MAX_PATH + 1, "topic.%d.msg.%d.is_topic", global_topic_count, global_msg_count);
   cs_set_int_value(name, 1); 
 }
 else
   global_msg_count++;

  /*is this message unread?  */
   if(!msg->user_data.time_read )
   {
      snprintf(name, MAX_PATH + 1, "topic.%d.msg.%d.is_unread", global_topic_count, global_msg_count);
      cs_set_int_value(name, 1); 
   }
  
  /* is this message flagged? */
  if(msg->user_data.flagged)
   {
      snprintf(name, MAX_PATH + 1, "topic.%d.msg.%d.is_flagged", global_topic_count, global_msg_count);
      cs_set_int_value(name, 1); 
   }
  
  /* set news_flag url */
  
   snprintf(url, 
       MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;msg_id=%d&amp;from=%s",
        "news_flag", course, key, grp, msg->data.info.msg_id, fromstring);

   snprintf(name, MAX_PATH + 1, "topic.%d.msg.%d.flag_url", global_topic_count, global_msg_count);
  
   cs_set_value(name, url);
   
   
  /* does this message have attachments? */
   if(msg->data.info.attachments )
   {
      snprintf(name, MAX_PATH + 1, "topic.%d.msg.%d.has_attachments", global_topic_count, global_msg_count);
      cs_set_int_value(name, 1); 
   }

  /* do info */
  snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;loc=%ld",
	  "news_info", course, key, grp, msg->offset);
  snprintf(name, MAX_PATH + 1, "topic.%d.msg.%d.info_url", global_topic_count, global_msg_count);
  cs_set_value(name, url); 

  /** AMP_SUB, et. al are #defined in shared_translate_url.h */                 
   snprintf
    (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;loc=%ld&amp;student=%s&amp;grp=%d&amp;from=%s",
     "assign_read", course, key, msg->offset, student, grp, fromstring);
   snprintf(name, MAX_PATH + 1, "topic.%d.msg.%d.subject_url", global_topic_count, global_msg_count);
   cs_set_value(name, url); 
  
  if(!strlen(msg->data.info.subject))
  {
   snprintf(name, MAX_PATH + 1, "topic.%d.msg.%d.no_subject", global_topic_count, global_msg_count);
   cs_set_int_value(name, 1); 
  }
  else
  {
    snprintf(name, MAX_PATH + 1, "topic.%d.msg.%d.subject", global_topic_count, global_msg_count);
    /* next makes use of undocmented ClearSilver function */
    if(cgi_html_escape_strfunc(msg->data.info.subject,&new_str) == STATUS_OK)
      {
       cs_set_value(name,new_str);
       if(new_str)
          free(new_str);
      }
    else
       cs_set_value(name,msg->data.info.subject);
    }        
  
  
  /* do sender */
   snprintf(name, MAX_PATH + 1, "topic.%d.msg.%d.sender", global_topic_count, global_msg_count);
   cs_set_value(name, msg->data.info.sender_realname); 

  /* do time sent */
  strftime (timestring, MAX_TIMESTRING, system_data_str("DOW_DATE_FORMAT"),
	      localtime (&(msg->data.info.time_sent)));
   snprintf(name, MAX_PATH + 1, "topic.%d.msg.%d.sent_time", global_topic_count, global_msg_count);
   cs_set_value(name, timestring); 

 /* do MSG ID, Re: */   

   snprintf(name, MAX_PATH + 1, "topic.%d.msg.%d.msg_id", global_topic_count, global_msg_count);
   cs_set_int_value(name, msg->data.info.msg_id); 
   if(msg->data.info.reply_to != -1)
   {
     snprintf(name, MAX_PATH + 1, "topic.%d.msg.%d.add_re", global_topic_count, global_msg_count);
     cs_set_int_value(name, 1); 
     snprintf(name, MAX_PATH + 1, "topic.%d.msg.%d.re_id", global_topic_count, global_msg_count);
     cs_set_int_value(name, msg->data.info.reply_to); 
   }

 /* set indent level */
   snprintf(name, MAX_PATH + 1, "topic.%d.msg.%d.indent", global_topic_count, global_msg_count);
   cs_set_int_value(name, global_indent); 
  
}






static void
set_subtree_data (MSG_TREE_NODE *root, int indent, const char *course, const char *key, long offset, int topic,
                     const char *student, const char *realname, const char *fromstring, int grp)
{

 if(!root)
    return;
 if(indent)
     global_indent++;
 
   set_message_data(root, course, key, offset, topic,student,realname, fromstring, grp);
   
 if(root->reply)
    set_subtree_data(root->reply,INDENT,course, key,offset,topic, student, realname, fromstring, grp);
 if(root->next && (root->next->data.info.reply_to != -1))  /* don't do 'next' branches if they lead to a topic */
    set_subtree_data(root->next,NO_INDENT, course, key,offset,topic,student, realname, fromstring, grp);
  
 if(indent)
     global_indent--;
                 
}



static void
get_fromstring(char *fromstring, int maxlen, const char *course, const char *key, 
           const char *student, const char *student_realname, long offset, int topic, int grp)
{
 char fixed_realname[MAX_NAME + 1];
 char *ptr;
 
 strncpy(fixed_realname,student_realname, MAX_NAME + 1);
/* convert spaces to  underscores */
 while ((ptr = strchr (fixed_realname, ' ')))
    *ptr = '_';


  snprintf
    (fromstring, maxlen, "%s%ccrs%c%s%cid%c%s%ctopic%c%d%cstudent%c%s%crealname%c%s%cloc%c%ld%cgrp%c%d",
     "assign_student_work", QMARK_SUB, EQUAL_SUB, course, AMP_SUB, EQUAL_SUB,
     key, AMP_SUB, EQUAL_SUB, topic, AMP_SUB, EQUAL_SUB, student, AMP_SUB,
     EQUAL_SUB, fixed_realname,AMP_SUB,EQUAL_SUB,offset, AMP_SUB, EQUAL_SUB, grp);
}     



 



static void
set_expanded_assignment_data (char *course, char *key,
		      		int topic, char *student, char *realname,
                      		CONFIG_STRUCT *conf, SESSION *user, long offset, int can_write, int grp)
{
 MSG_TREE_NODE *msg_ptr;
 MSG_TREE_NODE *topic_ptr;
 int msg_count;
 time_t current_time;
 char fromstring[MAX_PATH + 1];
 
  
  build_fac_assign_read_tree(user,  offset, student, &msg_ptr, &topic_ptr, &msg_count, &current_time); /* shared_news_util.c */
  
  if(!msg_ptr || !tree_head)
      cs_critical_error(ERR_CANT_FIND_THIS_OFFSET, "");

   /* is_teacher_hidden() is in shared_news_util.c */
  if(is_teacher_hidden (topic_ptr->data.status, topic_ptr->data.release_time,  
                                        topic_ptr->data.unrelease_time, current_time))
   {                                     
       cs_set_int_value("teacher_hidden", 1);
   }
   
  if(BASIC_STATUS(topic_ptr->data.status) == READ_ONLY)
   {
       cs_set_int_value("read_only", 1);
   } 
       

  get_fromstring(fromstring, MAX_PATH + 1,course, key, student, realname, offset, topic, grp);
  set_command_data (course, key, topic, realname, student, offset, can_write, fromstring, grp);
  
  set_subtree_data (tree_head, NO_INDENT,course,key,offset,topic,student,realname, fromstring, grp);
}





int
main (void)
{
  char course[MAX_PATH + 1];		/* from crs=? command line */
  char key[MAX_KEY + 1];		/* from id=? command line */
  int topic;				/* from topic=? command line */
  char student[MAX_USERNAME + 1];	/* from student =? command line */
  char realname[MAX_NAME + 1];	        /* from realname=? command line */
  long offset;				/* from loc = ? command line */
  int can_write;
  int grp;

  SESSION user;
  CONFIG_STRUCT conf;

  cs_cgi_init();                      /* shared_cs_util.c */

  unsetenv ("CONTENT_TYPE");  /* Internet Explorer seems to need this */
  
  read_parameters (course, key, &topic, student, realname,&offset, &grp);
  read_configuration_file (course, &conf);		/* shared_util.c */
  validate_key (key, &user,  &conf);			/* shared_util.c */
  can_write = has_write_permission(&user, &conf);        /* shared_access.c */

  if (user.group != FACULTY)
       cs_critical_error (ERR_REQUEST_DENIED, "");     			/* shared_cs_util.c */
       
  set_discussion_names (conf.course_path, user.username, grp);	/* shared_news_util.c */
  
  set_expanded_assignment_data (course, key, topic, student, realname, &conf, &user ,offset, can_write, grp);
  
  cs_set_course_info(&conf);		/* shared_cs_util.c */
  cs_set_current_time();		/* shared_cs_util.c */

  cs_cgi_display("assign_student_work", 1);		/* shared_cs_util.c */
  cs_cgi_destroy();					/* shared_cs_util.c */

  return 0;
}

