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

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

#include "ClearSilver.h"

#include "manhat-lib/shared_cs_util.h"
#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_news_util.h"
#include "manhat-lib/shared_person_list.h"
#include "manhat-lib/shared_translate_url.h"
#include "manhat-lib/shared_access.h"
#include "manhat-lib/shared_teamstring.h"
#include "manhat-lib/shared_server_string.h"


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

#define NO_INDENT 0   
#define INDENT 1

#define MAX_HDF_NAME 50


typedef struct expanded_topic_node
{
  int topic;
  struct expanded_topic_node *next;
}
EXPANDED_TOPIC_NODE;



EXPANDED_TOPIC_NODE *expanded_head = 0;	/* list of topics that are expanded */



typedef struct topic_node
{
  int total_msgs;
  int total_unread;
  int total_flagged;
  int expanded;
  int teacher_hidden;              
  int read_only;
  MSG_TREE_NODE *topic_head;
  struct topic_node *next;
  struct topic_node *prev;
}
TOPIC_NODE;


TOPIC_NODE *topic_head = 0;
TOPIC_NODE *topic_tail = 0;



#define MAX_TEAMPART 20

#define MAX_TEAMSTRING 20

typedef struct common_data
{
 char course[MAX_PATH + 1];
 char key[MAX_KEY + 1];
 int grp;
 char fromstring[MAX_PATH + 1];
 char teampart[MAX_TEAMPART + 1];
 int no_topic_type;
 char team;
 int is_faculty;
 int is_fac_teamteach;
 int is_fac_assignments;
 int allow_user_hidden;
 int can_write;         /* does this user have write permission? */
 int capture_mode;      /* are we in capture mode? */
 char teamstring1[MAX_TEAMSTRING + 1];
 char teamstring2[MAX_TEAMSTRING + 1];
 int fixed_font;        /* show msgs in fixed width font? */ 
} COMMON_DATA;

COMMON_DATA common;

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

static void
read_parameters ()
{
  char msg[80];


  cs_get_required_parameter ("id", common.key, MAX_KEY);
  cs_get_required_parameter ("crs", common.course, MAX_PATH);	/* shared_cs_util.c */
  cs_get_required_parameter ("grp", msg, 5);
  common.grp = atoi (msg);
  
}





static
void read_news_filter (NEWS_FILTER * filter, CONFIG_STRUCT *conf)
{
  FILE *fp;
  char filter_path[MAX_PATH + 1];
  int topic;
  EXPANDED_TOPIC_NODE *ptr = 0;

    
 /* if this course is being captured, 
 ** use the following settings 
 */   
 if(common.capture_mode)
  {
      filter->oldest_first = 1;
      filter->show_user_hidden = 1;
      filter->show_teacher_hidden = 1;
      return;
  }  


 /* still here? - need to read the filter file */
  snprintf (filter_path, MAX_PATH + 1, "%s/%s", discussion_path,
	    NEWS_FILTER_FNAME);
  fp = fopen (filter_path, "r");
  if (fp)
    {
      fread (filter, sizeof (NEWS_FILTER), 1, fp);
      while (fread (&topic, sizeof (int), 1, fp) == 1)
	{
	  if (!expanded_head)
	    {
	      expanded_head =
		(EXPANDED_TOPIC_NODE *) malloc (sizeof (EXPANDED_TOPIC_NODE));
	      ptr = expanded_head;
	    }
	  else
	    {
	      ptr->next =
		(EXPANDED_TOPIC_NODE *) malloc (sizeof (EXPANDED_TOPIC_NODE));
	      ptr = ptr->next;
	    }
	  if (!ptr)
	    cs_critical_error (ERR_MALLOC_FAILED, "");
	  ptr->topic = topic;
	  ptr->next = (EXPANDED_TOPIC_NODE *) 0;
	}

      fclose (fp);
    }
  else
    {
      filter->oldest_first = 1;
      filter->show_user_hidden = 1;
      filter->show_teacher_hidden = 1;
    }
}




