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

#include "ClearSilver.h"
#include "sqlite3.h"
#include "global.h"
#include "custom.h"		/* for date FORMAT strings */
#include "grade.h"		/* for date FORMAT strings */
#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_grade_book_menu.h"
#include "manhat-lib/shared_file_util.h"
#include "manhat-lib/shared_grade_book_util.h"
#include "manhat-lib/shared_grade_book_db.h"
#include "manhat-lib/shared_person_list.h"
#include "manhat-lib/shared_grade_book_calculation_util.h"
#include "manhat-lib/shared_grade_book_view.h"

void
read_parameters ( char *course, char *key)
{
     cs_get_required_parameter("crs", course, MAX_PATH);
     cs_get_required_parameter("id", key, MAX_KEY);

}



void get_all_grades(CONFIG_STRUCT *conf)	
{
    if(global_item_list && global_item_list->head)
    {
	for(global_item_list->current = global_item_list->head; global_item_list->current; global_item_list->current = global_item_list->current->next)
	{
	   if(strcmp(global_item_list->current->grade_entered, "yes") ==0)
	   {
	
	       get_one_item_grade_list(conf, global_item_list->current->item_id, GRADE_BOOK_STUDENT_DB); /* shared_grade_book_db.h */
	       if(global_grade_temp_list && global_grade_temp_list->head)
	       {
		  
		   if(strcmp(global_item_list->current->is_letter_grade, "yes") == 0)
			 update_letter_log_list(conf,  global_item_list->current->item_id, GRADE_BOOK_STUDENT_DB, global_grade_temp_list);  /* shared_grade_book_db.h */

	               global_item_list->current->grades = global_grade_temp_list;
	       }

	   }
	}
    }
}

void set_all_item_grades(SESSION *user)
{
#define MAX_TMP 50
    GRADE *ptr;
    ITEM *item_ptr;
    char name[MAX_TMP];
    char temp[MAX_TMP];
    char *username =0;

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


    if(user->group == FACULTY && strlen(username) == 0)
    { 
      for(item_ptr = global_item_list->head; item_ptr; item_ptr = item_ptr->next)
      {
	 if(item_ptr->grades && !strcmp(item_ptr->hide, "no"))
	 {
            for(ptr = item_ptr->grades->head; ptr; ptr = ptr->next)
	    {
	       if(strcmp(item_ptr->is_letter_grade, "no") == 0)
	       {
	          snprintf(name, MAX_TMP, "score.%s.%d.score", ptr->username, ptr->item_id);
	          snprintf(temp, MAX_TMP, "%4.*f", test_precision(ptr->score), ptr->score);
                  cs_set_value(name, temp);
	       } 
	       else
	       {
	          snprintf(name, MAX_TMP, "score.%s.%d.letter", ptr->username, ptr->item_id);
                  cs_set_value(name, ptr->letter);
	       }
	      snprintf(name, MAX_TMP, "score.%s.%d.excuse", ptr->username, ptr->item_id);
              cs_set_value(name, ptr->excuse);
	      snprintf(name, MAX_TMP, "score.%s.%d.pending", ptr->username, ptr->item_id);
              cs_set_value(name, ptr->pending);
	      snprintf(name, MAX_TMP, "score.%s.%d.item_id", ptr->username, ptr->item_id);
              cs_set_int_value(name, ptr->item_id);
	      snprintf(name, MAX_TMP, "score.%s.%d.drop", ptr->username, ptr->item_id);
              cs_set_value(name, ptr->drop);
               
            }
	     
	 }
      }
    }
    else
    {
	 if(user->group == STUDENT)
               username = malloc_str( user->username);
         for(item_ptr = global_item_list->head; item_ptr; item_ptr = item_ptr->next)
         {
	    if(item_ptr->grades)
	    {
               for(ptr = item_ptr->grades->head; ptr; ptr = ptr->next)
	       {
		  if(strcmp(username, ptr->username) ==0)
		  {
	            if(strcmp(item_ptr->is_letter_grade, "no") == 0)
	            {
	              snprintf(name, MAX_TMP, "score.%s.%d.score", ptr->username, ptr->item_id);
	              snprintf(temp, MAX_TMP, "%4.*f", test_precision(ptr->score), ptr->score);
                      cs_set_value(name, temp);
	            } 
	            else
	            {
	             snprintf(name, MAX_TMP, "score.%s.%d.letter", ptr->username, ptr->item_id);
                     cs_set_value(name, ptr->letter);
	            }
	            snprintf(name, MAX_TMP, "score.%s.%d.excuse", ptr->username, ptr->item_id);
                    cs_set_value(name, ptr->excuse);
	            snprintf(name, MAX_TMP, "score.%s.%d.pending", ptr->username, ptr->item_id);
                    cs_set_value(name, ptr->pending);
	            snprintf(name, MAX_TMP, "score.%s.%d.item_id", ptr->username, ptr->item_id);
                    cs_set_int_value(name, ptr->item_id);
	            snprintf(name, MAX_TMP, "score.%s.%d.drop", ptr->username, ptr->item_id);
                    cs_set_value(name, ptr->drop);
		    send_content_type();
		    if(ptr->comment)
		    {
	              snprintf(name, MAX_TMP, "score.%s.%d.comments", ptr->username, ptr->item_id);
                      cs_set_value(name, ptr->comment);
		    }
                 } 
              }
	     
	   }
        }
    }



 #undef MAX_TMP 
}

