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

#include "global.h"
#include "custom.h"		/* for date FORMAT strings */
#include "calendar.h"
#include "sqlite3.h"
#include "manhat-lib/shared_cs_util.h"
#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_calendar_util.h"
#include "manhat-lib/shared_super_util.h"
#include "manhat-lib/shared_file_util.h"
#include "manhat-lib/shared_strtrm.h"

int check_end_time( int year, int month, int today);

void
read_parameters ( char *course, char *key, int *event_id)
{
   char temp[40];

   cs_get_optional_parameter("crs", course, MAX_PATH);
   cs_get_required_parameter("id", key, MAX_KEY);
   cs_get_required_parameter("event_id", temp, 39);
   *event_id = atoi(temp); 

}



void
set_end_hour(int error)
{
   int  e_hour;
   char *oper;

   oper = hdf_get_value(global_cgi->hdf, "Query.oper", 0);
   e_hour = hdf_get_int_value(global_cgi->hdf, "Query.e_hour", 0);
   if(oper && strlen(oper) )
   {
       if(e_hour ==0 || error ==0)
       {
           cs_set_int_value( "e_hourstar", 1);
           cs_set_int_value( "error_endtime", 1);
       }

   }
   else
       cs_set_int_value("e_hourstar", 0);
   cs_set_int_value("e_hour", e_hour);

}

void
set_end_min( int error)
{
   int  e_min;
   char *oper;
   
   oper = hdf_get_value(global_cgi->hdf, "Query.oper", 0);
   e_min = hdf_get_int_value(global_cgi->hdf, "Query.e_min", -1);
   if(oper && strlen(oper) )
   {  
       if(e_min == -1 || error ==0)
       {
            cs_set_int_value( "e_minstar", 1);
           cs_set_int_value( "error_endtime", 1);
       }
       else
           cs_set_int_value( "e_minstar", 0);
   }
   cs_set_int_value("e_min", e_min); 
}


void
set_am_pm( int error)
{
   char *oper;
   int am;

   oper = hdf_get_value(global_cgi->hdf, "Query.oper", "");
   am = hdf_get_int_value(global_cgi->hdf, "Query.e_am", 0);
   if(oper && strlen(oper) )
   {
      if(!am || error ==0)
      {
          cs_set_int_value( "e_amstar", 1);
          cs_set_int_value( "error_endtime", 1);
      }
      else
           cs_set_int_value( "e_amstar", 0);
   }

   if(am == 1)
	cs_set_value("event_end_am", "AM");
   else if(am == 2)
	cs_set_value("event_end_am", "PM");

    
}


void
set_general_data( const char *prefix,  char *query,  char *value)
{
   char *oper =0;
   char name[MAX_PATH +1];
   int max;

   if(!strcmp(prefix, "title"))
      max = MAX_CALENDAR_TITLE;
   else   
      max = MAX_CALENDAR_DESC;

   oper = hdf_get_value(global_cgi->hdf, "Query.oper", "");

   snprintf(name, MAX_PATH +1, "%sstar", prefix);
 
   if(oper && strlen(oper))
   {
   
       if(!value || (value && !strlen(value)) ||
		     (value && !strlen(value) > max))
       {
          cs_set_int_value( name, 1);
          cs_set_int_value( "error_title", 0);
       }
       else
          cs_set_int_value( name, 0);
   }
   else
     cs_set_int_value( name, 0);
}





void
set_icon()
{
    char name[MAX_PATH +1];
    char *oper =0;
    int  icon =0;
   
    oper = hdf_get_value(global_cgi->hdf, "Query.oper", "");
    icon= hdf_get_int_value(global_cgi->hdf, "Query.icon", 0);
    if(oper && strlen(oper))
    {
      snprintf(name, MAX_PATH +1, "%sstar", "icon");
       if(icon == 0)
       {
          cs_set_int_value( name, 1);
          cs_set_int_value( "error_icon", 2);
       }
       else
          cs_set_int_value( name, 0);
    } 
    cs_set_int_value("icon", icon);
}

    

