#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_date( int year, int month, int today);
int check_end_time(int year, int month, int today);

void
read_parameters ( char *course, char *key)
{

   cs_get_optional_parameter("crs", course, MAX_PATH);
   cs_get_required_parameter("id", key, MAX_KEY);
}



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("end_event_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("end_event_min", e_min);
}

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

   oper = hdf_get_value(global_cgi->hdf, "Query.oper", 0);
   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("end_event_am", "AM");
   else if(am == 2)
	cs_set_value("end_event_am", "PM");

    
}


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

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

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

   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_enddate_data(int error, int year, int month, int day)
{
   char *oper =0, *p =0;
   char name[MAX_PATH +1];
   char de_value[MAX_PATH +1];

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

   p = hdf_get_value(global_cgi->hdf, "Query.enddate", 0);

   snprintf(name, MAX_PATH +1, "%sstar", "enddate");
   if(oper && strlen(oper))
   {
       if(!p  || error == 0)
       {
          cs_set_int_value( name, 1);
          cs_set_int_value( "error_enddate", 4);
       }
       else
          cs_set_int_value( name, 0);

      snprintf(name, MAX_PATH +1, "%svalue", "enddate");
      cs_set_value( name, p);
   }
   else
   {
     cs_set_int_value( name, 0);
     snprintf(name, MAX_PATH +1, "%svalue", "enddate");
     snprintf(de_value, MAX_PATH +1, "%s%d/%s%d/%d", month <10 ? "0":"", month, day<10 ? "0":"",day,year);
     cs_set_value( name, de_value);
   }
}



void
set_icon_freq( const char *prefix,  char *query, int max)
{
    char name[MAX_PATH +1];
    char *oper =0;
    int  freq =0, flag =0;
   
    if(!strcmp(prefix, "icon")) 
       flag =1;
    oper = hdf_get_value(global_cgi->hdf, "Query.oper", 0);
    freq = hdf_get_int_value(global_cgi->hdf, query, 0);

    if(oper && strlen(oper))
    {
      snprintf(name, MAX_PATH +1, "%sstar", prefix);
       if(freq == 0)
       {
          cs_set_int_value( name, 1);
          snprintf(name, MAX_PATH +1, "error_%s", prefix);
	  if(flag == 1)
             cs_set_int_value( name, 3);
	  else
             cs_set_int_value(name, 2);
       }
       else
          cs_set_int_value( name, 0);
    } 
    if(flag)
	cs_set_int_value("icon", freq);
    else
	cs_set_int_value("freq", freq);

}

    

void
set_layout_data(int today, int year, int month, 
		const char *crs, const char *key, char *title, char *desc, SESSION *user)
{
   char url[MAX_PATH +1];
   int i, check =1;
   int freq;

   set_general_data( "title", "Query.title", title);
   set_general_data( "desc", "Query.desc", desc);
   if(user->group == FACULTY)
   {
     freq = hdf_get_int_value(global_cgi->hdf, "Query.freq", 0);  /* freq = 1 mean event will happen once */
     if(freq != 0 && freq != 1)
       check = check_end_date( year, month, today);
     set_enddate_data( check, year, month, today);

     i = check_end_time( year, month, today);
     set_end_hour( i);
     set_end_min( i);
     set_am_pm( i);
     set_icon_freq( "freq", "Query.freq", 6);
     snprintf(url, MAX_PATH +1, "%s?crs=%s&amp;id=%s&amp;year=%d&amp;month=%d&amp;today=%d", 
		   CALENDAR_PICK,crs,key, year, month, today);  
      cs_set_value("pickdateurl", url);
   }
   set_icon_freq( "icon", "Query.icon", 4);
}


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");


   set_selected_time(today, year, month); /* shared_cs_util.c */
   set_hour_min(hour, min, "hourmin", "hourmin_am");
   cs_set_int_value("titlelen", MAX_CALENDAR_TITLE);
   set_layout_data(today, year, month, crs, key, title, desc, user);
   if(user->group == FACULTY)
      cs_set_int_value( "faculty", 1);
       
}



