#include <stdio.h>
#include <time.h>
#include <string.h>
#include <ctype.h>		/* for tolower() */


#include "global.h"

#include "manhat-lib/shared_util.h"
#include "manhat-lib/shared_cs_util.h"
#include "manhat-lib/shared_file_util.h"
#include "manhat-lib/shared_testpilot_util.h"
#include "manhat-lib/shared_grade_book_util.h"
#include "manhat-lib/shared_grade_book_db.h"
#include "manhat-lib/shared_time.h"
#include "manhat-lib/shared_person_list.h"

void validate_new_item(ITEM *new_item, int *errors);
void insert_item_to_db(CONFIG_STRUCT *conf, ITEM *new_item, int *new_item_id);


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

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


}

void set_score_value()
{
    int count =0, i, j =0;
    char name[MAX_PATH +1];
    char p_name[MAX_PATH +1];
    char *value;

    count = hdf_get_int_value(global_cgi->hdf, "Query.count", -1);
    if(count == -1)
	 cs_critical_error(ERR_TESTPILOT_NO_SCORE, "set score value");

    for(i =0; i<count; i++)
    {
       snprintf(p_name, MAX_PATH +1, "Query.checkbox_%d", i);
       value = hdf_get_value(global_cgi->hdf, p_name, "");

       if(strlen(value) >0)
       {
           snprintf(name, MAX_PATH +1, "user.%d.name", j);
	   cs_set_value(name, value);


           snprintf(p_name, MAX_PATH +1, "Query.id_%d", i);
           value  = hdf_get_value(global_cgi->hdf, p_name, "");
           snprintf(name, MAX_PATH +1, "user.%d.id", j);
	   cs_set_value(name, value);


           snprintf(p_name, MAX_PATH +1, "Query.score_%d", i);
           value  = hdf_get_value(global_cgi->hdf, p_name, "");
           snprintf(name, MAX_PATH +1, "user.%d.score", j);
	   cs_set_value(name, value);
	  

	   j++; 
                 
       } 
    }
    snprintf(p_name, MAX_PATH +1, "Query.maxscore");
    value  = hdf_get_value(global_cgi->hdf, p_name, "");
    cs_set_value("maxscore", value);

}


void create_new_item_at_grade_book(CONFIG_STRUCT *conf, int *new_item_id)
{
    ITEM new_item;
    int errors =0;

    validate_new_item(&new_item, &errors);
    if(errors >0)
	cs_critical_error(ERR_GRADE_BOOK_NEW_ITEM, "create_new_item in testpilot_export_grade");

   insert_item_to_db(conf, &new_item, new_item_id); 
}


void save_exported_test_tp4(CONFIG_STRUCT *conf, char *tp4, int new_item_id) 
{
    char path[MAX_PATH +1];
    FILE *fp;


    snprintf(path, MAX_PATH +1, "%s%s/%s", conf->course_path, GRADE_BOOK_DIR, TESTPILOT_EXPORT_FNAME);
    fp = fopen(path, "a+");
    if(!fp)
	 cs_critical_error(ERR_FOPEN_WRITE_FAILED, path);
    fprintf(fp, "%s:%d\n", tp4, new_item_id);
    fclose(fp);
}

void set_export_score_value()
{
    int count =0, i;
    char name[MAX_PATH +1];
    char p_name[MAX_PATH +1];
    char *value;
    char *value1;
    char *checkvalue;

    count = hdf_get_int_value(global_cgi->hdf, "Query.count", -1);
    if(count == -1)
	 cs_critical_error(ERR_TESTPILOT_NO_SCORE, "set score value");

    for(i =0; i<count; i++)
    {
           snprintf(p_name, MAX_PATH +1, "Query.checkbox_%d", i);
           checkvalue  = hdf_get_value(global_cgi->hdf, p_name, "");
           if(strlen(checkvalue) >0)
	   { 
              snprintf(p_name, MAX_PATH +1, "Query.id_%d", i);
              value  = hdf_get_value(global_cgi->hdf, p_name, "");
              snprintf(p_name, MAX_PATH +1, "Query.score_%d", i);
              value1  = hdf_get_value(global_cgi->hdf, p_name, "");
              snprintf(name, MAX_PATH +1, "export.%s.score", value);
	      cs_set_value(name, value1);
              snprintf(name, MAX_PATH +1, "export.%s.has_score", value);
	      cs_set_int_value(name, 1);
	   }
    }
    snprintf(p_name, MAX_PATH +1, "Query.maxscore");
    value  = hdf_get_value(global_cgi->hdf, p_name, "");
    cs_set_value("maxscore", value);

}





void set_common_value(CONFIG_STRUCT *conf, SESSION *user, int item_id)
{
	P_NODE *head;

        set_export_score_value();
	head = build_option_person_list (conf);  /* shared_person_list.c */
        set_person_list_values(head, user);            /* shared_grade_book_util.c */
        cs_set_int_value("max_point_len", MAX_POINT_LEN);
        get_one_item(conf, item_id, GRADE_BOOK_DB);
        set_item_list_values(1, 0);                  /* shared_grade_book_util.c */
        if(head)
           free_option_person_list(head);    /* shared_person_list.c */
	if(global_item_list)
             free_item_list(global_item_list);  /* shared_grade_book_util */
}