void
set_layout_data(int today, int year, int month, const char *crs, 
		const char *key, char *title, char *desc, SESSION *user)
{
   int i;
   char *str;
   struct tm event_date;

   set_general_data( "title", "Query.title", title);
   set_general_data( "desc", "Query.desc", desc);
 
   if(user->group == FACULTY)
   {
      i = check_end_time( year, month, today);
      set_end_hour( i);
      set_end_min( i);
      set_am_pm( i);
   }
   set_icon();

   init_tm(&event_date,year, month, today);
   str = get_selected_timestring(&event_date);
   cs_set_value( "event_date", str);
   cs_set_int_value( "show_para", user->group);
   free(str);
}


void
set_para( CONFIG_STRUCT *conf, const char *crs, const char *key, char *title, char *desc, SESSION *user)
{
   int year,  month,  today,  hour, min;

   year = hdf_get_int_value (global_cgi->hdf, "Query.year", 0);
   month = hdf_get_int_value (global_cgi->hdf, "Query.month", 0);
   today = hdf_get_int_value (global_cgi->hdf, "Query.today", 0);
   hour = hdf_get_int_value (global_cgi->hdf, "Query.hour", 0);
   min = hdf_get_int_value (global_cgi->hdf, "Query.min", -1);

   
   if(!year || !month || !today || !hour || min == -1)
	 cs_critical_error(ERR_PARAM_MISSING, "year, month, today, hour, min");

   cs_set_int_value("year", year);
   cs_set_int_value("month", month);
   cs_set_int_value("day", today);
   cs_set_int_value("s_hour", hour);
   cs_set_int_value("s_min", min);

   set_selected_time(today, year, month); /* shared_calendar_util.c */
   set_hour_min(hour, min, "event_start", "event_start_am");
   cs_set_int_value( "titlelen", MAX_CALENDAR_TITLE);

   set_layout_data( today, year, month, crs, key, title, desc, user);
   cs_set_int_value( "errorReport", 1);
}


void
init_tm_struct(struct tm *mytime, int year, int month, int today, int hour, int min)
{
    mytime->tm_year = year -1900;
    mytime->tm_mon = month -1;
    mytime->tm_mday = today;

    mytime->tm_hour = hour;
    mytime->tm_min = min;
    mytime->tm_sec =0;
    mytime->tm_isdst = -1;

}

int  get_end_time( int *e_hour, int *e_min)
{
    int e_am;
     
    *e_hour = hdf_get_int_value(global_cgi->hdf, "Query.e_hour", 0);
    *e_min = hdf_get_int_value(global_cgi->hdf, "Query.e_min", 0);
    e_am = hdf_get_int_value(global_cgi->hdf, "Query.e_am", 0);

    if(*e_hour ==0 || *e_min == -1 || e_am ==0)
      return 0;
    if(e_am ==2)  /* pm */
    {
       if(*e_hour != 12)
          *e_hour += 12;
    }
    else
    {
       if(*e_hour == 12)
	  *e_hour =0;
    }
      
    return 1;

}    
int
check_end_time( int year, int month, int today)
{
    int s_hour, s_min, e_hour, e_min;
    struct tm s_tm, e_tm;
    time_t s_time, e_time;

    s_hour = hdf_get_int_value(global_cgi->hdf, "Query.hour", 0);
    s_min = hdf_get_int_value(global_cgi->hdf, "Query.min", 0);

    if(!get_end_time( &e_hour, &e_min))
	return 0;

    init_tm_struct(&s_tm, year, month, today, s_hour, s_min);
    s_time = mktime(&s_tm);

    init_tm_struct(&e_tm, year, month, today, e_hour, e_min);
    e_time = mktime(&e_tm);
    if(e_time <= s_time)
        return 0;
    return 1;
}