void set_std_total_grade(TOTAL_GRADE *std_grade, SESSION *user, RELEASE_CONF *release_conf)
{
   #define MAX_TMP 50
   TOTAL_GRADE *ptr;
   char name[MAX_TMP];
   char temp[MAX_TMP];
   double total =0;
   double max =-1;
   double min =999999;
   double avg =0;
  // char letter[MAX_GRADE_LEN +1];
   int count =0;
   char *username =0;

   username = hdf_get_value(global_cgi->hdf, "Query.username", "");
   if(user->group == STUDENT)
      username = malloc_str( user->username);
   
   for(ptr = std_grade; ptr; ptr = ptr->next)
   {
      if(ptr->total >= 0)
      {
        if(user->group == FACULTY && strlen(username) == 0)
	{
           snprintf(name, MAX_TMP, "score.%s.total", ptr->username);
           snprintf(temp, MAX_TMP, "%4.*f", test_precision(ptr->total), ptr->total);
	   cs_set_value(name, temp);
           snprintf(name, MAX_TMP, "score.%s.grade", ptr->username);
	   cs_set_value(name, ptr->grade);
	}
        else
	{
           if(strcmp(username, ptr->username) ==0)
	   {
             snprintf(name, MAX_TMP, "score.%s.total", ptr->username);
             snprintf(temp, MAX_TMP, "%4.*f", test_precision(ptr->total), ptr->total);
	     cs_set_value(name, temp);
             snprintf(name, MAX_TMP, "score.%s.grade", ptr->username);
	     cs_set_value(name, ptr->grade);
	   }	   
	}	
	total += ptr->total;
	if(max < ptr->total)
           max = ptr->total;
	if(min > ptr->total)
	    min = ptr->total;
      }
	count++;
	
   }
   if(total >=0)
     avg = total/(float)count; 

/*   if(release_conf->view_max && total >= 0)
   {

      snprintf(temp, MAX_TMP, "%4.2f", global_grade_conf.rounding_method == WHOLE_NUMBER ? whole_number(avg): nearest_tenth(avg));
      cs_set_value("avg", temp);

     snprintf(temp, MAX_TMP, "%4.2f", global_grade_conf.rounding_method == WHOLE_NUMBER ? whole_number(min): nearest_tenth(min));
     cs_set_value("min", temp);

     snprintf(temp, MAX_TMP, "%4.2f", global_grade_conf.rounding_method == WHOLE_NUMBER ? whole_number(max): nearest_tenth(max));
     cs_set_value("max", temp);

    get_one_student_grade(global_grade_conf.rounding_method == WHOLE_NUMBER ? whole_number(min): nearest_tenth(min), letter);
    cs_set_value("min_grade", letter);

    get_one_student_grade(global_grade_conf.rounding_method == WHOLE_NUMBER ? whole_number(max): nearest_tenth(max), letter);
    cs_set_value("max_grade", letter);

    get_one_student_grade(global_grade_conf.rounding_method == WHOLE_NUMBER ? whole_number(avg): nearest_tenth(avg), letter);
    cs_set_value("avg_grade", letter);


    } */

 #undef MAX_TMP 
}