void do_action(const char *update, CONFIG_STRUCT *conf, SESSION *user)
{
   int db =0;
   char tp4[MAX_PATH +1];
   int new_item_id;

   if(strcmp(update, "first") == 0)
   {
	cs_set_int_value("show_item_name", 1);
        db = get_categories(conf, GRADE_BOOK_DB);    /* shared_grade_book_db.h */
        if(db == 0 || !global_cat_list  || !global_cat_list->head)
	  cs_critical_error(ERR_TESTPILOT_EXPORT_NO_CAT, "do action");

        set_score_value();
        set_cat_list_values();    /* shared_grade_book_util.h */
        free_category_list(global_cat_list);	 /* shared_grade_book_util.h */
        cs_load_lang("grade_book_items"); 
   }
   else if(strcmp(update, "create_new_item") == 0)
   {
	cs_get_required_parameter("tp4", tp4, MAX_PATH);
	create_new_item_at_grade_book(conf, &new_item_id);
        save_exported_test_tp4(conf, tp4, new_item_id); 
        set_common_value(conf, user, new_item_id);
        cs_set_int_value("Query.item_id", new_item_id);
        cs_load_lang("grade_book_enter_grades"); 
   }
   /*else if(strcmp(update, "insert_grades") == 0)
   {

       insert_grades_to_grade_book(conf);	
   } */
   else
   {
       
       set_common_value(conf, user, atoi(update));
       get_current_grade_list(conf, atoi(update), GRADE_BOOK_DB);  /* shared_grade_book_db.c */
       set_current_grade_list_values();        /* shared_grade_book_util.c */
        cs_set_value("Query.item_id", update);
        cs_load_lang("grade_book_enter_grades"); 
       
   } 
}



int
main (void)
{
  char course[MAX_PATH + 1];			/* from crs=? command line */
  char key[MAX_KEY + 1];			/* from id=? command line */
  SESSION user;
  CONFIG_STRUCT conf;
  char update[MAX_PATH +1];

  cs_cgi_init();                 		/* shared_cs_util.c */
  read_parameters (course, key, update);
  read_configuration_file (course, &conf);	/* shared_util.c */
  
  validate_key (key, &user, &conf);		/* shared_util.c */

  if (user.group != FACULTY)
       cs_critical_error (ERR_REQUEST_DENIED, "");    /* shared_cs_util.c */
 
  do_action(update, &conf, &user); 

  cs_cgi_display("testpilot_export_grade", 1);
  cs_cgi_destroy();                    /* shared_cs_util.c */
  
  return 0;
}



void
validate_new_item(ITEM *new_item, int *errors)
{
     char temp[MAX_PATH +1];
     int count = 0;

     cs_get_required_parameter("item_name", temp, MAX_PATH);
     if(!check_spe_char(temp))                 /* shared_grade_book_util.c */
	     count++;
     else
        strncpy(new_item->item_name, temp, MAX_ITEM_LEN);


     cs_get_required_parameter("item_category", temp, MAX_PATH);
     if(!strcmp(temp, "-1"))
	     count++;
     else
        new_item->cat_id = atoi(temp);


     cs_get_required_parameter("item_extra_credit", new_item->extra_credit, MAX_EXTRA_CREDIT_LEN);

     cs_get_required_parameter("item_due_date", temp, MAX_PATH);
     new_item->due_date = get_time("item_due_date");  /* shared_time.c */

     cs_get_required_parameter("maxscore", temp, MAX_PATH);
     new_item->points = atof(temp);
     strncpy(new_item->is_letter_grade, "no", MAX_BOOLEN_LEN +1); 
     strncpy(new_item->grade_entered, "no", MAX_BOOLEN_LEN +1);
     strncpy(new_item->hide, "no", MAX_BOOLEN_LEN +1);
     *errors = count;
}

void insert_item_to_db(CONFIG_STRUCT *conf, ITEM *new_item, int *new_item_id)
{
    char path[MAX_PATH +1];
    int ret = 0;
    sqlite3 *db;
    char *stmt;
    int new_id =0;


    snprintf(path, MAX_PATH +1, "%s%s/%s", conf->course_path, GRADE_BOOK_DIR, GRADE_BOOK_DB);
    ret = sqlite3_open(path, &db);
    if(ret)
      cs_critical_error(ERR_GRADES_DB, "insert function");

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

    if(ret)
    {
         sqlite3_close(db);
         cs_critical_error(ERR_GRADES_DB, "begin insert item function");

     }
    stmt = sqlite3_mprintf("insert into Items values(NULL, '%q', %4.2f, %d, '%q', '%q', '%q', '%q', %d)",
             new_item->item_name, new_item->points, new_item->due_date, new_item->extra_credit, 
	     new_item->is_letter_grade, new_item->grade_entered, new_item->hide, new_item->cat_id);
    if(stmt)
    {
	 ret = sqlite3_exec(db, stmt, 0, 0,0);
	 if(ret)
	 {
	     sqlite3_free(stmt);
	     sqlite3_close(db);
	     cs_critical_error(ERR_GRADES_DB, "ERR insert new item in grade_book_items_save");

	 }
	 sqlite3_free(stmt);
         new_id = sqlite3_last_insert_rowid(db);
	 *new_item_id = new_id;
    }
    else
    {
         sqlite3_close(db);
	  cs_critical_error(ERR_GRADES_DB, "ERR insert new item in grade_book_items_save");
    }	
    ret = sqlite3_exec(db,"commit transaction insert_new_item", 0,0,0);
    ret = sqlite3_exec(db,"end transaction insert_new_item", 0,0,0);
    sqlite3_close(db);


}