int
is_all_right( char **title, char **desc, SESSION *user)
{
    int check, year, month, today;
    int len;
    int error_count =0;

   year = hdf_get_int_value (global_cgi->hdf, "Query.year", 0);
   month = hdf_get_int_value (global_cgi->hdf, "Query.month", 0);
   today = hdf_get_int_value (global_cgi->hdf, "Query.today", 0);
     

    hdf_get_copy (global_cgi->hdf, "Query.title", title, "");
    strtrm(*title);
    cs_set_value( "title", *title);
    len = strlen(*title);
    if(!len || len > MAX_CALENDAR_TITLE)
       error_count++;

    hdf_get_copy (global_cgi->hdf, "Query.desc", desc,  "");
    strtrm(*desc);
    cs_set_value( "desc", *desc);
    len = strlen(*desc);
    if(!len || len > MAX_CALENDAR_DESC)
       error_count++;

    if(user->group == FACULTY)
    {
      check= hdf_get_int_value(global_cgi->hdf, "Query.e_hour", 0);
      if(check ==0)
       error_count++;

      check= hdf_get_int_value(global_cgi->hdf, "Query.e_min", -1);
     if(check == -1)
       error_count++;
    
      check= hdf_get_int_value(global_cgi->hdf, "Query.e_am", 0);
      if(check ==0)
         error_count++;

      if(!check_end_time( year, month, today))
         error_count++;
    }
    check = hdf_get_int_value(global_cgi->hdf, "Query.icon", 0);
    if(check ==0)
         error_count++;

   if(error_count > 0)
       return 0; 
    
    return 1;
} 

void
get_shourmin_ehourmin_icon( int *s_hour, int *s_min, int *e_hour, int *e_min, int *icon)
{
       int e_am;

      *s_hour = hdf_get_int_value(global_cgi->hdf, "Query.hour", 0);
      *s_min = hdf_get_int_value(global_cgi->hdf, "Query.min", 0);
      *e_hour = hdf_get_int_value(global_cgi->hdf, "Query.e_hour", 0);
      *e_min = hdf_get_int_value(global_cgi->hdf, "Query.e_min", 0);
       e_am = hdf_get_int_value(global_cgi->hdf, "Query.e_am", 0);
      if(e_am == 2)
      {
	  if(*e_hour != 12)
             *e_hour += 12;	
      }
      else if(e_am ==1)
      {
	 if(*e_hour == 12)
	     *e_hour = 0;
      }
      *icon = hdf_get_int_value(global_cgi->hdf, "Query.icon", 0);
}

void
get_year_month_today( int *year, int *month, int *day)
{
     
      *year = hdf_get_int_value(global_cgi->hdf, "Query.year", 0);
      *month = hdf_get_int_value(global_cgi->hdf, "Query.month", 0);
      *day = hdf_get_int_value(global_cgi->hdf, "Query.today", 0);
}

EVENT_NODE *
initialize_event_node(int s_hour, int s_min, int e_hour, int e_min, int icon, 
		      int new_day, int new_month, int new_year, SESSION *user, 
		      const char *title, const char *desc)
{
     EVENT_NODE *ptr;
     ptr = (EVENT_NODE *)malloc(sizeof(EVENT_NODE));

     strncpy(ptr->event.username, user->username, MAX_USERNAME +1);
     strncpy(ptr->event.realname, user->realname, MAX_NAME +1 );
     strncpy(ptr->event.title, title, MAX_CALENDAR_TITLE +1 );
     strncpy(ptr->event.desc, desc, MAX_CALENDAR_DESC +1);
     ptr->event.year = new_year;
     ptr->event.month =new_month;
     ptr->event.day = new_day;
     ptr->event.s_hour = s_hour;
     ptr->event.s_min = s_min;
     if(user->group == FACULTY)
     {
       ptr->event.e_hour = e_hour;
       ptr->event.e_min = e_min;
     }
     else
     {
       ptr->event.e_hour = s_hour;
       ptr->event.e_min = s_min;
     }

     ptr->event.icon = icon;
     if(user->group == FACULTY)
       strncpy(ptr->event.category,CATEGORY_1, MAX_CATEGORY +1);
     else
       strncpy(ptr->event.category,CATEGORY_2, MAX_CATEGORY +1);
     ptr->next =0;
     return ptr; 
}


