#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "sqlite3.h"
#include "global.h"
#include "custom.h"		/* for date FORMAT strings */
#include "calendar.h"		/* for date FORMAT strings */
#include "manhat-lib/shared_calendar_util.h"
#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_cs_util.h"
#include "manhat-lib/shared_super_util.h"
#include "manhat-lib/shared_file_util.h"



EVENT_LIST *list=0;


int callback(void *p_data, int num_fields, char **p_fields, char **p_col_name)
{
    EVENT_NODE *ptr;

    ptr = (EVENT_NODE *)malloc(sizeof(EVENT_NODE));

    ptr->event.id = atoi(p_fields[0]);
    ptr->event.year = atoi(p_fields[1]);
    ptr->event.month = atoi(p_fields[2]);
    ptr->event.day = atoi(p_fields[3]);
    ptr->event.icon = atoi(p_fields[4]);
    ptr->next =0;

    if(!list->head)
	 list->head = ptr;
    else
        list->current->next = ptr;
    list->current = ptr; 

   return 0;  
}

int 
get_event(CONFIG_STRUCT *conf, int year, int month, int day, int e_year, int e_month, int e_day)
{
    int ret, month_days;
    int nrecs =0;
    char *errmsg =0;
    char select[MAX_PATH +1]; 
    char db_name[MAX_PATH +1]; 
    sqlite3 *db;
   
    snprintf(db_name, MAX_PATH +1, "%s%s/%s", conf->course_path, CALENDAR_DIR, EVENT_DB);
    if(!file_exists(db_name))
	  return 0;

    list = (EVENT_LIST *)malloc(sizeof(EVENT_LIST));
    list->head =0;
    list->current =0;
    

    if(day > e_day)
    {
       month_days = get_month_days(month, day);
       snprintf(select, MAX_PATH +1, 
	     "select id, year, month, day, icon from event where "
	     " year=%d and month=%d and day between %d and %d or"
	     " year=%d and month=%d and day between %d and %d ",
	       year,  month, day, month_days, e_year, e_month, 1, e_day );
    }
    else
    {
       snprintf(select, MAX_PATH +1, 
	     "select id, year, month, day, icon from event where "
	     " year=%d and month=%d and day between %d and %d ",
	       year,  month,  day, e_day);
    }
    ret = sqlite3_open(db_name, &db);
    if(ret)
      return 0; 

    ret = sqlite3_exec(db,
	  select,
          callback,
          &nrecs,
          &errmsg);
    if(errmsg)
    {
       sqlite3_free(errmsg);
       sqlite3_close(db);
       return 0; 
    }
    sqlite3_close(db);
    return 1;
}


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_nav(int year, int month, int selected_day,  const char *course, const char *key)
{
     int pre_year, pre_month, next_year, next_month;
     char url[MAX_PATH +1];

     get_pre_next(year, month, &pre_year, &pre_month, &next_year, &next_month);


     snprintf(url, MAX_PATH +1, "%s?crs=%s&amp;id=%s&amp;year=%d&amp;month=%d&amp;today=%d", 
		     CALENDAR, course, key, pre_year, pre_month, 1);
     cs_set_value("preurl", url);

     snprintf(url, MAX_PATH +1, "%s?crs=%s&amp;id=%s&amp;year=%d&amp;month=%d&amp;today=%d", 
		     CALENDAR, course, key, next_year, next_month, 1);
     cs_set_value("nexturl", url);

     snprintf(url, MAX_PATH +1, "%s?crs=%s&amp;id=%s", CALENDAR, course, key);
     cs_set_value( "todayurl", url);

     snprintf(url, MAX_PATH +1, "%s?crs=%s&amp;id=%s&amp;year=%d&amp;month=%d&amp;today=%d", 
		     CALENDAR_SLOT, course, key, year, month, selected_day);
     cs_set_value( "sloturl", url);
     
}

void
set_body_calendar(int year, int month, int selected_day,  const char *course, const char *key, int today) 
{
      int  start, month_days;
      char url[MAX_PATH +1];
      start = get_this_month_start_day( year,  month );
      month_days = get_month_days(month, year);
      cs_set_int_value("month_name", month);
      cs_set_int_value("year", year);
      cs_set_int_value("start", start);
      cs_set_int_value("month_days", month_days);
      cs_set_int_value("today", today);
      cs_set_int_value("selected_day", selected_day);
      snprintf(url, MAX_PATH +1, "calendar?crs=%s&amp;id=%s&amp;year=%d&amp;month=%d&amp;today=", 
		      course, key, year, month);
      cs_set_value("common_url", url); 

}