static void
set_team_members_url(SESSION *user)
{
  char url[MAX_PATH + 1];
  
  snprintf(url, MAX_PATH +1, "%c", user->team);
  cs_set_value("team", url);

  get_team_name(user->team, url);    /* shared_teamstring.c */
  cs_set_value("team_name", url);

  
  
  switch (common.grp)
    {
    case TEAM_DISCUSSION:
       snprintf(url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d",
                              "news_members", common.course, common.key, common.grp);
       cs_set_value("team_members_url", url);
      break;


    case TEAM_TEACH:
       
      snprintf(url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d%s",
      			"news_members", common.course, common.key, common.grp,common.teamstring1);
      cs_set_value("team_members_url", url);
      break;

    default: break;

    }
}





static 
void set_topic_manager_values(NEWS_FILTER *filter)
{  
 char url[MAX_PATH + 1];

   if(common.can_write)
    {
     snprintf(url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d%s", 
                      "news_manage_topic_list",common.course, common.key,
                      common.grp,common.teamstring1);
     cs_set_value("manage_topics_url", url);
    } 
                       

 /* handle urls for list all topics/list only topics visible by students */
   
   if(filter->show_teacher_hidden)
    {
       snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;cmd=%d&amp;from=%s",
	    "news_filter_set", common.course, common.key, common.grp, HIDE_TEACHER_HIDDEN, common.fromstring);
       cs_set_value("teacher_list_only_visible_url", url);
    }   
   else
    {
       snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;cmd=%d&amp;from=%s",
	    "news_filter_set", common.course, common.key, common.grp, SHOW_TEACHER_HIDDEN, common.fromstring);
      cs_set_value("teacher_list_all_topics_url", url);
      	    
    }
}  












static void 
set_new_topic_values(SESSION *user)
{

char url[MAX_PATH + 1];

  if(common.no_topic_type)
      cs_set_int_value("no_topic_type", 1);
      
  if (common.no_topic_type || ((common.grp == ASSIGNMENTS) && !common.is_fac_assignments))
    {
    
      if (user->group == FACULTY)
	{
	            /* AMP_SUB, et. al. are #defined in shared_translate_url.h */		  
         if(common.can_write)
          {	
           if(common.grp == SURVEYS)
             
             snprintf (url, MAX_PATH + 1, "%s?admin=0&amp;id=%s&amp;crs=%s", 
                               "survey_read_info",  common.key, common.course);

           else
             snprintf
	       (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;from=%s%ccrs%c%s%cid%c%s%cgrp%c%d",
	        (common.grp == INTERNET_RESOURCES) ? "link_new_memo" : "news_new_memo",
	        common.course, common.key, common.grp, "news_topic", QMARK_SUB, EQUAL_SUB, common.course,
	        AMP_SUB, EQUAL_SUB, common.key, AMP_SUB, EQUAL_SUB, common.grp);
          
           cs_set_value("new_topic_url", url);
          }
	}
    }
  else  /* this is a group that supports topics */
    {
     if(common.can_write)
      {
      
        snprintf
	(url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;topic=-1%s&amp;reply_to=-1&amp;from=%s%ccrs%c%s%cid%c%s%cgrp%c%d%s",
	 "news_new_memo", common.course, common.key, common.grp, common.teamstring1, "news_topic", QMARK_SUB,
	 EQUAL_SUB, common.course, AMP_SUB, EQUAL_SUB, common.key, AMP_SUB, EQUAL_SUB, common.grp,
	 common.teamstring2);

        cs_set_value("new_topic_url", url);
      }
    }

#undef TEAMSTRING
}






static void
set_news_topic_commands (CONFIG_STRUCT *conf, SESSION *user, NEWS_FILTER *filter)
{
  char url[MAX_PATH + 1];

  cs_set_int_value("classroom_locked", CLASSROOM_LOCKED(conf->misc)? 1 : 0 );
  
  if (only_handouts_enabled (conf))	/* see shared_news_util.c */
   {
      cs_set_int_value("only_handouts_enabled", 1);
            
      if (user->group == FACULTY)
	{
	  /* give teacher a configuration link */
	  snprintf (url,MAX_PATH + 1, "%s?crs=%s&amp;id=%s", "admin_main_menu", common.course, common.key);
          cs_set_value("config_url",url);
          		  
	}
   
      
      snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s", "logout", common.course, common.key);
      cs_set_value("exit_classroom_url", url);
   }   
  else
   {
     /* back button is only for faculty in team_teach module */
     if (common.is_fac_teamteach)  
      {
      snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s", "news_team_list", common.course, common.key);
      cs_set_value("back_button_url", url);
      }

     /* set a url for the main_menu */
    snprintf (url, MAX_URL + 1, "%s?crs=%s&amp;id=%s", "main_menu", common.course, common.key);
    cs_set_value("main_menu_url", url);

   }
   
   
    set_new_topic_values(user);

    if( (user->group == FACULTY) && (!common.capture_mode))
       set_topic_manager_values(filter);

    if( (common.grp == TEAM_DISCUSSION ) || (common.grp == TEAM_TEACH) )
		  set_team_members_url (user);
		  
}