int count_slash(char *p)
{
   int i, len, count =0;

   len = strlen(p);
   for(i =0; i<len; i++)
   {
      if( p[i] != '/' && !isdigit(p[i]) )
	  return 0;

      if(p[i] == '/')
	  count++;
   }
   if(count == 2)
	return 1;
  return 0;    
}

void
parse_end_date( const char *end_date, int *end_year, int *end_month, int *end_day)
{
    char *ptr, *ptr2;
    char temp[MAX_END_DATE_STR +1];

    strncpy(temp, end_date, MAX_END_DATE_STR +1);
    ptr = strchr(temp, '/');
    if(ptr)
    {
           *ptr = '\0';
           *end_month = atoi(temp);
           ptr++;
           ptr2 = strchr(ptr, '/');
          if(ptr2)
          {
            *ptr2 = '\0';
           *end_day = atoi(ptr);
             ptr2++;
            *end_year = atoi(ptr2);
         }
    }
}


int
get_end_date( int *e_year, int *e_month, int *e_day)
{
    char *p;
    int len;

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

    len = strlen(p);

    if(!len)
	return 0;
    if(len != 10)
	return 0;

    if(!count_slash(p))
	return 0;
    parse_end_date(p, e_year, e_month, e_day);

            
   return 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
check_end_date( int s_year, int s_month, int s_day)
{
   int e_year, e_month, e_day;
   int s;
   struct tm s_tm, e_tm;
   time_t s_time, e_time;

   s = get_end_date( &e_year, &e_month, &e_day);
   if(s ==0)
	return 0;
   
   if( e_month <= 0 || e_month > 12)
	return 0;
   if(e_day > get_month_days(e_month, e_year))
	return 0;
   
   init_tm_struct(&e_tm, e_year, e_month, e_day, 10, 10);
   e_time = mktime(&e_tm);

   init_tm_struct(&s_tm, s_year, s_month, s_day, 10, 10);
   s_time = mktime(&s_tm);

   if(e_time <= s_time)
      return 0;
   return 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 get_week_day_int(int year, int month, int day)
{
   struct tm mytime;
   mytime.tm_mon = month -1;
   mytime.tm_mday = day;
   mytime.tm_year = year -1900;
   mytime.tm_hour = 8;
   mytime.tm_min = 30;
   mytime.tm_sec = 0;
   mytime.tm_wday = 0;
   mytime.tm_isdst = -1;
   mktime(&mytime);
   return mytime.tm_wday;
}

int  verify_event_on_MWF()
{
     int wday = -1;
     int year, month, 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);

     wday = get_week_day_int(year, month, day);
     if(wday == 1 || wday == 3 || wday == 5)
	    return 1;
     return 0;
	   
}
int  
verify_event_on_TTh()
{
     int wday = -1;
     int year, month, 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);

     wday = get_week_day_int(year, month, day);
     if(wday == 2 || wday == 4)
	  return 1;
     return 0;
}

int
verify_MWF_TTh( int frequency)
{
     if(frequency == 4)
        return  verify_event_on_MWF();
     else if (frequency == 5)
        return  verify_event_on_TTh();
     return 0;
}

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

   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( "titlevalue", *title);
    len = strlen(*title);
    if(!len || len > MAX_CALENDAR_TITLE)
	 return 0;

    hdf_get_copy (global_cgi->hdf, "Query.desc", desc,  "");
    strtrm(*desc);
    cs_set_value("descvalue", *desc);
    len = strlen(*desc);
    if(!len || len > MAX_CALENDAR_DESC)
	 return 0;
    if(user->group == FACULTY)
    {
      check= hdf_get_int_value(global_cgi->hdf, "Query.e_hour", 0);
      if(check ==0)
	 return 0;

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

       if(!check_end_time( year, month, today))
        return 0;

       check= hdf_get_int_value(global_cgi->hdf, "Query.freq", 0);
      if(check ==0)
	 return 0;

      if(check !=1)
      {
       if(check == 4 || check == 5)
       {
         if(!verify_MWF_TTh( check))
	   return check;
       } 
	if(!check_end_date( year, month, today))
	  return 0;
      }
    }
    
    check = hdf_get_int_value(global_cgi->hdf, "Query.icon", 0);
    if(check ==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; 
}

