#ifndef GRADE_H
#define GRADE_H

#include "global.h"

/* These correspond to values in the CONFIG_STRUCT
** e.g. conf.grades == 2 means we're using the WEB_BASED_METHOD
*/
#define EXCEL_TAB_FILE_METHOD 1
#define WEB_BASED_METHOD 2


/* define programs */


/* directories and filenames */
#define GRADE_BOOK_DIR "grade_book"
#define GRADE_BOOK_DB "grade_book.db"
#define GRADE_BOOK_STUDENT_DB "grade_book_student.db"
#define GRADE_CAL_CONF_FNAME "calculation.dat"
#define GRADE_BOOK_RELEASE_CONF_FNAME "release.dat"

#define GRADES_TAB_FNAME "grades.tab"   		/* name of tab-delimited grades file uploaded by instructor */
#define GRADES_NEW_TAB_FNAME "grades_tab.new"  		/* name of (temporary) file uploaded by instructor 
                                               		** renamed to GRADES_TAB_FNAME when it passes all tests **/


#define MAX_GRADE_LEN 10 
#define MAX_ITEM_LEN 40 
#define MAX_CAT_LEN 40 
#define MAX_POINT_LEN 7 
#define MAX_WEIGHT_LEN 7 
#define MAX_EARN_POINTS_LEN 7 
#define MAX_EXTRA_CREDIT_LEN 15 
#define MAX_BOOLEN_LEN 5 
#define MIN_GRADE_BOOK -999999 


typedef struct scale
{
    int id;
    double start;
    double end;
    char grade[MAX_GRADE_LEN +1];
    int count;
    struct scale *next;
}SCALE;
 
typedef struct scale_list
{
    SCALE *head;
    SCALE *current;
}SCALE_LIST;


typedef  enum scoring_method{ NO_CAL, BASIC_POINTS, CATEGORY_WEIGHT} SCORING_METHOD;
typedef  enum rounding_method{WHOLE_NUMBER, NEAREST_TENTH} ROUNDING_METHOD;

typedef struct grade_book_configure
{
   SCORING_METHOD scoring_method;
   ROUNDING_METHOD rounding_method;
   int feature1;
   int feature2;
   int feature3;
   int feature4;
   int feature5;
   int feature6;
}GRADE_BOOK_CONFIGURE;

typedef struct category
{
    int cat_id;
    char cat_name[MAX_CAT_LEN +1];
    double weight;
    int drop_lowest;      /* value is 0 to 10 */
    int number_members;
    int number_graded_items;
    int hided_items;
    struct category *next;
}CATEGORY;

typedef struct category_list
{
    CATEGORY *head;
    CATEGORY *current;

}CATEGORY_LIST;



typedef struct letter_grade
{
     int letter_id;
     char letter[MAX_GRADE_LEN +1];
     double points;
     int item_id;
     int count;
     struct letter_grade *next;
}LETTER_GRADE;

typedef struct letter_grade_list
{
    LETTER_GRADE *head;
    LETTER_GRADE *current;
}LETTER_GRADE_LIST;

typedef struct grade
{
   char username[MAX_USERNAME +1];
   int item_id;
   double score;
   char excuse[MAX_BOOLEN_LEN +1];
   char pending[MAX_BOOLEN_LEN +1];
   char drop[MAX_BOOLEN_LEN +1];
   char *comment;
   int letter_id;
   char letter[MAX_GRADE_LEN +1];
   char is_letter_grade[MAX_BOOLEN_LEN +1];
   time_t timestamp;
   struct grade *next;
}GRADE;

typedef struct grade_list
{
    GRADE *head;
    GRADE *current;
}GRADE_LIST;

typedef struct item
{
   int item_id;
   char item_name[MAX_ITEM_LEN +1];
   double points;
   time_t due_date;
   char extra_credit[MAX_EXTRA_CREDIT_LEN +1];
   char is_letter_grade[MAX_BOOLEN_LEN +1];
   char grade_entered[MAX_BOOLEN_LEN +1];
   char hide[MAX_BOOLEN_LEN +1];
   int cat_id;
   char min[MAX_GRADE_LEN +1];
   char max[MAX_GRADE_LEN +1];
   char avg[MAX_GRADE_LEN +1];
   LETTER_GRADE_LIST *letters;
   GRADE_LIST *grades;
   struct item *next; 
}ITEM;


typedef struct item_list
{
    ITEM *head; 
    ITEM *current; 
}ITEM_LIST;

typedef struct total_grade
{
    char username[MAX_USERNAME +1];
    double total;
    char grade[MAX_GRADE_LEN +1];
    struct total_grade *next;
}TOTAL_GRADE;

typedef struct release_conf
{
    int view_bar;
    int view_total;
    int view_max;
    time_t released_time;
}RELEASE_CONF;


#endif