/* does topic_id appear in the expanded topic list */
static int
topic_expanded (int topic_id)
{

  EXPANDED_TOPIC_NODE *ptr;

  for (ptr = expanded_head; ptr; ptr = ptr->next)
    if (ptr->topic == topic_id)
      return 1;

  return 0;

}



/* assumes build_msg_tree() has already been called */
static void
build_topic_list (time_t current_time, int show_teacher_hidden, int *unread_msgs)
{
  TOPIC_NODE *ptr = 0;
  MSG_TREE_NODE *topic_ptr;
  int total_msgs = 0, 
      total_unread = 0,
      total_flagged = 0;
  
  *unread_msgs = 0;
  
  for(topic_ptr = tree_head; topic_ptr; topic_ptr=topic_ptr->next)
   {	  
    if (!topic_head)
    {
      topic_head = (TOPIC_NODE *) malloc (sizeof (TOPIC_NODE));
      if(!topic_head)
	 cs_critical_error(ERR_MALLOC_FAILED,"");
       ptr = topic_head;
       ptr->prev = 0;
    }
    else
    {
      ptr->next = (TOPIC_NODE *) malloc (sizeof (TOPIC_NODE));
      if(!ptr->next)
	 cs_critical_error(ERR_MALLOC_FAILED, "");
      ptr->next->prev = ptr;
      ptr = ptr->next;
    }
   count_topic_msgs(topic_ptr,&total_msgs, &total_unread, &total_flagged);   /* shared_news_util.c */
   *unread_msgs += total_unread;
   ptr->total_msgs = total_msgs;
   ptr->total_unread = total_unread;
   ptr->total_flagged = total_flagged;
   ptr->expanded = common.is_fac_assignments? 0 : common.capture_mode? 1 : topic_expanded (topic_ptr->data.info.msg_id);
   ptr -> teacher_hidden = 
           is_teacher_hidden (topic_ptr->data.status, topic_ptr->data.release_time,   /* shared_news_util.c */
                              topic_ptr->data.unrelease_time, current_time);
   ptr-> read_only = BASIC_STATUS(topic_ptr->data.status) == READ_ONLY? 1 : 0;                           
   ptr->topic_head = topic_ptr;
   ptr->next = 0;
   topic_tail = ptr;
   total_msgs = 0;
   total_unread = 0;
   }
}


	
static void
free_topic_list ()
{
  TOPIC_NODE *ptr;

  while (topic_head)
    {
      ptr = topic_head;
      topic_head = topic_head->next;
      free(ptr);
    } 
}


static void
free_expanded_list()
{
 EXPANDED_TOPIC_NODE *ptr;
 
 while(expanded_head)
  {
   ptr = expanded_head;
   expanded_head = expanded_head -> next;
   free (ptr);
  }
}



static void
get_fromstring ()
{
           /* AMP_SUB, et. al. are #defined in shared_translate_url.h */		  
  snprintf (common.fromstring, MAX_PATH + 1, "%s%ccrs%c%s%cid%c%s%cgrp%c%d",
	    "news_topic", QMARK_SUB, EQUAL_SUB, common.course, AMP_SUB, EQUAL_SUB, common.key,
	    AMP_SUB, EQUAL_SUB, common.grp);

  if (common.team != NOTEAM)
    {
      snprintf (common.teampart, MAX_TEAMPART, "%cteam%c%c", AMP_SUB, EQUAL_SUB, common.team);
      strcat (common.fromstring, common.teampart);
      snprintf (common.teampart, MAX_TEAMPART, "&amp;team=%c", common.team);	/* so we can use it directly */
    }
  else
    *common.teampart = '\0';
}







