//***************************************************************************************************************************************************
//
// Copyright (C) 2021 Selim Temizer.
//
// This file is part of Course Statistics.
//
// Course Statistics is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
//
// Course Statistics is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License along with Course Statistics. If not, see <http://www.gnu.org/licenses/>.
//
//***************************************************************************************************************************************************




//***************************************************************************************************************************************************

package gui ;

//***************************************************************************************************************************************************




//***************************************************************************************************************************************************

import lib.VerifiedFileChooser          ;
import domain.GSHtml                    ;
import domain.Generator                 ;
import domain.GSNUGraduate              ;
import domain.GradingSystem             ;
import domain.GSNUUndergraduate         ;
import java.io.File                     ;
import java.util.List                   ;
import java.util.Calendar               ;
import javax.swing.ImageIcon            ;
import javax.swing.SwingUtilities       ;
import javax.swing.DefaultComboBoxModel ;

//***************************************************************************************************************************************************




//***************************************************************************************************************************************************

public class GuiMain extends javax.swing.JFrame
{
  //=================================================================================================================================================
  
  private              GuiDataSource         guiDataSource                            ;
  private final        List< GradingSystem > systems                                  ;
  private final        VerifiedFileChooser   excelFileChooser                         ;
  private static final long                  serialVersionUID = -3466556971507246321L ;

  //=================================================================================================================================================
  
  public GuiMain () throws Exception
  {
    //-----------------------------------------------------------------------------------------------------------------------------------------------
    
    initComponents() ;

    ImageIcon icon = new ImageIcon( this.getClass().getResource( "/media/Icon.png" ) ) ;    setIconImage( icon.getImage() ) ;

    //-----------------------------------------------------------------------------------------------------------------------------------------------

    excelFileChooser = new VerifiedFileChooser( /* Component  parent                           */ this                                ,
                                                /* File       initialOpenTarget                */ null                                ,
                                                /* File       initialSaveTarget                */ new File( "CourseStatistics.xlsx" ) ,
                                                /* String     descriptionForAcceptedExtensions */ "Excel Files"                       ,
                                                /* String ... acceptedExtensions               */ "xlsx"                              ) ;

    guiDataSource = null                         ;
    systems       = GSHtml.parseAll( "systems" ) ;

    // systems.add( new GSNUGraduate     () ) ;
    // systems.add( new GSNUUndergraduate() ) ;

    //-----------------------------------------------------------------------------------------------------------------------------------------------

    DefaultComboBoxModel< String > cbSystemModel = new DefaultComboBoxModel<>() ;

    for ( GradingSystem system : systems )  { cbSystemModel.addElement( system.getName() ) ; }

    cbSystem.setModel        ( cbSystemModel ) ;
    cbSystem.setSelectedIndex( 0             ) ;

    //-----------------------------------------------------------------------------------------------------------------------------------------------

    DefaultComboBoxModel< String > cbYearModel = new DefaultComboBoxModel<>()                ;
    int                            year        = Calendar.getInstance().get( Calendar.YEAR ) ;

    for ( int y = year - 2 ; y <= year + 2 ; y++ )  { cbYearModel.addElement( Integer.toString( y ) ) ; }

    cbYear.setModel       ( cbYearModel              ) ;
    cbYear.setSelectedItem( Integer.toString( year ) ) ;

    //-----------------------------------------------------------------------------------------------------------------------------------------------
  }

  //=================================================================================================================================================

