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


#include "global.h"
#include "custom.h"

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


typedef enum {VISIBLE, HIDDEN, R_ONLY, SCHED_NORMAL, SCHED_HIDDEN, UNKNOWN} VISIBILITY;



static void
read_parameters (char *course, char *key, int *grp, long *offset)
{

 char tmp[20];    /* scratch variable */

  cs_get_required_parameter ("crs", course, MAX_PATH);
  cs_set_value("crs", course);
  cs_get_required_parameter ("id", key, MAX_KEY);
  cs_set_value("id", key);
  
  cs_get_required_parameter ("grp", tmp, 5);
  cs_set_value("grp", tmp);
  *grp = atoi(tmp);
  
  cs_get_required_parameter ("loc",tmp, 19);
  cs_set_value("offset", tmp);
  *offset = atol(tmp);
  
}






static
void read_msg(CENTRAL_INBOX_RECORD *msg, long offset)
{

 FILE *fp;
 int fd;
 char inbox_fname[MAX_PATH + 1];  /* full path to central inbox */

 snprintf(inbox_fname,MAX_PATH + 1,"%s%s",central_discussion_path,INBOX_FNAME);
 fp = fopen(inbox_fname,"r");
 if(!fp)                              /* inbox.dat doesn't exist */
   cs_critical_error(ERR_FOPEN_READ_FAILED,"");
 
 fd = fileno(fp);
 get_shared_lock(fd, 1);                      /* shared_lock.c */

 if(fseek( fp, offset, SEEK_SET))
   cs_critical_error(ERR_FSEEK_FAILED,"");
 if(fread(msg,sizeof(CENTRAL_INBOX_RECORD),1,fp) != 1)
   cs_critical_error(ERR_FREAD_FAILED, "");
 
 release_lock(fd);  /* shared_lock.c */
 fclose(fp);
}





static 
void set_subject(char *subject)
{
  char *escaped_subject = (char *) 0;

  cs_set_value("subject", subject);
  
  cs_html_escape_string(subject, &escaped_subject);
  if(escaped_subject)
   {
    cs_set_value("escaped_subject", escaped_subject );
    free(escaped_subject);
   } 

}                                



static
void get_msg_visibility(CENTRAL_INBOX_RECORD *msg, VISIBILITY *status, time_t now)
{
 switch(BASIC_STATUS(msg->status))   /* see macro definition in global.h */
 {
  case NORMAL :        *status = VISIBLE;
                       break;
                
  case TEACHER_HIDDEN: *status = HIDDEN;
                       break;                
                       
  case READ_ONLY:     *status = R_ONLY;
                      break;                       

  case TIMED_RELEASE : if( (msg->unrelease_time && (msg->unrelease_time < now)) ||
                             (msg->release_time > now) )
                           *status = SCHED_HIDDEN;
                       else
                           *status = SCHED_NORMAL;
                       break;
  default:             *status = UNKNOWN;   /* should never happen */
                       break;
 }
}







static void
set_manual_hide_url(VISIBILITY status, const char *course, const char *key, 
					int grp, long offset)
{
  char url[MAX_PATH +1];

  if(status == HIDDEN)
     return;   /* since the message is already manually hidden */
    
  snprintf(url, MAX_PATH +1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;loc=%ld&amp;hide=1",
                                               "news_manage_topic_hide",course,key,grp,offset);
  cs_set_value("manual_hide_url", url);
}






static void
set_manual_unhide_url(VISIBILITY status, const char *course, const char *key, 
					int grp, long offset)
{
  char url[MAX_PATH +1];


  if(status == VISIBLE)
     return;   /* since the message is already a normal msg */
     
  
  snprintf(url, MAX_PATH +1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;loc=%ld&amp;hide=0",
                 "news_manage_topic_hide",course,key,grp,offset);
 
  cs_set_value("manual_unhide_url", url);
}







static void
set_manual_ro_url(VISIBILITY status, const char *course, const char *key, 
					int grp, long offset)
{
  char url[MAX_PATH +1];
  
  /* faculty_only_group() is in shared_news_util.c */
  if( (status == R_ONLY) || faculty_only_group(grp) )
     return;  
     
  
  snprintf(url, MAX_PATH +1, "%s?crs=%s&amp;id=%s&amp;grp=%d&amp;loc=%ld&amp;hide=2",
                 "news_manage_topic_hide",course,key,grp,offset);
  cs_set_value("manual_readonly_url", url);
}






void
set_mm_dd_yyyy(struct tm target_tm,  char *prefix)
{
#define MAX_TMP 30

   char str[MAX_TMP + 1];
   char name[MAX_TMP + 1];
   int month, day, year;

   year = target_tm.tm_year + 1900;


  /* handle month */
   month = target_tm.tm_mon + 1;
   snprintf(name, MAX_TMP, "%s_month", prefix);
   if(month < 10)
    {
      snprintf(str,MAX_TMP, "0%d", month);
      cs_set_value(name, str);
    }
   else
     cs_set_int_value(name, month);


  /* handle day */
   day = target_tm.tm_mday;
   snprintf(name, MAX_TMP, "%s_day", prefix);
   if(day < 10)
    {
      snprintf(str,MAX_TMP, "0%d", day);
      cs_set_value(name, str);
    }
   else
     cs_set_int_value(name, day);


  /* handle year */
   year = target_tm.tm_year + 1900;
   snprintf(name, MAX_TMP, "%s_year", prefix);
   cs_set_int_value(name, year);

#undef MAX_TMP
}