static
void set_msg_data(const char *base_name, MSG_TREE_NODE *msg)
{

 char *new_str = 0;
 char timestring[MAX_TIMESTRING + 1];
 char name[MAX_HDF_NAME + 1];
 char url[MAX_PATH + 1];
 
  /*is this msg unread? */
  snprintf(name, MAX_HDF_NAME + 1, "%s.is_unread", base_name);
  cs_set_int_value(name, msg->user_data.time_read? 0:1);


  /*is this msg flagged? */
  snprintf(name, MAX_HDF_NAME + 1, "%s.is_flagged", base_name);
  cs_set_int_value(name, msg->user_data.flagged? 1:0);
  
  
  /* does this msg have attachments? */
  snprintf(name, MAX_HDF_NAME + 1, "%s.attachments", base_name);
  cs_set_int_value(name, msg->data.info.attachments);
  

  /* do info url */

  if(common.grp == SURVEYS)
      snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;loc=%ld",
	  "survey_info", common.course, common.key, msg->offset);
  else
       snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;loc=%ld",
	      "news_info", common.course, common.key, common.grp, msg->offset);
   
  snprintf(name,MAX_HDF_NAME + 1,"%s.info_url", base_name);
  cs_set_value(name, url);
    
  
  /* do set 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", common.course, common.key, common.grp, msg->data.info.msg_id,
                          common.fromstring);
   snprintf(name,MAX_HDF_NAME + 1,"%s.flag_url", base_name);                         
   cs_set_value(name, url);  
   
   
   
  /* do read msg url */

   if (common.is_fac_assignments)
    snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;loc=%ld&amp;topic=%d",
		 		 "assign_fac_expand", common.course, common.key,
		 			msg->offset,msg->data.info.topic_id);
  else
   {
     snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;loc=%ld&amp;grp=%d%s",
           "news_read", common.course, common.key, msg->offset, common.grp, common.teampart);
     if(common.fixed_font)
            strcat(url,"&amp;fixed=1");
   }
         
      

  snprintf(name, MAX_HDF_NAME + 1, "%s.read_msg_url", base_name);
  cs_set_value(name, url);
  
  /** set subject **/
  if(strlen(msg->data.info.subject))
   {
    snprintf(name, MAX_HDF_NAME + 1, "%s.subject",base_name);
    
    /* next makes use of undocmented ClearSilver function */
    if(cgi_html_escape_strfunc(msg->data.info.subject,&new_str) == STATUS_OK)
      {
       cs_set_value(name,(char *)new_str);
       if(new_str)
          free(new_str);
      }
    else
       cs_set_value(name,msg->data.info.subject);
    }        
        

  
   /* set sender */  
  snprintf(name, MAX_HDF_NAME + 1, "%s.sender", base_name);
  cs_set_value(name, msg->data.info.sender_realname);
  
  
  /* set time sent */
  snprintf(name, MAX_HDF_NAME + 1, "%s.time_sent", base_name);
  if ( !((common.grp == ANONYMOUS_DISCUSSION) && HIDE_ANONYMOUS_TIMES) )	/* see custom.h */
   {
    strftime (timestring, MAX_TIMESTRING, DOW_DATE_FORMAT,
	      localtime (&(msg->data.info.time_sent)));
    cs_set_value(name, timestring);
   }   
    


  /* set msg_id */
  snprintf(name, MAX_HDF_NAME + 1, "%s.msg_id", base_name);  
  cs_set_int_value(name, msg->data.info.msg_id);
  
  /* set reply_to id */
  if(msg->data.info.reply_to != -1)
   {
     snprintf(name, MAX_HDF_NAME + 1, "%s.re_msg_id", base_name);    
     cs_set_int_value(name, msg->data.info.reply_to);
   }

 /* set indent value */
  snprintf(name, MAX_HDF_NAME + 1, "%s.indent", base_name);    
  cs_set_int_value(name, global_indent);
 
    

}





