
import java.util.Scanner;
import java.util.NoSuchElementException;
import java.io.*;

public class ShowGrades {
    
    public static final Scanner KBD = new Scanner(System.in);

    public static void main(String[] args) {

        // create variables
        Student[] myClass = readStudentInfo();
        int[] grades;
        String aNumber;

        // class summary
        printClass(myClass);
        
        // get and save grades
        while (!(aNumber = getANumber()).isEmpty()) {
            // find this Student's grades and write them to the Web
            grades = getGrades(aNumber, myClass);
            writeGrades(findStudent(aNumber, myClass));
        }
    }

    /**
     * Get and return an A-number from the user. The methods prompts for the 
     * A-number, and reminds the user that an empty string will end input, but
     * does not check whether the A-number entered is valid.
     * 
     * @return the A-number entered by the user
     */
    public static String getANumber() {
        String aNumber;
        
        System.out.print("Enter an A-Number (or nothing to quit): ");
        aNumber = KBD.nextLine();
        
        return aNumber;
    }

    /**
     * Print out the Students in the given array.
     *
     * @param myClass the array of Students to print out
     */
    private static void printClass(Student[] myClass) {
        System.out.println("\nYour class:");
        for (int s = 0; s < myClass.length; ++s) {
            System.out.println("\t" + myClass[s]);
        }
        System.out.println();
    }

    /**
     * Read Student names and grades from a data file.
     * NOTE: CSCI1226 students do not need to understand how this method works!
     *
     * @return an array containing Student objects for each student's info
     *         found in the file.
     */
    private static Student[] readStudentInfo() {
        // create variables
        Student[] result;
        int numStu;
        String name;
        int grade;

        // try to get all the student information
        try(Scanner in = new Scanner(new File("StudentInfo.txt"))) {
            // file starts with # of student records in file
            numStu = in.nextInt();
            in.nextLine();

            // create an array big enuf to hold them all
            result = new Student[numStu];

            // read in the student records
            for (int i = 0; i < numStu; ++i) {
                // record starts with name on its own line
                name = in.nextLine();
                result[i] = new Student(name);

                // next line has grades for every assignment
                for (int a = 1; a <= Student.NUM_ASGN; ++a) {
                    grade = in.nextInt();
                    result[i].setAsgnGrade(a, grade);
                }
                in.nextLine();
            }

            // all info saved, so return it
            return result;
        } 
        // deal with possible weird stuff by printing an error message
        // and quitting the program(!)
        catch (FileNotFoundException fnf) {
            System.out.println("Missing data file: StudentInfo.txt");
            System.exit(0);
        } catch (NoSuchElementException nse) {
            System.out.println("Corrupt data file: StudentInfo.txt");
            System.exit(0);
        }

        // should never get here, but Java requires a return here
        return null;
    }

    /**
     * Find the assignments grades for the student with the given ANumber.
     *
     * @param aNumber the A-Number of the Student to find
     * @param myClass the array to find the student in
     * @return an array containing the assignment grades of the given student
     *         OR null if there is no such Student
     */
    private static int[] getGrades(String aNumber, Student[] myClass) {
        for (int s = 0; s < myClass.length; ++s) {
            if (aNumber.equals(myClass[s].getANumber())) {
                return myClass[s].getAsgnGrades();
            }
        }
        return null;
    }

    /**
     * Write a Student's grades into a Web file.
     * The Web file is named with the student's A-Number
     * and the extension "html".
     * NOTE: CSCI1226 students don't need to understand how this method works!
     *
     * @param aNumber the A-Number of the Student
     * @param grades an array containing that Student's grades
     */
    private static void writeGrades(Student stu) {
        if (stu == null) {
            System.out.println("No such Student!");
        } else {
            String aNumber = stu.A_NUMBER;
            int[] grades = stu.getAsgnGrades();
            
            try(PrintWriter out = new PrintWriter(new File(aNumber+".html"))) {
                // create head matter for the file
                out.println("<HTML><HEAD><TITLE>" + aNumber 
                        + "'s Grades</TITLE></HEAD><BODY>");

                // create in-page title
                out.println("<H1>Assignment Grades for " + aNumber + "</H1>");

                // create table of grades
                out.println("<TABLE BORDER>");
                for (int a = 0; a < grades.length; ++a) {
                    out.printf(" <TR>"
                            + "<TH>A%02d</TH>"
                            + "<TD align='right'>%d</TD>"
                            + "</TR>%n",
                        (a+1), grades[a]);
                }

                // close off table, body and file
                out.println("</TABLE>");
                out.println("<p>Final Assignment Grade: " 
                        + stu.getAsgnsGrade() + "%");
                out.println("</BODY></HTML>");
                out.close();

                // report success to user
                System.out.println("Grade report created in file " 
                        + aNumber + ".html");
            } catch (FileNotFoundException fnf) {
                System.out.println("Could not create output file!");
            }
        }
    }

    private static Student findStudent(String aNumber, Student[] myClass) {
        for (Student s : myClass) {
            if (aNumber.equals(s.A_NUMBER)) {
                return s;
            }
        }
        return null;
    }
    
}