  /**
   * This method is called from within the constructor to
   * initialize the form.
   * WARNING: Do NOT modify this code. The content of this method is
   * always regenerated by the Form Editor.
   */
  @SuppressWarnings( "unchecked" )
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents()
  {

    l1 = new javax.swing.JLabel();
    l2 = new javax.swing.JLabel();
    l3 = new javax.swing.JLabel();
    l4 = new javax.swing.JLabel();
    l5 = new javax.swing.JLabel();
    l6 = new javax.swing.JLabel();
    l7 = new javax.swing.JLabel();
    lAbout = new javax.swing.JLabel();
    tfCourse = new javax.swing.JTextField();
    cbSystem = new javax.swing.JComboBox<>();
    cbYear = new javax.swing.JComboBox<>();
    cbSemester = new javax.swing.JComboBox<>();
    tfCoordinator = new javax.swing.JTextField();
    tfNumStudents = new javax.swing.JTextField();
    tfNumAssessments = new javax.swing.JTextField();
    tfNumCLOs = new javax.swing.JTextField();
    bSetData = new javax.swing.JButton();
    bGenerateAndSaveExcel = new javax.swing.JButton();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
    setTitle("Course Statistics");
    setLocationByPlatform(true);

    l1.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
    l1.setText("Course Code and Title:");

    l2.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
    l2.setText("Grading System:");

    l3.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
    l3.setText("Year and Semester:");

    l4.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
    l4.setText("Course Coordinator:");

    l5.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
    l5.setText("Number of Students:");

    l6.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
    l6.setText("Number of Assessments:");

    l7.setHorizontalAlignment(javax.swing.SwingConstants.TRAILING);
    l7.setText("Number of CLOs:");

    lAbout.setForeground(new java.awt.Color(153, 153, 153));
    lAbout.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
    lAbout.setText("<html><center>Course Statistics<br>by<br>Selim Temizer</center>");
    lAbout.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(204, 204, 204)));

    cbSystem.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

    cbYear.setEditable(true);
    cbYear.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

    cbSemester.setEditable(true);
    cbSemester.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Spring", "Summer", "Fall" }));

    bSetData.setText("Set Assessments and Course Learning Outcomes (CLO) Data");
    bSetData.addActionListener(new java.awt.event.ActionListener()
    {
      public void actionPerformed(java.awt.event.ActionEvent evt)
      {
        bSetDataActionPerformed(evt);
      }
    });

    bGenerateAndSaveExcel.setText("Generate and Save Excel File");
    bGenerateAndSaveExcel.addActionListener(new java.awt.event.ActionListener()
    {
      public void actionPerformed(java.awt.event.ActionEvent evt)
      {
        bGenerateAndSaveExcelActionPerformed(evt);
      }
    });

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(layout.createSequentialGroup()
            .addComponent(l1)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(tfCourse))
          .addGroup(layout.createSequentialGroup()
            .addComponent(l2)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(cbSystem, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
          .addGroup(layout.createSequentialGroup()
            .addComponent(l3)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(cbYear, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(cbSemester, 0, 271, Short.MAX_VALUE))
          .addGroup(layout.createSequentialGroup()
            .addComponent(l4)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(tfCoordinator))
          .addGroup(layout.createSequentialGroup()
            .addComponent(l5)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(tfNumStudents))
          .addGroup(layout.createSequentialGroup()
            .addComponent(l6)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(tfNumAssessments))
          .addGroup(layout.createSequentialGroup()
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
              .addComponent(l7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
              .addComponent(lAbout))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
              .addComponent(tfNumCLOs)
              .addComponent(bSetData, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
              .addComponent(bGenerateAndSaveExcel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
        .addContainerGap())
    );

    layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {l1, l2, l3, l4, l5, l6, l7});

    layout.setVerticalGroup(
      layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
      .addGroup(layout.createSequentialGroup()
        .addContainerGap()
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(l1)
          .addComponent(tfCourse, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(l2)
          .addComponent(cbSystem, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(l3)
          .addComponent(cbYear, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
          .addComponent(cbSemester, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(l4)
          .addComponent(tfCoordinator, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(l5)
          .addComponent(tfNumStudents, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(l6)
          .addComponent(tfNumAssessments, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
          .addComponent(l7)
          .addComponent(tfNumCLOs, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(layout.createSequentialGroup()
            .addComponent(bSetData)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(bGenerateAndSaveExcel))
          .addComponent(lAbout, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE))
        .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
    );

    pack();
  }// </editor-fold>//GEN-END:initComponents

  private void bSetDataActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bSetDataActionPerformed
  {//GEN-HEADEREND:event_bSetDataActionPerformed
    try
    {
      int numAssessments = Integer.parseInt( tfNumAssessments.getText().trim() ) ;
      int numCLOs        = Integer.parseInt( tfNumCLOs       .getText().trim() ) ;

      if ( numAssessments < 1 )  { throw new RuntimeException( "At least 1 assessment required."                    ) ; }
      if ( numCLOs        < 1 )  { throw new RuntimeException( "At least 1 course learning outcome (CLO) required." ) ; }

      if ( guiDataSource != null )  { guiDataSource.dispose() ;  guiDataSource = null ; }

      SwingUtilities.invokeLater(new Runnable()
      {
        //@Override public void run ()  { guiDataSource = new GuiData1( numAssessments , numCLOs ) ;    guiDataSource.setVisible( true ) ; }
          @Override public void run ()  { guiDataSource = new GuiData2( numAssessments , numCLOs ) ;    guiDataSource.setVisible( true ) ; }
      } ) ;
    }
    catch ( Exception e )  { System.err.println( e.toString() ) ; }
  }//GEN-LAST:event_bSetDataActionPerformed

  private void bGenerateAndSaveExcelActionPerformed(java.awt.event.ActionEvent evt)//GEN-FIRST:event_bGenerateAndSaveExcelActionPerformed
  {//GEN-HEADEREND:event_bGenerateAndSaveExcelActionPerformed
    try
    {
      String codeAndTitle   =                   tfCourse        .getText()          .trim()   ;
      String systemName     = ( (String)        cbSystem        .getSelectedItem() ).trim()   ;
      String year           = ( (String)        cbYear          .getSelectedItem() ).trim()   ;
      String semester       = ( (String)        cbSemester      .getSelectedItem() ).trim()   ;
      String coordinator    =                   tfCoordinator   .getText()          .trim()   ;
      int    numStudents    = Integer.parseInt( tfNumStudents   .getText()          .trim() ) ;
      int    numAssessments = Integer.parseInt( tfNumAssessments.getText()          .trim() ) ;
      int    numCLOs        = Integer.parseInt( tfNumCLOs       .getText()          .trim() ) ;

      if ( numStudents    < 1 )  { throw new RuntimeException( "At least 1 student required."                       ) ; }
      if ( numAssessments < 1 )  { throw new RuntimeException( "At least 1 assessment required."                    ) ; }
      if ( numCLOs        < 1 )  { throw new RuntimeException( "At least 1 course learning outcome (CLO) required." ) ; }

      GradingSystem system    = GradingSystem.getSystem( systems , systemName ) ;
      Generator     generator = new Generator( codeAndTitle , system         , year    , semester      , coordinator      ,
                                               numStudents  , numAssessments , numCLOs , guiDataSource , excelFileChooser ) ;

      generator.save( generator.build() ) ;
    }
    catch ( Exception e )  { System.err.println( e.toString() ) ; }
  }//GEN-LAST:event_bGenerateAndSaveExcelActionPerformed

  /**
   * @param args the command line arguments
   */
  public static void main ( String args[] )
  {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try
    {
      for ( javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels() )
      {
        if ( "Windows".equals( info.getName() ) )
        {
          javax.swing.UIManager.setLookAndFeel( info.getClassName() );
          break;
        }
      }
    }
    catch ( ClassNotFoundException ex )
    {
      java.util.logging.Logger.getLogger( GuiMain.class.getName() ).log( java.util.logging.Level.SEVERE , null , ex );
    }
    catch ( InstantiationException ex )
    {
      java.util.logging.Logger.getLogger( GuiMain.class.getName() ).log( java.util.logging.Level.SEVERE , null , ex );
    }
    catch ( IllegalAccessException ex )
    {
      java.util.logging.Logger.getLogger( GuiMain.class.getName() ).log( java.util.logging.Level.SEVERE , null , ex );
    }
    catch ( javax.swing.UnsupportedLookAndFeelException ex )
    {
      java.util.logging.Logger.getLogger( GuiMain.class.getName() ).log( java.util.logging.Level.SEVERE , null , ex );
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater( new Runnable()
    {
      @Override public void run ()
      {
        try                    { new GuiMain().setVisible( true )   ; }
        catch ( Exception e )  { System.err.println( e.toString() ) ; }
      }
    } ) ;
  }

  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JButton bGenerateAndSaveExcel;
  private javax.swing.JButton bSetData;
  private javax.swing.JComboBox<String> cbSemester;
  private javax.swing.JComboBox<String> cbSystem;
  private javax.swing.JComboBox<String> cbYear;
  private javax.swing.JLabel l1;
  private javax.swing.JLabel l2;
  private javax.swing.JLabel l3;
  private javax.swing.JLabel l4;
  private javax.swing.JLabel l5;
  private javax.swing.JLabel l6;
  private javax.swing.JLabel l7;
  private javax.swing.JLabel lAbout;
  private javax.swing.JTextField tfCoordinator;
  private javax.swing.JTextField tfCourse;
  private javax.swing.JTextField tfNumAssessments;
  private javax.swing.JTextField tfNumCLOs;
  private javax.swing.JTextField tfNumStudents;
  // End of variables declaration//GEN-END:variables
}

//***************************************************************************************************************************************************