static void
print_message (MSG_TREE_NODE * msg)
{

  TOPIC_NODE *ptr;
  int found;
  static int teacher_hidden = 0;
  static int read_only = 0;
  char name[MAX_HDF_NAME + 1];
  char url[MAX_PATH + 1];
  
 if(msg->data.info.reply_to == -1)  /* if this is a topic */
 {  
  
  
  /* find the msg in the topic list */
  for(ptr=topic_head, found=0; ptr && !found; ptr = ptr->next) 
    {
     found = (ptr->topic_head == msg);
     if(found)
       break;
    }   
  
  if(!found)   /*this should never happen */
      return;
  
  global_topic_count++;
  global_msg_count = -1;
  
   /* set teacher_hidden */
  teacher_hidden = ptr->teacher_hidden? 1:0;   
  snprintf(name,MAX_NAME + 1, "topic.%d.teacher_hidden", global_topic_count);
  cs_set_int_value(name, teacher_hidden);


   /* set read_only */
  read_only = ptr->read_only ? 1:0;
  snprintf(name,MAX_NAME + 1, "topic.%d.read_only", global_topic_count);
  cs_set_int_value(name, read_only);

  
  /** set msg_id */

  snprintf(name,MAX_HDF_NAME + 1, "topic.%d.msg_id", global_topic_count);
  cs_set_int_value(name, msg->data.info.msg_id);
  
    

  /* handle data for expand/collapse of topic */  
  if (ptr->total_msgs > 1)
   {
    if(ptr->expanded)
     {
      snprintf(name,MAX_HDF_NAME + 1, "topic.%d.is_expanded", global_topic_count);
      cs_set_int_value(name, 1);
     } 
    
    snprintf(name, MAX_HDF_NAME + 1, "topic.%d.expand_url", global_topic_count);
    snprintf(url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;topic=%d&amp;expand=%d&amp;from=%s",
       "news_expand_topic", common.course, common.key, common.grp, msg->data.info.msg_id, ptr->expanded?0:1,
       common.fromstring);
    cs_set_value(name, url);
        
   }
       




  /* do #messages */
    snprintf(name, MAX_HDF_NAME + 1, "topic.%d.total_msgs", global_topic_count);  
    cs_set_int_value(name, ptr->total_msgs);
    
   /* does this TOPIC contain one or more unread msgs? */
    snprintf(name, MAX_HDF_NAME + 1, "topic.%d.total_unread", global_topic_count);  
    cs_set_int_value(name, ptr->total_unread);


   /* does this TOPIC contain one or more flagged  msgs? */
    snprintf(name, MAX_HDF_NAME + 1, "topic.%d.total_flagged", global_topic_count);  
    cs_set_int_value(name, ptr->total_flagged);
  


  /* do 'gather' */
 if (!common.no_topic_type && !common.capture_mode)
   {
        snprintf(name, MAX_HDF_NAME + 1, "topic.%d.gather_url", global_topic_count);  
        if(common.is_fac_assignments)
           snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;gather=_all_&amp;loc=%ld&amp;grp=%d",
                      "assign_gather", common.course, common.key, msg->offset,
                         common.grp);
        else
          snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d%s&amp;gather=_topic_%d",
                      "news_gather", common.course,  common.key, common.grp, common.teamstring1, msg->data.info.msg_id);
               
        if(common.fixed_font)
            strcat(url,"&amp;fixed=1");
  
        cs_set_value(name, url);
   }
   
   
   
   
  /* do user hide/unhide urls */
  
  if(common.allow_user_hidden && !(ptr->total_unread))
   {
    snprintf(url, 
       MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;msg_id=%d&amp;hide=%d%s",
        "news_mark_hidden", common.course, common.key, common.grp, msg->data.info.msg_id,
                         msg->user_data.user_hidden?0:1, common.teamstring1);
    snprintf(name, MAX_HDF_NAME + 1, "topic.%d.%s", global_topic_count,
    					msg->user_data.user_hidden?"unhide_url":"hide_url");
    cs_set_value(name, url);
   }
   
  }   /* if this is a topic */
  
  
  if(msg->data.info.reply_to == -1)   /* if this is a topic */
       snprintf(name, MAX_HDF_NAME + 1, "topic.%d", global_topic_count);
  else
   {  
      global_msg_count++;
      snprintf(name, MAX_HDF_NAME + 1, "topic.%d.msg.%d", global_topic_count,global_msg_count);
   }        
  set_msg_data(name,msg);
  

}







