/*
    No.9   
     
    最終課題 
    これまで学んできたことをもとにして、以下の応用課題を作成してください。 
*/

import java.io.IOException;
import java.io.FileInputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Comparator;

public class Program {

/*
  １）新たに gakusei クラスを作成してください。
*/
    public static class gakusei {
    /*     
        メンバーは、 
        private String bangou;    //学生番号 
        private String namae;   //氏名 
        private int eigo;    //英語の得点 
        private int kokugo;    //国語の得点 
        private int suugaku;  //数学の得点 
        private int goukei;    //３科目の合計点 
        とします。 
    */

        private String bangou;    //学生番号 
        private String namae;   //氏名 
        private int eigo;    //英語の得点 
        private int kokugo;    //国語の得点 
        private int suugaku;  //数学の得点 
        private int goukei;    //３科目の合計点 

        // ２）引数のないコンストラクタを作成します。処理は特にしません。 
        
        public gakusei(){}

        /*
            ３）学生番号、氏名、英語の得点、国語の得点、数学の得点を引数とするコンストラクタを作成しま
            す。コンストラクタ内では、受け取った英語の得点、国語の得点、数学の得点の合計を計算し、
            値を goukeiにセットします。 
        */
        public gakusei( String abangou, String anamae,
            int aeigo, int akokugo, int asuugaku )
        {
            bangou  = abangou;
            namae   = anamae;
            eigo    = aeigo;
            kokugo  = akokugo;
            suugaku = asuugaku;

            goukei  = eigo + kokugo + suugaku;
        }
        /*
            ４）メンバーの内容を表示するメソッド showSeiseki()を以下の内容で作成してください。 
            表示の方法は実行結果を参考にし、各項目を揃えるようにしてください。 
        
        public void showSeiseki() { 
         
        int moji;      // 氏名の文字数 
        System.out.print(bangou + " "); 
        moji = namae.length(); 
        moji --;     // 間の空白分を文字数から減らす 
        System.out.print(namae); 
         
        // 氏名の文字数による間隔の調整 
        for(int i = 0;i<= 6-namae.length();i++) { 
        System.out.print(" "); 
        } 
        // 英語の得点表示 
        // 国語の得点表示 
        // 数学の得点表示 
        // 合計得点表示 
        } 
        */

        public void showSeiseki() {
            int moji;
            System.out.print(bangou + " "); 
            // 意図不明
            moji = namae.length(); 
            moji --;     // 間の空白分を文字数から減らす 
            System.out.print(namae); 

            // 氏名の文字数による間隔の調整 
            for(int i = 0;i <= 6 - namae.length();i++) {
                System.out.print("  "); 
            }

            // 英語の得点表示 
            if(eigo<100){ System.out.print(" "); }
            if(eigo<10) { System.out.print(" "); }
            System.out.print(eigo); 
            System.out.print("  ");

            // 国語の得点表示 
            if(kokugo<100){ System.out.print(" "); }
            if(kokugo<10) { System.out.print(" "); }
            System.out.print(kokugo); 
            System.out.print("  ");

            // 数学の得点表示 
            if(suugaku<100){ System.out.print(" "); }
            if(suugaku<10) { System.out.print(" "); }
            System.out.print(suugaku); 
            System.out.print("  ");

            // 合計得点表示 
            if(goukei<100){ System.out.print(" "); }
            if(goukei<10) { System.out.print(" "); }
            System.out.println(goukei); 
        } 
        // ５）goukeiの値を返すメソッド getGoukei()を作成してください。 
        public int getGoukei(){
            return goukei;
        }
    }