int 
get_new_day(int *start_day, int *start_month, int *start_year, int days, 
		int end_year, int end_month, int end_day, int add_days)
{
     *start_day += add_days;

     if(*start_day > days)
     {
        *start_month += 1;
	*start_day = *start_day - days;
        if(*start_month > 12)
	{
	   *start_year += 1;	
	   *start_month = 1;
	}
     }
     if(*start_year < end_year)
	 return 1; 
     else if(*start_month < end_month && *start_year == end_year)
	 return 1;
     else if(*start_month == end_month && *start_year == end_year)
     {
        if(*start_day <= end_day)
	  return 1;
     }
     return 0;
}


EVENT_NODE *
event_weekly_expend( SESSION *user, const char *title, const char *desc)
{
     int start_day;
     int start_month;
     int start_year;
     int s_hour, s_min, e_hour, e_min, icon;
     int e_year, e_month, e_day;
     int days;
     EVENT_NODE *head =0, *current=0, *ptr;
     
     days = get_month_days(start_month, start_year);
     get_year_month_today( &start_year, &start_month, &start_day);
     days = get_month_days(start_month, start_year);
     get_shourmin_ehourmin_icon( &s_hour, &s_min, &e_hour, &e_min, &icon);
     get_end_date( &e_year, &e_month, &e_day);

     head = initialize_event_node(s_hour,  s_min,  e_hour,  e_min, icon, 
		      start_day, start_month, start_year, user, 
		      title, desc);
    current = head;
    while(get_new_day(&start_day, &start_month, &start_year, days, e_year, e_month, e_day, 7))
     {
         ptr = 	initialize_event_node(s_hour, s_min, e_hour, e_min, icon, start_day, 
			   start_month, start_year, user, title, desc);
         current->next = ptr;
	 current = ptr;
	 days = get_month_days(start_month, start_year);
     }
    return head;
}
int get_new_month(int *start_day, int *start_month, int *start_year, 
		int end_year, int end_month, int end_day)
{
      int days;
      *start_month = *start_month +1;
      if(*start_month > 12)
      {
	  *start_month = 1;
	  *start_year += 1;
      }
      days = get_month_days(*start_month, *start_year);
      if(*start_day > days)
	    *start_day = days;
     if(*start_year < end_year)
	 return 1; 
     else if(*start_month < end_month && *start_year == end_year)
	 return 1;
     else if(*start_month == end_month && *start_year == end_year)
     {
        if(*start_day <= end_day)
	  return 1;
     }
     return 0;
}

EVENT_NODE *
event_monthly_expend( SESSION *user, const char *title, const char *desc)
{
     int start_day;
     int start_month;
     int start_year;
     int s_hour, s_min, e_hour, e_min, icon;
     int e_year, e_month, e_day;
     EVENT_NODE *head =0, *current=0, *ptr;

     get_year_month_today( &start_year, &start_month, &start_day);
     get_shourmin_ehourmin_icon( &s_hour, &s_min, &e_hour, &e_min, &icon);
     get_end_date( &e_year, &e_month, &e_day);

     head = initialize_event_node(s_hour,  s_min,  e_hour,  e_min, icon, 
		      start_day, start_month, start_year, user, 
		      title, desc);
    current = head;
    while(get_new_month(&start_day, &start_month, &start_year, e_year, e_month, e_day))
     {
         ptr = 	initialize_event_node(s_hour, s_min, e_hour, e_min, icon, start_day, start_month,
			 start_year, user, title, desc);
         current->next = ptr;
	 current = ptr;
     }
    return head;
}

