#include <stdio.h>


#include "global.h"


#include <ClearSilver.h>
#include "grade.h"	


#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_strtrm.h"
#include "manhat-lib/shared_grade_book_view.h"
#include "manhat-lib/shared_copy_tab_file.h"
#include "manhat-lib/shared_cs_util.h"
#include "manhat-lib/shared_lock.h"




void
set_grade_values( char *grades_line, int number, int should_bold)
{
#define MAX_TEMP_LEN 35
     char *ptr, *ptr2 =0;
     char name[MAX_TEMP_LEN +1];
     char value[MAX_PATH +1];
     int done = 0, i = 0;
	 static int max_cols;


     ptr = strchr(grades_line, '\t');
     if(ptr)
	*ptr = '\0';
     else
	done = 1;
     if(!done)
     {
	 snprintf(name, MAX_TEMP_LEN +1, "st.%d.id", number);
	 snprintf(value, MAX_PATH +1, "%s%s%s", !should_bold ? "<b>":"", grades_line, !should_bold ? "</b>":"");
	 cs_set_value( name, value);
     }
     
     
     while(!done)
     {
       ptr2 = ptr +1;
       ptr = strchr(ptr2, '\t');
       if(ptr)
	   *ptr = '\0';
       else
	   done =1;
       if(!done)
       {
	   snprintf(name, MAX_TEMP_LEN +1, "st.%d.score.%d.earn_points", number, i);
	   snprintf(value, MAX_PATH +1, "%s%s%s", !should_bold ? "<b>":"", ptr2, !should_bold ? "</b>":"");
	   cs_set_value( name, value);
	   i++;
       }
    }
	if(max_cols < i +1)
	{
	    max_cols = i +1;
        cs_set_int_value("max_cols", max_cols);

	}

    
    
    if(!ptr && done)
    {
       snprintf(name, MAX_TEMP_LEN +1, "st.%d.score.%d.earn_points", number, i);
       snprintf(value, MAX_PATH +1, "%s%s%s", !should_bold ? "<b>":"", ptr2, !should_bold ? "</b>":"");
       cs_set_value( name, value);
    }


#undef MAX_TEMP_LEN 
}






int
contains_digits( char *id)
{
   int i, len;

   len = strlen(id);

   for(i =0; i<len; i++)
   {
       if(isdigit(id[i]))
          return 1;
   }
   return 0;
}






int
parse_tab_file(CONFIG_STRUCT *conf, SESSION *user)
{
    char db_path[MAX_PATH +1], 
         *username = 0;
    FILE *fp;
    char *grades_line = 0;
    int big = MAX_GRADES_LINELEN, 
        i, 
        j = 0;
    char *buf;
    struct stat file_stat;
    int len = 0, 
        ss, 
        should_bold = 0, 
        space =0;
    char *id_ptr;

    snprintf(db_path, MAX_PATH +1, "%s%s/%s", conf->course_path, GRADE_BOOK_DIR, GRADES_TAB_FNAME);
    if(stat(db_path, &file_stat))
      {
        /* copy old grades_tab file from teacher's directory to grade_book directory */
	if(!copy_tab_file(conf))
	   return -1;
	if(stat(db_path, &file_stat))
	    return -1;
      }
    
    
    buf = (char*)malloc((file_stat.st_size + 1) * sizeof(char));
    if(!buf)
	 return 0;


    fp = fopen(db_path, "r");
    if(!fp)
       return 0;     /* can't open file */
       
       
    if(get_shared_lock(fileno(fp), 0))  /* shared_lock.c */
     {
       fclose(fp);
       return 0;
     }
    
    if(fread(buf, file_stat.st_size, 1, fp) != 1)
     {
         fclose(fp);
	 return 0;
     }
     
    release_lock(fileno(fp));     /* shared_lock.c */
    fclose(fp);

    *(buf + file_stat.st_size) = '\0';  /* null terminate the buf string */

    grades_line = (char*)malloc(sizeof(char) * (MAX_GRADES_LINELEN + 1));
    if(!grades_line)
	 return 0;

    len = strlen(buf);
    username = hdf_get_value(global_cgi->hdf, "Query.student_id", 0); 
    for(ss = 0; ss < len; ss++)
    {
        i = 0;
        space = 0;

	while( ss < len && buf[ss] != '\n')
	{
	   if((int)strlen(grades_line) >= big)
	   {
	          grades_line = realloc(grades_line, big * 2 + 1);
		  big = big * 2;
	   } 
	   if(isspace(buf[ss]))
		 space++;

	   grades_line[i] = buf[ss];
	   grades_line[i+1] = '\0';
	   i++;
	   ss++;
	}
	
	if(strlen(grades_line) && i != space )
	{
	  /* testing the first field contains digit. */
	   id_ptr = strchr(grades_line, '\t');
	   if(id_ptr)
	       *id_ptr = '\0';
	       
            should_bold = contains_digits(grades_line);
            *id_ptr = '\t';

	    if(user->group == STUDENT) /* student is viewing his grades */
              {
	        if(strstr(grades_line, user->id) || !should_bold )	
	          {
	           set_grade_values(grades_line, j, should_bold);
	           j++;
	          }
	      }
	    else
	      {
	        if(username)  /* teacher viewing one student's grades */
	         {
		   if(strstr(grades_line, username) || !should_bold)
		    {
	              set_grade_values( grades_line, j, should_bold);
	              j++;
		    }
	         }
                else 
	         {
	           set_grade_values( grades_line, j, should_bold);
	           j++;
	         }
	      }
	  free(grades_line);
	  grades_line = 0;
	  big = MAX_GRADES_LINELEN;
          grades_line = (char*)malloc(sizeof(char) * (MAX_GRADES_LINELEN + 1));
          if(!grades_line)
	     return 0;
        }	  
    }
    if(buf)
       free(buf);
    return 1;
}







int
set_grades( const char *course, const char *key, CONFIG_STRUCT *conf,SESSION *user) 
{

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

    if(user->group == FACULTY)
        cs_set_back_url(course, key, "grades_fac_menu");  /* shared_cs_util.c */
    else
        cs_set_back_url( course, key, "main_menu");  /* shared_cs_util.c */

    cs_set_int_value("display_grade", 1);
    return parse_tab_file(conf, user);
}







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

}







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

  cs_cgi_init();    /*shared_cs_util.c */

  read_parameters (course, key);
  read_configuration_file (course, &conf);	
  validate_key (key, &user, &conf);	
  
  if(user.group == STUDENT && *(user.realname) == '*')
	  cs_critical_error(ERR_NO_GRADE_FOR_AUDIT_ST, "");

  flag = set_grades(course, key,  &conf, &user);
  if(flag == 0)
      cs_critical_error(ERR_MALLOC_FAILED, "");
  else if(flag == -1)
      cs_critical_error(ERR_NO_RELEASED_GRADES, "");
  else
    {
         if(user.group == STUDENT )
             handle_new_file(&conf, &user);
    
         cs_cgi_display ("grades_view", 1);
    }



  cs_cgi_destroy();           
                              
                              

  return 0;		

}