    public static void main( String arg[] ){
        // ここからは、kadai0903 を作成していきます。  
        /* ６）gakusei型の配列 g_tblを、 
     
        gakusei g_tbl[] = new gakusei[200]; 
        と宣言しておきます。 
        また、見出しを、 
        String kamoku = "番号 学生氏名 英語 国語 数学 合計"; 
        と宣言しておきます。 
        */
        gakusei g_tbl[] = new gakusei[200]; 
        String kamoku = "番号   学生氏名    英語 国語 数学 合計"; 

        /*
            ７）以下のように変数を宣言します。 
            String ban;      // 切り出した学生番号をセット 
            String sei;      // 切り出した姓をセット 
            String mei;      // 切り出した名をセット 
            String ei;      // 切り出した英語の得点をセット
            String koku;      // 切り出した国語の得点をセット 
            String suu;      // 切り出した数学の得点をセット 
            String name;      // 姓と名を半角の空白を挟んでセット 
 
            int t_eigo;      // 整数化した英語の得点をセット 
            int t_kokugo;      // 整数化した国語の得点をセット 
            int t_suugaku;      // 整数化した数学の得点をセット 
             
            int g_eigo=0;      // 英語の合計 
            int g_kokugo=0;    // 国語の合計 
            int g_suugaku=0;    // 数学の合計 
            int g_goukei=0;     // 総合計 
             
            double h_eigo;      // 英語の平均点 
            double h_kokugo;    // 国語の平均点 
            double h_suugaku;    // 数学の平均点 
            double h_goukei;    // 合計の平均点 
             
            int max_eigo;      // 英語の最高点 
            int min_eigo;      // 英語の最低点 
            int max_kokugo;    // 国語の最高点 
            int min_kokugo;    // 国語の最低点 
            int max_suugaku;    // 数学の最高点 
            int min_suugaku;    // 数学の最低点 
            int max_goukei;    // 合計の最高点 
            int min_goukei;     // 合計の最低点 
            int nin = 0;      // 読み込んだデータ数 
         
            // 配列の並べ替えの際に使用する 
            gakusei work = new gakusei(); 
             
            その他の必要な変数は各自で宣言してください。 
        */

        String ban;      // 切り出した学生番号をセット 
        String sei;      // 切り出した姓をセット 
        String mei;      // 切り出した名をセット 
        String ei;      // 切り出した英語の得点をセット
        String koku;      // 切り出した国語の得点をセット 
        String suu;      // 切り出した数学の得点をセット 
        String name;      // 姓と名を半角の空白を挟んでセット 

        int t_eigo;      // 整数化した英語の得点をセット 
        int t_kokugo;      // 整数化した国語の得点をセット 
        int t_suugaku;      // 整数化した数学の得点をセット 
         
        int g_eigo=0;      // 英語の合計 
        int g_kokugo=0;    // 国語の合計 
        int g_suugaku=0;    // 数学の合計 
        int g_goukei=0;     // 総合計 
         
        double h_eigo;      // 英語の平均点 
        double h_kokugo;    // 国語の平均点 
        double h_suugaku;    // 数学の平均点 
        double h_goukei;    // 合計の平均点 
         
        int max_eigo = 0;      // 英語の最高点 
        int min_eigo = 100;      // 英語の最低点 
        int max_kokugo = 0;    // 国語の最高点 
        int min_kokugo = 100;    // 国語の最低点 
        int max_suugaku = 0;    // 数学の最高点 
        int min_suugaku = 100;    // 数学の最低点 
        int max_goukei = 0;    // 合計の最高点 
        int min_goukei = 300;     // 合計の最低点 
        int nin = 0;      // 読み込んだデータ数 
         
        // 配列の並べ替えの際に使用する 
        /* 意図不明のためnew削除 */
        gakusei work; // = new gakusei(); 
         
        // ８）seiseki.txt ファイルを１行読み込みます。
        FileInputStream fis;
        InputStreamReader isr;
        BufferedReader br;

        try {
            fis = new FileInputStream("seiseki.txt");
            isr = new InputStreamReader(fis,"UTF-8");
            br  = new BufferedReader(isr);
        } catch ( IOException e ){
            e.printStackTrace();
            return;
        }

        /* ファイルは、  
         
        J09001,阿久津,恵,79,56,67 
        J09002,荒,里美,66,45,86 
        J09003,新井,佳枝,63,58,92 
        J09004,飯野,良子,67,72,62 
        J09005,池田,愛美,100,81,76 
        J09006,石井,康代,67,55,92 
        J09007,石倉,真樹,90,79,82 
        J09008,石坂,奈緒子,92,85,70 
         
        のように、学生番号、姓、名、英語の得点、国語の得点、数学の得点がカンマで区切られています。 
        */
        String line = null;
        
        try{ line = br.readLine(); }
        catch (IOException e){
            e.printStackTrace();
            return;
        }

        // ------  13）while文を用いて、上記８）～12）までを繰り返します。 

        // ８）seiseki.txt ファイルを１行読み込みます。
        while( line != null ){

            // ９）それぞれの項目を切り出します。 
            String[] v = line.split(",");
            ban  = v[0];
            sei  = v[1];
            mei  = v[2];
            ei   = v[3];
            koku = v[4];
            suu  = v[5];
 
            // 10）Strng 型の変数 name を宣言し、切り出した姓と名を半角の空白を挟んで代入します。 
            name = sei + " " + mei;
 
            // 11）３科目の得点をそれぞれ整数に変換します。 
            t_eigo    = Integer.parseInt(ei);
            t_kokugo  = Integer.parseInt(koku);
            t_suugaku = Integer.parseInt(suu);
            // 12）引数のあるコンストラクタを用いて、配列 g_tblに gakusei オブジェクトを生成します。 
            g_tbl[nin] = new gakusei(ban,name,t_eigo,t_kokugo,t_suugaku);
            
            /*****  16）科目ごとの最高点、最低点、平均点 */
            if( max_eigo < t_eigo ){
                max_eigo = t_eigo;
            }
            if( max_kokugo < t_kokugo ){
                max_kokugo = t_kokugo;
            }
            if( max_suugaku < t_suugaku ){
                max_suugaku = t_suugaku;
            }
            if( max_goukei < g_tbl[nin].getGoukei() ){
                max_goukei = g_tbl[nin].getGoukei();
            }
            if( min_eigo > t_eigo ){
                min_eigo = t_eigo;
            }
            if( min_kokugo > t_kokugo ){
                min_kokugo = t_kokugo;
            }
            if( min_suugaku > t_suugaku ){
                min_suugaku = t_suugaku;
            }
            if( min_goukei > g_tbl[nin].getGoukei() ){
                min_goukei = g_tbl[nin].getGoukei();
            }

            g_eigo    += t_eigo;
            g_kokugo  += t_kokugo;
            g_suugaku += t_suugaku;
            g_goukei  += g_tbl[nin].getGoukei();



            // 上記８）～12）までを繰り返します。 
            nin++;
            try{ line = br.readLine(); }
            catch (IOException e){
                e.printStackTrace();
                return;
            }

        }
        // -----   13）while文を用いて、上記８）～12）までを繰り返します。 

        try {
            br.close();
            isr.close();
            fis.close();
        } catch ( IOException e ){
            e.printStackTrace();
            return;
        }
 
        // 14）配列の内容を goukei 点の高い順に並べ替えを行います。 
        for( int i = 0; i < ( nin - 1 ); i++ ){
            for( int j = 0; j < ( nin - 1 - i ); j++ ){
                if( g_tbl[j].getGoukei() < g_tbl[j+1].getGoukei() ){
                    work = g_tbl[j];
                    g_tbl[j] = g_tbl[j+1];
                    g_tbl[j+1] = work;
                }
            }
        }

        // 15）並べ替えた結果をメソッド showMeibo()を用いて表示します。 
        showMeibo(kamoku,g_tbl,nin);

 
        // 16）科目ごとの最高点、最低点、平均点を表示します。 
        
        
        h_eigo    = ( (double)g_eigo    / nin );
        h_kokugo  = ( (double)g_kokugo  / nin );
        h_suugaku = ( (double)g_suugaku / nin );
        h_goukei  = ( (double)g_goukei  / nin );

        System.out.println("-------------------------------------------------");
        
        System.out.println(
            String.format("英語 最高点:%3d  最低点：%3d  平均点：%18.14f",
                max_eigo,min_eigo,h_eigo)
        );
        System.out.println(
            String.format("国語 最高点:%3d  最低点：%3d  平均点：%18.14f",
                max_kokugo,min_kokugo,h_kokugo)
        );
        System.out.println(
            String.format("数学 最高点:%3d  最低点：%3d  平均点：%18.14f",
                max_suugaku,min_suugaku,h_suugaku)
        );
        System.out.println(
        String.format("合計 最高点:%3d  最低点：%3d  平均点：%18.14f",
                max_goukei,min_goukei,h_goukei)
        );
    }

    static public void showMeibo( String kamoku, gakusei[] gaku, int nin ){
        System.out.println(kamoku);
        for( int i = 0; i < nin; i++ ){
            gaku[i].showSeiseki();
        }
    }
 }

/* 
    実行結果 
    番号   学生氏名    英語 国語 数学 合計 
    J09064 斉藤 和子     93   96   96  285 
    J09137 福本 真紀     99   90   95  284 
    J09077 菅原 優子     96  100   86  282 
    J09013 市川 亜希     96   78   98  272 
    J09105 津坂 明子     69   49   48  166 
    J09158 矢作 美保     58   47   59  164 
    J09100 千葉 香奈子   67   33   62  162 
    J09086 大工原 亜香利 79   19   63  161 
    J09045 九鬼 麻美     48   48   58  154 
    J09082 関戸 美和     40   50   58  148 
    J09014 伊藤 菜穂子   48   51   48  147 
     
     
     
    ------------------------------------------------- 
    英語 最高点: 99 最低点： 23 平均点： 73.48235294117647 
    国語 最高点:100 最低点： 19 平均点： 71.45882352941176 
    数学 最高点:100 最低点： 38 平均点： 72.05294117647058 
    合計 最高点:285 最低点：147 平均点：216.99411764705883 
*/