EVENT_NODE *
event_MWF_expend( SESSION *user, const char *title, const char *desc)
{
     int wday = -1;
     int start_day;
     int start_month;
     int start_year;
     int days;
     int s_hour, s_min, e_hour, e_min, icon;
     int e_year, e_month, e_day;
     EVENT_NODE *head =0, *current=0, *ptr;
     
     get_year_month_today( &start_year, &start_month, &start_day);
     get_shourmin_ehourmin_icon( &s_hour, &s_min, &e_hour, &e_min, &icon);
     get_end_date( &e_year, &e_month, &e_day);
     days = get_month_days(start_month, start_year);
     head = initialize_event_node(s_hour,  s_min,  e_hour,  e_min, icon, 
		      start_day, start_month, start_year, user, 
		      title, desc);
     current = head;
     wday = get_week_day_int(start_year, start_month, start_day);
    while(get_new_day(&start_day, &start_month, &start_year, days, e_year, e_month, e_day, wday == 5 ? 3 :2))
     {
         ptr = 	initialize_event_node(s_hour, s_min, e_hour, e_min, icon, start_day, start_month,
			 start_year, user, title, desc);
         current->next = ptr;
	 current = ptr;
	 days = get_month_days(start_month, start_year);
         wday = get_week_day_int(start_year, start_month, start_day);
     }
    return head;
      
}
EVENT_NODE *
event_TTh_expend( SESSION *user, const char *title, const char *desc) 
{
     int wday = -1;
     int start_day;
     int start_month;
     int start_year;
     int days;
     int s_hour, s_min, e_hour, e_min, icon;
     int e_year, e_month, e_day;
     EVENT_NODE *head =0, *current=0, *ptr;
     
     get_year_month_today( &start_year, &start_month, &start_day);
     get_shourmin_ehourmin_icon( &s_hour, &s_min, &e_hour, &e_min, &icon);
     get_end_date( &e_year, &e_month, &e_day);
     days = get_month_days(start_month, start_year);
     head = initialize_event_node(s_hour,  s_min,  e_hour,  e_min, icon, 
		      start_day, start_month, start_year, user, 
		      title, desc);
    
    current = head;
    wday = get_week_day_int(start_year, start_month, start_day);
    while(get_new_day(&start_day, &start_month, &start_year, days, e_year, e_month, e_day, wday == 2 ? 2 :5))
     {
         ptr = 	initialize_event_node(s_hour, s_min, e_hour, e_min, icon, start_day, start_month,
			 start_year, user, title, desc);
         current->next = ptr;
	 current = ptr;
	 days = get_month_days(start_month, start_year);
         wday = get_week_day_int(start_year, start_month, start_day);
     }
    return head;
}

EVENT_NODE *
event_once( SESSION *user, const char *title, const char *desc)
{
   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);

    return ptr; 
    
}

EVENT_NODE *
expend_event( SESSION *user, const char *title, const char *desc)
{
    EVENT_NODE *head =0;
    int freq;
    if(user->group == FACULTY)
       freq = hdf_get_int_value(global_cgi->hdf, "Query.freq", 0);
    else
        freq =1;

    if(freq == 1)
	head = event_once( user, title, desc);
    else if(freq == 2) 
	 head = event_weekly_expend( user, title, desc);
    else if(freq == 3)
	 head = event_monthly_expend( user, title, desc);
   else if(freq == 4)
	 head = event_MWF_expend( user, title, desc);
   else if(freq ==5)
	 head = event_TTh_expend( user, title, desc); 
    return head;
}
 

void
create_db(const char *path, int id)
{
    int ret;
    char *stmt;
     
    sqlite3 *db;
    ret = sqlite3_open(path, &db);

    if(ret)
       cs_critical_error(ERR_DB_OPEN, "create_db");

    ret = sqlite3_exec(db, 
     "create table event( Id integer primary key, username varchar(20), realname varchar(35), title varchar(30), desc text, year integer, month integer, day integer, shour integer, smin integer, ehour integer, emin integer, icon integer, category varchar(25) )",
       0,0,0);
    if(ret)
    {
       sqlite3_close(db);
       cs_critical_error(ERR_DB_CREATE_ERROR, "create_db");
    }
    stmt = sqlite3_mprintf(
       "insert into event values(%d, '%q', '%q', '%q', '%q', 0,0,0,0,0,0,0,0, '%q')",
         id, "dummy", "dummy", "dummy", "dummy", "dummy");
    if(stmt)
    {
        ret = sqlite3_exec(db, stmt, 0,0,0);
        sqlite3_free(stmt);
    }

    if(ret)
    {
       sqlite3_close(db);
       cs_critical_error(ERR_DB_INSERT, "create_db");
    }
    sqlite3_close(db);

}