static void
print_subtree (MSG_TREE_NODE *root, int indent)
{

 if(!root)
    return;
 if(indent)
     global_indent++;
 
   print_message(root);
   
 if(root->reply)
    print_subtree(root->reply,INDENT);
 if(root->next && (root->next->data.info.reply_to != -1))  /* don't do 'next' branches if they lead to a topic */
    print_subtree(root->next,NO_INDENT);
  
 if(indent)
    global_indent--;
                 
}


/** ASSUMES set_discussion_names() has already been called **/
static
void write_user_inbox(USER_INBOX_NODE *user_head)
{
 FILE *fp;
 USER_INBOX_NODE *ptr;


 fp = open_user_inbox("w");     /* shared_news_util.c */ 
 if(!fp)                             
    cs_critical_error(ERR_FOPEN_WRITE_FAILED, USER_INBOX_FNAME);
 for(ptr = user_head; ptr; ptr= ptr->next)
 {
  if(fwrite(&ptr->data, sizeof(USER_INBOX_RECORD), 1, fp) != 1)
     cs_critical_error(ERR_FWRITE_FAILED, USER_INBOX_FNAME);
 }
 
 fclose(fp);
}     








/* a topic with an unread msg MUST have its
** USER_INBOX_RECORD for that message set so that
** user_hidden is 0
** In other words, a topic with an unread message is
** automatically 'unhidden' 
*/

static void
adjust_user_hidden_status()
{
 TOPIC_NODE *ptr;
 USER_INBOX_NODE *u_ptr;
 
 user_head = 0;   /* declared globally in shared_news_util.c */
 
 for(ptr = topic_head; ptr; ptr = ptr->next)
  if(ptr->total_unread && ptr->topic_head->user_data.user_hidden)
   {
     ptr->topic_head->user_data.user_hidden = 0;    /* force it to be unhidden in memory */
     if(!user_head)
        user_head = build_user_inbox_list();  /* shared_news_util.c */
     for(u_ptr = user_head; u_ptr; u_ptr=u_ptr->next)
        if(u_ptr->data.msg_id == ptr->topic_head->data.info.msg_id)
          {
            u_ptr->data.user_hidden = 0;  /* force it to be unhidden on disk */
            break;
          }  
   }
  if(user_head)    /* if adjustments were made */
   {
    write_user_inbox(user_head);
    free_user_inbox_list();   /* shared_news_util.c */
   }
}    
     
   



static void
set_topic_data ( NEWS_FILTER * filter, SESSION *user)
{
  TOPIC_NODE *ptr;
  
  if (topic_head)
    {

      for (ptr = filter->oldest_first ? topic_head : topic_tail;
	   ptr; ptr = filter->oldest_first ? ptr->next : ptr->prev)
	{
          if( (filter->show_user_hidden) ||
              !common.allow_user_hidden  ||
              ((!(filter->show_user_hidden)) && (!(ptr->topic_head->user_data.user_hidden))) )
          {    
	   if (ptr->expanded)
              print_subtree (ptr->topic_head, NO_INDENT);
           else
              print_message (ptr->topic_head);
          }    
	}		
      free_topic_list ();
    }			

  free_msg_tree(tree_head);  /* shared_news_util.c */
}





static
void set_sort_order_url(NEWS_FILTER *filter)
{
  
 char url[MAX_PATH + 1];
   
    snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;cmd=%d&amp;from=%s",
	    "news_filter_set", common.course, common.key, common.grp, filter->oldest_first?1:0, common.fromstring);
    cs_set_value("sort_order_url", url);
    
}
   



static void
set_gather_form_data (NEWS_FILTER *filter, CONFIG_STRUCT *conf)
{

#define MAX_STRING (MAX_USERNAME + MAX_NAME + 10)

  P_NODE *person_head, *pptr;
  char value_string[MAX_STRING + 1];
  char name_string[MAX_STRING + 1];
  int i;
  
  
  cs_set_value("gather_form_action", common.is_fac_assignments? "assign_gather": "news_gather");
  cs_set_int_value("fixed_font", common.fixed_font);
  
  if (common.is_fac_assignments || group_uses_name_filter (common.grp) )   /* shared_news_util.c */
    {			
      person_head = build_option_person_list (conf);
      for(i=0, pptr=person_head; pptr; pptr=pptr->next, i++)
       {
         snprintf(name_string, MAX_STRING + 1, "gather.%d.value", i);
         snprintf(value_string, MAX_STRING + 1, "%s:%s", pptr->data.username, pptr->data.realname);
         cs_set_value(name_string, value_string);
         
         snprintf(name_string, MAX_STRING + 1, "gather.%d.name", i);
         cs_set_value(name_string, pptr->data.realname);
       }  

      free_option_person_list (person_head);	/* shared_person_list.c */
    }

}




  