static 
void set_start_date_options(CENTRAL_INBOX_RECORD *msg, VISIBILITY status, time_t now)
{
  struct tm target_tm;
  
  
  if( (status == SCHED_NORMAL) || (status == SCHED_HIDDEN))
      target_tm =  *localtime (&(msg->release_time));
  else
      target_tm = *localtime(&now);
      
      
  set_mm_dd_yyyy(target_tm, "release");
  set_hour_minute_ampm(&target_tm, "release"); /* shared_time.c */

}






void set_end_date_options(CENTRAL_INBOX_RECORD *msg, VISIBILITY status, time_t now)
{
  struct tm target_tm;
  
  
  if( ((status == SCHED_NORMAL) || (status == SCHED_HIDDEN)) && (msg->unrelease_time) )
     {
      target_tm =  *localtime (&(msg->unrelease_time));
      set_mm_dd_yyyy(target_tm, "unrelease");
     }
  else
      target_tm = *localtime(&now);

   set_hour_minute_ampm(&target_tm, "unrelease"); /* shared_time.c */
}







static 
void set_schedule_option(CENTRAL_INBOX_RECORD *msg, VISIBILITY status)
{
 time_t now;
 
 now = time(NULL);

 set_start_date_options(msg,status,now); 
 set_end_date_options(msg,status,now);
}

  
  
  


  
  
static void 
set_visibility_values(VISIBILITY status, time_t release_time, time_t unrelease_time)
{
  char timestring[MAX_TIMESTRING + 1];


  cs_set_int_value("raw_status", status);   /* probably useless, but we'll provide it anyway */
  /* these are more human readable representations of status */
  switch(status)
   {
      case VISIBLE: 		cs_set_value("status", "VISIBLE");
                                break;
                    
      case HIDDEN:              cs_set_value("status", "HIDDEN");
                                break;
                  
      case R_ONLY:              cs_set_value("status", "R_ONLY");
                                break;

      case SCHED_NORMAL:        cs_set_value("status", "SCHED_NORMAL");
                                break;
 
      case SCHED_HIDDEN:        cs_set_value("status", "SCHED_HIDDEN");
                                break;

      case UNKNOWN:             cs_set_value("status", "UNKNOWN");
                                break;                  


      default:     	        cs_set_value("status", "UNKNOWN");
                                break;                  
                         
   }
   
     /* If scheduled, set the release and unrelease times */
  if( (status == SCHED_HIDDEN)  || (status == SCHED_NORMAL) )
      {
        strftime (timestring, MAX_TIMESTRING, DOW_DATE_TIME_FORMAT, localtime (&release_time) );
	cs_set_value("release_time", timestring);

        if(unrelease_time)
	  {
             strftime (timestring, MAX_TIMESTRING, DOW_DATE_TIME_FORMAT, localtime (&unrelease_time) );
	     cs_set_value("unrelease_time", timestring);
	  }
      
      }
}            





static 
void set_form_data(  char *course,  char *key, int grp, long offset, SESSION *user, CONFIG_STRUCT *conf)
{
#define MAX_OFFSET_STRING 20
 CENTRAL_INBOX_RECORD msg;
 VISIBILITY visible;
 time_t now;

 now = time(NULL);

 set_discussion_names (conf->course_path, user->username, grp);   /* shared_news_util.c */
 read_msg(&msg, offset);

 cs_set_course_info(conf);
 cs_set_current_time();
  
 cs_set_value("grp_uses_topic", group_uses_topic(grp)? "1" :"0");

 get_msg_visibility(&msg,&visible,now);
 set_visibility_values(visible, msg.release_time, msg.unrelease_time);
  
 set_subject(msg.info.subject);
 set_manual_hide_url(visible, course,key, grp, offset);
 set_manual_unhide_url(visible, course,key,grp,offset);
 set_manual_ro_url(visible, course, key,grp,offset);

 set_schedule_option(&msg,visible);

#undef MAX_OFFSET_STRING
 
} 
 


int
main ()
{
  char course[MAX_PATH + 1];	/* from crs=? command line */
  char key[MAX_KEY + 1];	/* from id=? command line */
  long offset;                  /* from loc=? command line */
  int grp;                      /* from grp=? command line */
  
  SESSION user;
  CONFIG_STRUCT conf;	

  cs_cgi_init();

  read_parameters (course, key, &grp, &offset);
  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, "");
  
  set_form_data(course, key, grp, offset, &user, &conf);

  cs_cgi_display("news_manage_sched_form", 1);
  cs_cgi_destroy(); 
  return 0;		
}