int
get_event_id()
{
    int seed, i;
    seed = time(NULL);
   srand(seed);
   i = 1000+(int)(9000.0 *rand()/(RAND_MAX + 1000.0));
   return i;
}

void
insert_db(CONFIG_STRUCT *conf, EVENT_NODE *head)
{
    EVENT_NODE  *ptr;
    char path[MAX_PATH +1];
    sqlite3 *db;
    int ret;
    char *stmt;

    snprintf(path, MAX_PATH +1, "%s%s/%s", conf->course_path, CALENDAR_DIR, EVENT_DB);
     
    ret = sqlite3_open(path, &db);

    if(ret)
	 cs_critical_error(ERR_DB_OPEN, "insert_db");

    ret = sqlite3_exec(db,
                  "Begin transaction insert_calendar_event", 0,0,0);

    for(ptr = head; ptr; ptr = ptr->next)
    {
       stmt = sqlite3_mprintf(
       "insert into event values(NULL, '%q', '%q', '%q', '%q',%d,%d,%d,%d,%d,%d,%d,%d, '%q')",
        ptr->event.username, ptr->event.realname, ptr->event.title, ptr->event.desc, 
	ptr->event.year, ptr->event.month, ptr->event.day,
	ptr->event.s_hour, ptr->event.s_min, ptr->event.e_hour, ptr->event.e_min,
	ptr->event.icon,
	ptr->event.category);
       if(stmt)
       {
	  ret =sqlite3_exec(db, stmt, 0,0,0);
	  sqlite3_free(stmt);
	  if(ret)
	  {
	      ret = sqlite3_exec(db,
		 "rollback transaction insert_calendar_event", 0,0,0);
	      sqlite3_close(db);
	      cs_critical_error(ERR_DB_INSERT, "insert_db");
	  }
       }
    }
    ret = sqlite3_exec(db,"commit transaction insert_calendar_event", 0,0,0);
    ret = sqlite3_exec(db,"end transaction insert_calendar_event", 0,0,0);
    sqlite3_close(db);
     
}

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

    snprintf(path, MAX_PATH +1, "%s%s", conf->course_path, CALENDAR_DIR);
    if(!file_exists(path))
    {
       mkdir(path, 0770);
       snprintf(path, MAX_PATH +1, "%s%s/%s", conf->course_path, CALENDAR_DIR, EVENT_DB);
       id = get_event_id();
       create_db(path, id);
    }
    head = expend_event( user, title, desc);
    insert_db(conf, head);
    free_event_list(head);
}


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;

  SESSION user;
  CONFIG_STRUCT conf;
  *course = '\0';

  cs_cgi_init();
  read_parameters ( course, key);

  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);   

  action_flag = is_all_right( &title, &desc, &user);
  
  if(action_flag == 4 || action_flag ==5)
  {
      if(action_flag == 4)
         cs_set_value( "freq_error_code", "MWF");
      else
         cs_set_value( "freq_error_code", "TTh");
      cs_cgi_display ("calendar_event_edit", 1);
  }
  else if(action_flag ==0)
  {
      set_para( &conf, course, key, title, desc, &user);
      cs_cgi_display ("calendar_event_edit", 1);
  }
  else
  {
      save_data_to_db(&conf,  &user, title, desc);
      cs_set_int_value("print_success", 1);
      cs_cgi_display ("calendar_event_edit", 1);

  } 
 
  cs_cgi_destroy();

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

}
    