static void
set_hide_sleepy_urls(NEWS_FILTER *filter)
{
   
 TOPIC_NODE *ptr;
 int sleepy_count;
 char url[MAX_PATH + 1];
     
 if(filter->show_user_hidden)
    {
       snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;cmd=%d&amp;from=%s", 
	    "news_filter_set", common.course, common.key, common.grp, HIDE_USER_HIDDEN, common.fromstring);
       cs_set_value("hide_sleepy_url",url);
    }   
       
   else
    {
       /* count topics marked as 'sleepy' by the user */
       for(ptr=topic_head, sleepy_count=0; ptr; ptr=ptr->next)
          if(ptr->topic_head->user_data.user_hidden)
              sleepy_count++;   
       cs_set_int_value("sleepy_count", sleepy_count);       

       snprintf (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;cmd=%d&amp;from=%s",
	    			"news_filter_set", common.course, common.key, 
	    			common.grp, SHOW_USER_HIDDEN, common.fromstring);
	    			
       cs_set_value("list_all_url",url);

    }
}



static
void set_hdf_common_values()
{
char teamstring[2] ="A";

  cs_set_value("crs", common.course);   /* macros #defined in shared_cs_util.h */
  cs_set_value("key", common.key);
  cs_set_int_value("grp", common.grp);

  cs_set_value("from", common.fromstring);
  cs_set_int_value("no_topic_type", common.no_topic_type);
  
  if(common.team != NOTEAM)
   {
    teamstring[0] = common.team;
    cs_set_value("team", teamstring);
   } 

  cs_set_int_value("is_faculty", common.is_faculty);  
  cs_set_int_value("is_fac_teamteach", common.is_fac_teamteach);    
  cs_set_int_value("is_fac_assignments", common.is_fac_assignments);    
  cs_set_int_value("allow_user_hidden", common.allow_user_hidden);    
  cs_set_int_value("can_write", common.can_write);      
  cs_set_int_value("capture_mode", common.capture_mode);        
    
}





static void set_expand_collapse_all_urls()
{
 char url[MAX_PATH + 1];
 
  if (!common.is_fac_assignments && !common.no_topic_type)
    {


     snprintf
   	   (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;topic=-1&amp;expand=1%s&amp;from=%s",
	    "news_expand_topic", common.course, common.key, common.grp, common.teamstring1,common.fromstring);
     cs_set_value("expand_all_url", url);
     
     
     snprintf
   	   (url, MAX_PATH + 1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;topic=-1&amp;expand=0%s&amp;from=%s",
	    "news_expand_topic", common.course, common.key, common.grp, common.teamstring1,common.fromstring);
     cs_set_value("collapse_all_url", url);
     }

}


static
void set_teamstrings()
{
  if (common.is_fac_teamteach)
    {
      snprintf (common.teamstring1, MAX_TEAMSTRING + 1, "&amp;team=%c", common.team);
               /* AMP_SUB, et. al. are #defined in shared_translate_url.h */		  
      snprintf (common.teamstring2, MAX_TEAMSTRING + 1, "%cteam%c%c", AMP_SUB, EQUAL_SUB,
		common.team);
    }
  else
    {
      *common.teamstring1 = '\0';
      *common.teamstring2 = '\0';
    }
}