void
set_week_days( struct tm mytime[7], const char *course, const char *key, int selected_day, 
		CONFIG_STRUCT *conf)
{
    char name[MAX_PATH +1];
    char url[MAX_PATH +1];
    int i, j =0;

    for(i =0; i<7; i++)
    {
	j =0;
        snprintf(name, MAX_PATH +1, "wday.%d.w", i);
        cs_set_int_value( name, mytime[i].tm_wday);

        snprintf(name, MAX_PATH +1, "wday.%d.mday", i);
        cs_set_int_value( name, mytime[i].tm_mday);

        snprintf(name, MAX_PATH +1, "wday.%d.is_selected", i);
        if(selected_day == mytime[i].tm_mday)
           cs_set_int_value( name, 1);
	else
           cs_set_int_value( name, 0);

        snprintf(name, MAX_PATH +1, "wday.%d.url", i);
	snprintf(url, MAX_PATH +1, "%s?crs=%s&amp;id=%s&amp;year=%d&amp;month=%d&amp;today=%d", CALENDAR, course, key,
		      mytime[i].tm_year + 1900, mytime[i].tm_mon +1, mytime[i].tm_mday);	
        cs_set_value( name, url);
	if(list && list->head)
	{
	    for(list->current = list->head; list->current; list->current = list->current->next)
	    {
		if(list->current->event.day == mytime[i].tm_mday &&
		    list->current->event.year == mytime[i].tm_year +1900 &&
		    list->current->event.month == mytime[i].tm_mon +1)
		 {
                     snprintf(name, MAX_PATH +1, "wday.%d.icon.%d", i, j);
		     cs_set_int_value( name, list->current->event.icon);
		     j++;
		 } 
		    
	    }
	}
    }
}

int 
set_week_time(int start, int year, int month, const char *course, const char *key,  CONFIG_STRUCT *conf)
{
    struct tm mytime[7];
    int i, j =0;
    int days = get_month_days( month, year);

    for(i = 0; i < 7; i++)
    {
       if(start + i > days)
       {
           mytime[i].tm_mday = j +1;
            j++;
           if(month +1 >12)    /* start new year */
	   {
	       mytime[i].tm_mon = 0;
	       mytime[i].tm_year = year +1 - 1900;
	       month = 1;
	       year = year +1;
	   }
	  else    /* start new month */
	  {
	        mytime[i].tm_mon = month;
	        mytime[i].tm_year = year -1900;
	  }
       }
      else
      {
           mytime[i].tm_mday = start + i;  /* tm_mday 1-31 */
	   mytime[i].tm_mon = month -1;   /* tm_month 0-11 */
	   mytime[i].tm_year = year - 1900;
      }
      mytime[i].tm_hour = 10;
      mytime[i].tm_min = 30;
      mytime[i].tm_sec = 0;
      mytime[i].tm_wday = 0;
      mytime[i].tm_isdst = -1;
   }
   for (i =0; i<7; i++)
          mktime( &mytime[i]);


   get_event(conf, year, month, start, 
	      mytime[6].tm_year +1900, mytime[6].tm_mon +1, mytime[6].tm_mday);
   set_week_days( mytime, course, key, start, conf);
   if(list)
   {
      free_event_list(list->head);
      free(list);
   }

   return 1;
}

int
set_calendar( const char *course, const char *key, CONFIG_STRUCT *conf)
{
    time_t current;
    struct tm *today;
    int year =0, month =0, selected_day =0;
    char system_url[MAX_PATH +1];

    current = time(NULL);
    today = localtime(&current);
   
    year = hdf_get_int_value (global_cgi->hdf, "Query.year", 0);
    month = hdf_get_int_value (global_cgi->hdf, "Query.month", 0);
    selected_day = hdf_get_int_value (global_cgi->hdf, "Query.today", 0);
    
    if(!year && !month)
    {
       year = today->tm_year +1900;
       month = today->tm_mon + 1;
       selected_day = today->tm_mday;
    }
    snprintf(system_url, MAX_PATH +1, "%s?crs=%s&amp;id=%s&amp;year=%d&amp;month=%d&amp;today=%d",
		   CALENDAR_SYSTEM, course, key, year, month, selected_day);
    cs_set_value( "systemurl", system_url); 
    set_nav(year, month, selected_day,  course, key);
    if(year == today->tm_year + 1900 && month == today->tm_mon +1)
       set_body_calendar(year, month, selected_day,  course,key, today->tm_mday); 
    else
       set_body_calendar(year, month, selected_day,  course,key, 0); 

    set_week_time(selected_day,  year,  month, course, key,  conf);
    set_selected_time(selected_day, year, month); 
    return 1;
}

int set_up_current_calendar(const char *course, const char *key, CONFIG_STRUCT *conf, SESSION *user)
{
   char url[MAX_PATH +1];

    cs_set_course_info( conf);
    set_calendar( course, key, conf);
    if(user->group == ADMIN)
        snprintf(url, MAX_PATH +1, "%s?id=%s", "super_admin_page",  key);
    else
        snprintf(url, MAX_PATH +1, "%s?crs=%s&amp;id=%s", "main_menu", course, key);
   cs_set_value("back_url", url); 
    return 1;
}	

int
main ()
{
  char course[MAX_PATH +1];
  char key[MAX_KEY +1];
  SESSION user;
  CONFIG_STRUCT conf;

  cs_cgi_init();
  *course = '\0';
  read_parameters ( course, key);
  if(!strlen(course))
  {
     validate_super_key(key, &user);
     mk_conf(&user, &conf);  
  } 
  else
  {
    read_configuration_file (course, &conf);	
    validate_key (key, &user, &conf);	
  }

  set_up_current_calendar(course, key,&conf, &user);
  cs_cgi_display ("calendar", 1);
  cs_cgi_destroy();                  
  return 0;		

}