EVENT_NODE *
event_once( SESSION *user, const char *title, const char *desc, int event_id)
{
   EVENT_NODE *ptr;
   int s_hour, s_min, e_hour, e_min, icon, year, month, day;

    get_shourmin_ehourmin_icon( &s_hour, &s_min, &e_hour, &e_min, &icon);
    get_year_month_today( &year, &month, &day);

    ptr = initialize_event_node(s_hour, s_min, e_hour,  e_min,  icon, 
		       day, month, year, user, title, desc);
    ptr->event.id = event_id;
    return ptr; 
    
}

 

int
update_event(const char *path, EVENT_NODE *node)
{
    int ret;
    char *stmt;
     
    sqlite3 *db;
    ret = sqlite3_open(path, &db);

    if(ret)
      cs_critical_error(ERR_CALENDAR_DB_OPEN, "update_event");

    stmt = sqlite3_mprintf(
       "update event set title='%q', desc='%q', ehour=%d, emin=%d, icon=%d where id=%d",
       node->event.title, node->event.desc, node->event.e_hour, node->event.e_min,
       node->event.icon, node->event.id
       );
   if(stmt)
   {
       ret = sqlite3_exec(db,stmt, 0, 0, 0); 
       sqlite3_free(stmt);
       if(ret)
       {
          sqlite3_close(db);
          return 0;
       }
   }
   sqlite3_close(db);
   return 1;
}


int
save_data_to_db(CONFIG_STRUCT *conf, SESSION *user, 
		const char *title, const char *desc, int event_id)
{
    char path[MAX_PATH +1];
    EVENT_NODE *node;

    snprintf(path, MAX_PATH +1, "%s%s/%s", conf->course_path, CALENDAR_DIR, EVENT_DB);
    if(!file_exists(path))
	 return 0;

    node = event_once( user, title, desc,  event_id);
    if(!update_event(path, node))
	 return 0;
    return 1;
}


int
main ()
{
  char course[MAX_PATH +1];	/* from crs=? command line */
  char key[MAX_KEY +1];	/* from id=? command line */
  char *title;
  char *desc;
  int action_flag, event_id;

  SESSION user;
  CONFIG_STRUCT conf;

  cs_cgi_init();
  *course = '\0';
  read_parameters ( course, key, &event_id);

  if(!strlen(course))
  {
     validate_super_key(key, &user);  /* shared_super_util.c */
     mk_conf(&user, &conf);           /* shared_calendar.c */ 
  }
  else 
  {
    read_configuration_file (course, &conf);	/* shared_util.c */
    validate_key (key, &user, &conf);	/* shared_util.c */
  }
  if(user.group == STUDENT)
	cs_critical_error(ERR_REQUEST_DENIED, "");


  cs_set_course_info( &conf);   /*shared_cs_util.c/c */

  action_flag = is_all_right( &title, &desc, &user);

  if(action_flag ==0)
  {
      set_para( &conf, course, key, title, desc, &user);
      cs_load_lang("calendar_event_edit");
      cs_cgi_display ( "calendar_event_modify", 0);
  }
  else
  {
      if(save_data_to_db(&conf,  &user, title, desc, event_id))
      {
         cs_set_int_value("success", 1);
         cs_load_lang("calendar_event_edit");
         cs_cgi_display ("calendar_event_modify", 0);
      }
      else
	 cs_critical_error(ERR_CALENDAR_UPDATE_EVENT, "");

  } 
 
  cs_cgi_destroy();

  if(title)
     free(title);
  if(desc)
     free(desc);
  return 0;			/* exit successfully */

}
    