static void
set_page_data ( CONFIG_STRUCT *conf, SESSION *user)
{

  NEWS_FILTER filter;
  time_t current_time;
  int unread_msgs;

  get_fromstring ();
  common.no_topic_type = !group_uses_topic (common.grp);	/* shared_news_util.c */

  set_teamstrings();
  
  
   /* store all data collected in 'common' data structure as part of the hdf dataset */  
  set_hdf_common_values();
  
  read_news_filter (&filter, conf);                            

  build_msg_tree(user,common.grp,0,filter.show_teacher_hidden, &current_time);   /* shared_news_util.c */
  build_topic_list (current_time,filter.show_teacher_hidden, &unread_msgs);
  free_expanded_list();  /* we've recorded whether a topic is expanded or not */

  if(common.allow_user_hidden && unread_msgs)
      adjust_user_hidden_status();


  set_news_topic_commands (conf, user, &filter);

  
  if (!common.capture_mode)
   {
    set_gather_form_data (&filter, conf);
    set_sort_order_url (&filter);
    set_expand_collapse_all_urls();
   }  
    
    
  if(common.allow_user_hidden && !common.capture_mode)
     set_hide_sleepy_urls(&filter);
     
  
   set_topic_data (&filter,user);
}



static
int user_hiding_enabled(CONFIG_STRUCT *conf)
{
 
 if(common.capture_mode)
    return 0;
    
 switch(common.grp)
 {
 case CLASS_DISCUSSION: return (conf->discussion == 2);
 case STUDENT_LOUNGE:   return (conf->lounge == 2);
 case ANONYMOUS_DISCUSSION : return (conf->anonymous == 2);
 case TEAM_DISCUSSION      : return (conf->team == 2);
 case HANDOUTS_NOTICES     : return (conf->syllabus == 2);
 case INTERNET_RESOURCES   : return (conf->internet == 2);
 case ASSIGNMENTS          : return (conf->assignments == 2);
 case TEAM_TEACH           : return (conf->team_teach == 2);
 case SELFTEST             : return (conf->selftest == 2);
 case LECTURES             : return (conf->lectures == 2);
 case SURVEYS              : return (conf->surveys == 2);
 case PODCASTS             : return (conf->podcasts == 2);
 default                   : return (0);
 }

}

void  set_podcast_subscribe_url(char *course_path, char *course, char *key)
{
   char url[MAX_PATH +1];

   snprintf(url, MAX_PATH +1, "podcast_subscribe?crs=%s&id=%s", course, key);
   cs_set_value("podcast_subscribe_url", url); 
}



void  set_wimpy_url(char *course, char *key)
{
   char url[MAX_PATH +1];
   
   snprintf(url, MAX_PATH +1, "podcast_launch_framaplayer?crs=%s&id=%s&grp=16", course, key);
   cs_set_value("launch_frama_url", url);
}




   
 

int
main (void)
{
  char msg[10];
  SESSION user;
  CONFIG_STRUCT conf;		/* the configuration read from config file */
  

  unsetenv("CONTENT_TYPE");
  
  cs_cgi_init();    /* shared_cs_util.c */


  read_parameters ();


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

    if((user.group != FACULTY) && CLASSROOM_LOCKED(conf.misc) )   /* global.h */
        access_denied_error();
        
  /* sets course_no, semester, course_title, instructor */
  cs_set_course_info(&conf);    /* shared_cs_util.c */
    
  common.can_write = has_write_permission(&user, &conf);   /* shared_access.c */
  common.capture_mode = (conf.access == ACCESS_CAPTURE);   /* are we in capture mode? */
  
  common.allow_user_hidden = user_hiding_enabled(&conf);
  common.is_faculty = (user.group == FACULTY);
  common.is_fac_assignments = (user.group == FACULTY) && (common.grp == ASSIGNMENTS);

  common.fixed_font = USE_FIXED_FONT(conf.misc)? 1: 0;  /* global.h */
  
  
  if ((user.group == FACULTY) && (common.grp == TEAM_TEACH))
    {
      common.is_fac_teamteach = 1;
      cs_get_required_parameter ("team", msg, 5);
      common.team = *msg;   /* switch this teacher's team to that supplied on the command line */
      user.team = common.team;
    }
  else
    {
      common.is_fac_teamteach = 0;
      common.team = NOTEAM;
    }


  set_discussion_names (conf.course_path, user.username, common.grp);	/* shared_news_util.c */

  if(common.grp == PODCASTS)
    {
        set_podcast_subscribe_url(conf.course_path, common.course, common.key);
            set_wimpy_url(common.course, common.key);
    }        
            
  
  set_page_data (&conf, &user);
  
  
  cs_cgi_display ("news_topic", 1);    /* shared_cs_util.c */
  cs_cgi_destroy();        /* shared_cs_util.c */

  
  return 0;
}