void  do_action(CONFIG_STRUCT *conf, SESSION *user)
{
    P_NODE *head;
    TOTAL_GRADE *std_grade =0;
    RELEASE_CONF release_conf;

    head = build_option_person_list (conf);  /* shared_person_list.c */
    set_person_list_values(head, user);   /* shared_grade_book_util.c */

    get_categories(conf, GRADE_BOOK_STUDENT_DB);  /* shared_grade_book_db.h */
    
    read_release_conf(conf, &release_conf);
    if(release_conf.view_bar)
	cs_set_int_value("view_bar", 1);
    if(release_conf.view_max)
	cs_set_int_value("max_min_avg", 1);

    if(global_cat_list && global_cat_list->head)
    {
	set_cat_list_values();               /* shared_grade_book_util.h */
        get_items(conf, GRADE_BOOK_STUDENT_DB, 0);     /* shared_grade_book_db.h */
	if(global_item_list && global_item_list->head)
	{
           get_all_grades(conf);	
	   
	   get_items_min_avg_max(conf, GRADE_BOOK_STUDENT_DB);   /* shared_grade_book_calculation_util.h */

           set_all_item_grades(user);
           
	   set_item_list_values(release_conf.view_max, 1);        /* shared_grade_book_util.h */

	   if(release_conf.view_total)
	   {
	     
	     cs_set_int_value("view_total", 1);
	     std_grade = calculate_total_grades(head, conf, GRADE_BOOK_STUDENT_DB); /* shared_grade_book_calculation_util.h */
	     if(std_grade)
	     {
	        set_std_total_grade(std_grade, user, &release_conf);
		free_total_grade_list(std_grade);
	     }
	   }
         

	}

    }


    if(head)
	free_option_person_list(head);    /* shared_person_list.c */
    if(global_cat_list)
	free_category_list(global_cat_list);
    if(global_item_list)
	free_item_list(global_item_list);
    if(global_scale_list)
       free_scale_list(global_scale_list);

}




int
main ()
{
  char course[MAX_PATH +1];
  char key[MAX_KEY +1];
  char *username = 0;
  SESSION user;
  CONFIG_STRUCT conf;
  
  cs_cgi_init();   /* shared_cs_util.h */
  read_parameters ( course, key);
  read_configuration_file (course, &conf);	
  validate_key (key, &user, &conf);	
  cs_set_course_info(&conf);  
  cs_load_lang("grade_book_menu_util");
  if(user.group == STUDENT)
  {
	 cs_set_back_url(course, key, "main_menu");
	 cs_set_int_value("is_student", 1);
	 cs_set_value("username", user.username);
	 handle_new_file(&conf, &user);

  }
  do_action(&conf, &user);
  cs_set_int_value("student_db", 1);
  
  username = hdf_get_value(global_cgi->hdf, "Query.username", "");
  if(user.group == STUDENT || (username && strlen(username)))
  {
     cs_load_lang("grade_book"); 
     cs_cgi_display ("grade_book_std", 0);
  }
  else
    cs_cgi_display ("grade_book", 1);
  cs_cgi_destroy();      

  return 0;			

}


