package submissionsystem;

import assignment.Assignment;
import it.zielke.moji.MossException;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListModel;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import net.lingala.zip4j.core.*;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.*;
import org.apache.commons.io.FileUtils;
import submissionsystem.*;
/**
 *
 * @author Abdullah Talayhan
 */
public class InsMain extends javax.swing.JFrame {

    Client client;
    ArrayList<Assignment> allAssignments;
    ArrayList<Assignment> allSubmissionsInAsgn;
    FileInputStream fis;
    FileOutputStream fos;
    File[] allMossFiles;
    /**
     * Creates new form InsMain
     */
    public InsMain(Client pclient) {
        client = pclient;
        
        initComponents();
        studentTable.setModel( new DefaultTableModel());
        subTable.setModel(new DefaultTableModel());
        courseTitleLabel.setText("");
        courseTitleLabel2.setText("");
        init();
        addedFilesArea.setText("");
        downAsgnBtn.setVisible(false);
        asgnNameLabel.setVisible(false);
        asgnDueLabel.setVisible(false);
        //initTabs();
        asgnCombo.addActionListener (new ActionListener () {
            public void actionPerformed(ActionEvent e) {
                DefaultTableModel asgnTableModel;
                //studentTable.setModel(panelTableModel);
                client.sendUTFDataToServer("GET_SUBMISSIONS");
                client.sendUTFDataToServer(courseTitleLabel2.getText());
                client.sendUTFDataToServer((String) asgnCombo.getSelectedItem());
                
                asgnTableModel = (DefaultTableModel) client.getObjectFromServer();
                allSubmissionsInAsgn = (ArrayList<Assignment>) client.getObjectFromServer();
                subTable.setModel(asgnTableModel);
                asgnNameLabel.setVisible(true);
                asgnDueLabel.setVisible(true);
                asgnNameLabel.setText("Assignment: " + (String)asgnCombo.getSelectedItem());
                
                asgnDueLabel.setText("Due Date: " + allAssignments.get(asgnCombo.getSelectedIndex()).getDuedate());
                downAsgnBtn.setVisible(true);
            }
        });
        
        
        initSubTable();
        
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                client.closeConnection();
            }
        });
    }

    /**
     * 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() {

        myCourseLabel = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        courseList = new javax.swing.JList();
        addCourseButton = new javax.swing.JButton();
        mainTabs = new javax.swing.JTabbedPane();
        coursePanel = new javax.swing.JPanel();
        cName1Label = new javax.swing.JLabel();
        courseTitleLabel = new javax.swing.JLabel();
        jScrollPane2 = new javax.swing.JScrollPane();
        studentTable = new javax.swing.JTable();
        pubAssignButton = new javax.swing.JButton();
        userNameLabel = new javax.swing.JLabel();
        assignmentPanel = new javax.swing.JPanel();
        cName2Label = new javax.swing.JLabel();
        courseTitleLabel2 = new javax.swing.JLabel();
        jScrollPane3 = new javax.swing.JScrollPane();
        subTable = new javax.swing.JTable();
        asgnCombo = new javax.swing.JComboBox();
        downSubBtn = new javax.swing.JButton();
        gradeLabel = new javax.swing.JLabel();
        gradeField = new javax.swing.JTextField();
        sendGradeBtn = new javax.swing.JButton();
        asgnNameLabel = new javax.swing.JLabel();
        asgnDueLabel = new javax.swing.JLabel();
        downAsgnBtn = new javax.swing.JButton();
        refreshBtn = new javax.swing.JButton();
        mossPanel = new javax.swing.JPanel();
        mossToolPanel = new javax.swing.JPanel();
        welcomeMossLabel = new javax.swing.JLabel();
        mossPrpLabel = new javax.swing.JLabel();
        chooseMossFileBtn = new javax.swing.JButton();
        jScrollPane4 = new javax.swing.JScrollPane();
        addedFilesArea = new javax.swing.JTextArea();
        getMossBtn = new javax.swing.JButton();
        mossLinkLabel = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Instructor Control Panel");

        myCourseLabel.setText("My Courses: ");

        courseList.setModel(new javax.swing.AbstractListModel() {
            String[] strings = { "CS102-02", "CS223-01", "CS319-02" };
            public int getSize() { return strings.length; }
            public Object getElementAt(int i) { return strings[i]; }
        });
        jScrollPane1.setViewportView(courseList);

        addCourseButton.setText("Add Course");
        addCourseButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                addCourseButtonActionPerformed(evt);
            }
        });

        coursePanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        cName1Label.setText("Course Name: ");

        courseTitleLabel.setText("CS102-02");

        studentTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {"1", "29866079", "lab01", "04.10.2016",  new Boolean(false),  new Boolean(false)},
                {"2", "61618675", "lab02", "11.10.2016",  new Boolean(false),  new Boolean(false)},
                {"3", "59022017", "lab03", "18.10.2016", null,  new Boolean(true)},
                {"4", "44546138", "lab04", "25.10.2016",  new Boolean(true),  new Boolean(true)},
                {"5", "60437855", "lab05", "02.11.2016", null,  new Boolean(true)},
                {"6", "67873316", "lab06", "16.11.2016", null,  new Boolean(true)},
                {"7", "27908627", "lab07", "23.11.2016",  new Boolean(true), null},
                {"8", "17570421", "lab08", "30.11.2016", null,  new Boolean(true)},
                {"9", "64320744", "lab09", "06.11.2016", null,  new Boolean(true)}
            },
            new String [] {
                "No ▲", "ID", "Assignment", "Due Date", "Auto Grading", "Moss Check"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.Object.class, java.lang.Object.class, java.lang.String.class, java.lang.Object.class, java.lang.Boolean.class, java.lang.Boolean.class
            };
            boolean[] canEdit = new boolean [] {
                true, true, true, true, false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jScrollPane2.setViewportView(studentTable);

        pubAssignButton.setText("Send Assignment");
        pubAssignButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                pubAssignButtonActionPerformed(evt);
            }
        });

        userNameLabel.setText("jLabel5");

        javax.swing.GroupLayout coursePanelLayout = new javax.swing.GroupLayout(coursePanel);
        coursePanel.setLayout(coursePanelLayout);
        coursePanelLayout.setHorizontalGroup(
            coursePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(coursePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(coursePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(coursePanelLayout.createSequentialGroup()
                        .addComponent(cName1Label)
                        .addGap(30, 30, 30)
                        .addComponent(courseTitleLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(userNameLabel)
                        .addGap(174, 174, 174))
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 627, Short.MAX_VALUE)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, coursePanelLayout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(pubAssignButton)))
                .addContainerGap())
        );
        coursePanelLayout.setVerticalGroup(
            coursePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(coursePanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(coursePanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cName1Label)
                    .addComponent(courseTitleLabel)
                    .addComponent(userNameLabel))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 233, Short.MAX_VALUE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(pubAssignButton)
                .addGap(6, 6, 6))
        );

        mainTabs.addTab("Students", coursePanel);

        assignmentPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        cName2Label.setText("Course Name: ");

        courseTitleLabel2.setText("CS102-02");

        subTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {
                {"1", "29866079", "lab01", "04.10.2016",  new Boolean(false),  new Boolean(false)},
                {"2", "61618675", "lab02", "11.10.2016",  new Boolean(false),  new Boolean(false)},
                {"3", "59022017", "lab03", "18.10.2016", null,  new Boolean(true)},
                {"4", "44546138", "lab04", "25.10.2016",  new Boolean(true),  new Boolean(true)},
                {"5", "60437855", "lab05", "02.11.2016", null,  new Boolean(true)},
                {"6", "67873316", "lab06", "16.11.2016", null,  new Boolean(true)},
                {"7", "27908627", "lab07", "23.11.2016",  new Boolean(true), null},
                {"8", "17570421", "lab08", "30.11.2016", null,  new Boolean(true)},
                {"9", "64320744", "lab09", "06.11.2016", null,  new Boolean(true)}
            },
            new String [] {
                "No ▲", "ID", "Assignment", "Due Date", "Auto Grading", "Moss Check"
            }
        ) {
            Class[] types = new Class [] {
                java.lang.Object.class, java.lang.Object.class, java.lang.String.class, java.lang.Object.class, java.lang.Boolean.class, java.lang.Boolean.class
            };
            boolean[] canEdit = new boolean [] {
                true, true, true, true, false, false
            };

            public Class getColumnClass(int columnIndex) {
                return types [columnIndex];
            }

            public boolean isCellEditable(int rowIndex, int columnIndex) {
                return canEdit [columnIndex];
            }
        });
        jScrollPane3.setViewportView(subTable);

        asgnCombo.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        asgnCombo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                asgnComboActionPerformed(evt);
            }
        });

        downSubBtn.setText("Download Submission");
        downSubBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                downSubBtnActionPerformed(evt);
            }
        });

        gradeLabel.setText("Grade: ");

        sendGradeBtn.setText("Send Grade");
        sendGradeBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                sendGradeBtnActionPerformed(evt);
            }
        });

        asgnNameLabel.setText("Assignment: ");

        asgnDueLabel.setText("Due Date:");

        downAsgnBtn.setText("Download Assignment");
        downAsgnBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                downAsgnBtnActionPerformed(evt);
            }
        });

        refreshBtn.setText("Refresh");
        refreshBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                refreshBtnActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout assignmentPanelLayout = new javax.swing.GroupLayout(assignmentPanel);
        assignmentPanel.setLayout(assignmentPanelLayout);
        assignmentPanelLayout.setHorizontalGroup(
            assignmentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(assignmentPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(assignmentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, assignmentPanelLayout.createSequentialGroup()
                        .addComponent(cName2Label)
                        .addGap(30, 30, 30)
                        .addComponent(courseTitleLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(refreshBtn)
                        .addGap(8, 8, 8))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, assignmentPanelLayout.createSequentialGroup()
                        .addGroup(assignmentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(asgnNameLabel)
                            .addComponent(asgnDueLabel)
                            .addComponent(asgnCombo, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(downAsgnBtn))
                        .addGap(21, 21, 21)
                        .addGroup(assignmentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(assignmentPanelLayout.createSequentialGroup()
                                .addComponent(downSubBtn, javax.swing.GroupLayout.PREFERRED_SIZE, 152, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                .addComponent(gradeLabel)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(gradeField, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(sendGradeBtn))
                            .addComponent(jScrollPane3, javax.swing.GroupLayout.DEFAULT_SIZE, 469, Short.MAX_VALUE))))
                .addContainerGap())
        );
        assignmentPanelLayout.setVerticalGroup(
            assignmentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(assignmentPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(assignmentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(cName2Label)
                    .addComponent(courseTitleLabel2)
                    .addComponent(refreshBtn))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(assignmentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(assignmentPanelLayout.createSequentialGroup()
                        .addComponent(asgnCombo, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(36, 36, 36)
                        .addComponent(asgnNameLabel)
                        .addGap(18, 18, 18)
                        .addComponent(asgnDueLabel)
                        .addGap(18, 18, 18)
                        .addComponent(downAsgnBtn)
                        .addGap(0, 105, Short.MAX_VALUE))
                    .addGroup(assignmentPanelLayout.createSequentialGroup()
                        .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(assignmentPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(sendGradeBtn)
                            .addComponent(gradeField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(gradeLabel)
                            .addComponent(downSubBtn))))
                .addContainerGap())
        );

        mainTabs.addTab("Assignments", assignmentPanel);

        mossToolPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));

        welcomeMossLabel.setText("Welcome to Moss Tool");

        mossPrpLabel.setText("Select the assignment zip files you want to check similarity for:");

        chooseMossFileBtn.setText("Select Files");
        chooseMossFileBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chooseMossFileBtnActionPerformed(evt);
            }
        });

        addedFilesArea.setColumns(20);
        addedFilesArea.setRows(5);
        jScrollPane4.setViewportView(addedFilesArea);

        getMossBtn.setText("Generate Moss Link");
        getMossBtn.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                getMossBtnActionPerformed(evt);
            }
        });

        mossLinkLabel.setText("It may take a while to generate the link depending on the Moss server load.");
        mossLinkLabel.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                mossLinkLabelMouseClicked(evt);
            }
        });

        javax.swing.GroupLayout mossToolPanelLayout = new javax.swing.GroupLayout(mossToolPanel);
        mossToolPanel.setLayout(mossToolPanelLayout);
        mossToolPanelLayout.setHorizontalGroup(
            mossToolPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mossToolPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(mossToolPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(welcomeMossLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 188, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(mossToolPanelLayout.createSequentialGroup()
                        .addComponent(mossPrpLabel)
                        .addGap(18, 18, 18)
                        .addComponent(chooseMossFileBtn))
                    .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 402, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(mossToolPanelLayout.createSequentialGroup()
                        .addComponent(getMossBtn)
                        .addGap(18, 18, 18)
                        .addComponent(mossLinkLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 417, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(23, Short.MAX_VALUE))
        );
        mossToolPanelLayout.setVerticalGroup(
            mossToolPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mossToolPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(welcomeMossLabel)
                .addGap(23, 23, 23)
                .addGroup(mossToolPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(mossPrpLabel)
                    .addComponent(chooseMossFileBtn))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jScrollPane4, javax.swing.GroupLayout.PREFERRED_SIZE, 147, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(mossToolPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(getMossBtn)
                    .addComponent(mossLinkLabel))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        javax.swing.GroupLayout mossPanelLayout = new javax.swing.GroupLayout(mossPanel);
        mossPanel.setLayout(mossPanelLayout);
        mossPanelLayout.setHorizontalGroup(
            mossPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mossPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(mossToolPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        mossPanelLayout.setVerticalGroup(
            mossPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(mossPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(mossToolPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addContainerGap())
        );

        mainTabs.addTab("Moss Tool", mossPanel);

        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, false)
                    .addComponent(addCourseButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jScrollPane1)
                    .addComponent(myCourseLabel))
                .addGap(18, 18, 18)
                .addComponent(mainTabs, javax.swing.GroupLayout.PREFERRED_SIZE, 654, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(33, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(mainTabs, javax.swing.GroupLayout.PREFERRED_SIZE, 334, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(myCourseLabel)
                        .addGap(3, 3, 3)
                        .addComponent(jScrollPane1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(addCourseButton)))
                .addContainerGap(25, Short.MAX_VALUE))
        );

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

    /**
     * adds the courses of the instructor
     */
    private void addCourseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addCourseButtonActionPerformed
        // TODO add your handling code here:
        CourseReg createCourseFrame = new CourseReg(client, this);
        createCourseFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        createCourseFrame.setLocationRelativeTo(this);
        createCourseFrame.setVisible(true);
    }//GEN-LAST:event_addCourseButtonActionPerformed
    
    /**
     * publish assignment
     */
    private void pubAssignButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_pubAssignButtonActionPerformed
        // TODO add your handling code here:
        if(courseTitleLabel.getText().equals("")) {
            JOptionPane.showMessageDialog(this, "Please select a course", "Call-IDE Error!", JOptionPane.WARNING_MESSAGE);
        }
        else {
            SendAssignment sendFrame = new SendAssignment(client, courseTitleLabel.getText());
            sendFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            sendFrame.setLocationRelativeTo(this);
            sendFrame.setVisible(true);
        }
    }//GEN-LAST:event_pubAssignButtonActionPerformed

    private void asgnComboActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_asgnComboActionPerformed
        // TODO add your handling code here:
        
    }//GEN-LAST:event_asgnComboActionPerformed
    
    /**
     * Send the grade to the submisson
     */
    private void sendGradeBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_sendGradeBtnActionPerformed
        // TODO add your handling code here:
        String email = subTable.getValueAt(subTable.getSelectedRow(), 1).toString();
        int grade = Integer.parseInt(gradeField.getText());
        int index = asgnCombo.getSelectedIndex();
        
        Assignment asgnToGrade = allAssignments.get(index);
        client.sendUTFDataToServer("SEND_GRADE");
        client.sendUTFDataToServer(email);
        client.sendIntDataToServer(grade);
        client.sendUTFDataToServer(asgnToGrade.getName());
        
    }//GEN-LAST:event_sendGradeBtnActionPerformed
    
    /**
     * download submission or assignment from server
     * @param toDown assignment or submission to be downloaded
     */
    private void downloadFrom(Assignment toDown ) {
        client.sendUTFDataToServer("DOWNLOAD_SUBS");
        client.sendObjectToServer(toDown);
        
        JFileChooser chooser = new JFileChooser();
        chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
        chooser.showOpenDialog(this);
        File downFolder = chooser.getSelectedFile();
        
        
        byte[] data = (byte[]) client.getObjectFromServer();
        try {
            fos = new FileOutputStream(downFolder.getAbsolutePath() + "/" + toDown.getName() + ".zip");
            fos.write(data);
            fos.close();
        } catch (IOException ex) {
            Logger.getLogger(StudentMain.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        
    }
    
    private void downSubBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_downSubBtnActionPerformed
        // TODO add your handling code here:
        int index = subTable.getSelectedRow();
        Assignment toDown = allSubmissionsInAsgn.get(index);
        downloadFrom(toDown);
        
        
    }//GEN-LAST:event_downSubBtnActionPerformed

    private void downAsgnBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_downAsgnBtnActionPerformed
        // TODO add your handling code here:
        int index = asgnCombo.getSelectedIndex();
        
        Assignment asgnToDown = allAssignments.get(index);
        downloadFrom(asgnToDown);
    }//GEN-LAST:event_downAsgnBtnActionPerformed

    private void refreshBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshBtnActionPerformed
        // TODO add your handling code here:
        //JList list = (JList) evt.getSource();
        int index = courseList.getSelectedIndex();
        if(index != -1) {
        //constructCoursePanel(index);
            constuctAssignmentPanel(index);
        }
    }//GEN-LAST:event_refreshBtnActionPerformed
    
    /**
     * choose the files for moss
     */
    private void chooseMossFileBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chooseMossFileBtnActionPerformed
        // TODO add your handling code here:
        JFileChooser chooseMoss = new JFileChooser();
        chooseMoss.setFileSelectionMode(JFileChooser.FILES_ONLY);
        chooseMoss.setMultiSelectionEnabled(true);
        chooseMoss.showOpenDialog(this);
        
        allMossFiles = chooseMoss.getSelectedFiles();
        for(File f : allMossFiles) {
            addedFilesArea.append(f.getAbsolutePath()+"\n");
        }
    }//GEN-LAST:event_chooseMossFileBtnActionPerformed
    
    /**
     * gets the moss link
     */
    private void getMossBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_getMossBtnActionPerformed
        String dest = System.getProperty("user.home") + "/Call-IDE/" + "Moss/Null";
        File destFolder = new File(dest);
        if (!destFolder.getParentFile().exists())
            destFolder.getParentFile().mkdir();
        if (!destFolder.exists())
            destFolder.mkdir();
        File finFolder = null;
        try {
            for(int i = 0; i < allMossFiles.length; i++) {
            // TODO add your handling code here:
            ZipFile zipFile = new ZipFile(allMossFiles[i]);
            
            // Get the list of file headers from the zip file
            List fileHeaderList = zipFile.getFileHeaders();
            
            // Loop through the file headers
            for (int j = 0; j < fileHeaderList.size(); j++) {
                FileHeader fileHeader = (FileHeader)fileHeaderList.get(j);
                String fileName = fileHeader.getFileName();
                if(fileName.endsWith(".java")){
                    //System.out.println(dest + "/" + allMossFiles[i].getName().substring(0, allMossFiles[i].getName().length() - 4));
                    new File(dest + "/" + allMossFiles[i].getName().substring(0, allMossFiles[i].getName().length() - 4)).mkdir();
                    zipFile.extractFile(fileHeader, dest +  "/" +allMossFiles[i].getName().substring(0, allMossFiles[i].getName().length() - 4));
                    
                }
                //System.out.println(fileHeader.getFileName());
            }
            if(allMossFiles[i].getAbsolutePath().contains(".zip")) {
                String tempName = allMossFiles[i].getName().substring(0, allMossFiles[i].getName().length() - 4);
                File tempFile = new File(dest + "/" + tempName);
                //System.out.println(tempFile.getAbsolutePath());
                String destName = System.getProperty("user.home") + "/Call-IDE/" + "Moss/moss-dir";
                String destFix = System.getProperty("user.home") + "/Call-IDE/" + "Moss/moss-base-dir";
                new File(destFix).mkdir();
                new File(destName).mkdir();
                finFolder = new File(destName);
                new File(destName + "/" + tempName).mkdir();
                File destFile = new File(destName + "/" + tempName);
                //System.out.println(destFile);
                walkFiles(tempFile, destFile);
            }
            }
        } catch (ZipException ex) {
            Logger.getLogger(InsMain.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        try {
            MossDetector detector = new MossDetector(finFolder.getParent());
            // System.out.println(detector.getMossLink());
            mossLinkLabel.setText(detector.getMossLink().toString());
            FileUtils.cleanDirectory(finFolder);
            FileUtils.cleanDirectory(new File(dest));
        } catch (MossException ex) {
            Logger.getLogger(InsMain.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(InsMain.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_getMossBtnActionPerformed

    private void mossLinkLabelMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_mossLinkLabelMouseClicked
        try {
            // TODO add your handling code here:
            if(mossLinkLabel.getText().contains("moss.stanford"))
                Desktop.getDesktop().browse(new URI(mossLinkLabel.getText()));
        } catch (IOException ex) {
            Logger.getLogger(InsMain.class.getName()).log(Level.SEVERE, null, ex);
        } catch (URISyntaxException ex) {
            Logger.getLogger(InsMain.class.getName()).log(Level.SEVERE, null, ex);
        }
    }//GEN-LAST:event_mossLinkLabelMouseClicked
    /**
     * Decription: walks all the files in a given directory and filtes the java files
     * @param folder folder to be walked
     * @param dest directory for storing the filtered files
     */
    public static void walkFiles( File folder, File dest) {
        Queue<File> dirsq = new LinkedList<>();
            dirsq.add(folder);
            while (!dirsq.isEmpty()) {
                for (File f : dirsq.poll().listFiles()) {
                    if (f.isDirectory()) {
                        dirsq.add(f);
                    } else if (f.isFile() && f.getAbsolutePath().endsWith(".java")) {
                        // System.out.println(f.getAbsolutePath());
                        try {
                            Files.copy(f.toPath(), dest.toPath().resolve(f.toPath().getFileName()));
                        } catch (IOException ex) {
                            //Logger.getLogger(JavaApplication1.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                }
            }
    
    }
    
    public void initTabs() {
        mainTabs.addChangeListener(new ChangeListener() {
            public void stateChanged(ChangeEvent e) {
                //TODO
                //System.out.println("Tab: " + tabbedPane.getSelectedIndex());
                // Prints the string 3 times if there are 3 tabs etc
            }
        });
    }
    /**
     * initialize the other components of the frame
     */
    public void init() {
        userNameLabel.setText("Welcome: " + client.getName());
        courseList.setModel(new DefaultListModel());
        client.sendUTFDataToServer("GET_COURSES");
        courseArrList = (ArrayList)client.getObjectFromServer();
        model = (DefaultListModel) courseList.getModel();
        model.clear();
        for(String s : courseArrList) {
            model.addElement(s);
        }
        if(courseArrList.size() == 0) {
            model.addElement("No Course");
        }
        courseList.setModel(model);
        courseList.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent evt) {
                
                
                JList list = (JList) evt.getSource();
                int index = list.getSelectedIndex();
                if(index != -1) {
                constructCoursePanel(index);
                constuctAssignmentPanel(index);
                }
            }
        });
        
        downSubBtn.setEnabled(false);
        gradeField.setEditable(false);
        sendGradeBtn.setEnabled(false); 
    }
    /**
     * update the course list
     */
    public void updateCourseList() {
        courseList.setModel(new DefaultListModel());
        client.sendUTFDataToServer("GET_COURSES");
        courseArrList = (ArrayList)client.getObjectFromServer();
        model = (DefaultListModel) courseList.getModel();
        //model.clear();
        for(String s : courseArrList) {
            model.addElement(s);
        }
        courseList.setModel(model);
    }
    public void constructCoursePanel(int index) {
        String course = (String) model.getElementAt(index);
        courseTitleLabel2.setText(course);
        
        client.sendUTFDataToServer("CONSTRUCT_STUDENT_PANEL");
        client.sendUTFDataToServer(course);
        
        DefaultTableModel panelTableModel = (DefaultTableModel)client.getObjectFromServer();
        studentTable.setModel(panelTableModel);
    }
    
    /**
     * constucts the assignments panel
     * @param index selected course index
     */
    public void constuctAssignmentPanel(int index) {
        String course = (String) model.getElementAt(index);
        courseTitleLabel.setText(course);
        // System.out.println("inside");
        client.sendUTFDataToServer("CONSTRUCT_ASSIGNMENT_PANEL");
        client.sendUTFDataToServer(course);
        allAssignments = (ArrayList<Assignment>) client.getObjectFromServer();
        //System.out.println(allAssignments);
        ArrayList<String> allAsgnNames = new ArrayList<String>();
        
        for(int i = 0; i < allAssignments.size();i++) {
            allAsgnNames.add(allAssignments.get(i).getName());
        }
            
        asgnCombo.setModel( new DefaultComboBoxModel(allAsgnNames.toArray()));
        
        //DefaultTableModel panelTableModel = (DefaultTableModel)client.getObjectFromServer();
        //studentTable.setModel(panelTableModel);
    }
    
    /**
     * initialize the submissions tables
     */
    public void initSubTable() {
        
        subTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
        @Override
        public void valueChanged(ListSelectionEvent event) {
            if (subTable.getSelectedRow() > -1) {
                // print first column value from selected row
                // System.out.println(subTable.getValueAt(subTable.getSelectedRow(), 0).toString());
                downSubBtn.setEnabled(true);
                gradeField.setEditable(true);
                sendGradeBtn.setEnabled(true);
            }
            else {
               downSubBtn.setEnabled(false);
               gradeField.setEditable(false);
               sendGradeBtn.setEnabled(false); 
            }
        }
        });
    }
    
    // other vairables
    public ArrayList<String> courseArrList;
    public DefaultListModel model;
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton addCourseButton;
    private javax.swing.JTextArea addedFilesArea;
    private javax.swing.JComboBox asgnCombo;
    private javax.swing.JLabel asgnDueLabel;
    private javax.swing.JLabel asgnNameLabel;
    private javax.swing.JPanel assignmentPanel;
    private javax.swing.JLabel cName1Label;
    private javax.swing.JLabel cName2Label;
    private javax.swing.JButton chooseMossFileBtn;
    private javax.swing.JList courseList;
    private javax.swing.JPanel coursePanel;
    private javax.swing.JLabel courseTitleLabel;
    private javax.swing.JLabel courseTitleLabel2;
    private javax.swing.JButton downAsgnBtn;
    private javax.swing.JButton downSubBtn;
    private javax.swing.JButton getMossBtn;
    private javax.swing.JTextField gradeField;
    private javax.swing.JLabel gradeLabel;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JScrollPane jScrollPane4;
    private javax.swing.JTabbedPane mainTabs;
    private javax.swing.JLabel mossLinkLabel;
    private javax.swing.JPanel mossPanel;
    private javax.swing.JLabel mossPrpLabel;
    private javax.swing.JPanel mossToolPanel;
    private javax.swing.JLabel myCourseLabel;
    private javax.swing.JButton pubAssignButton;
    private javax.swing.JButton refreshBtn;
    private javax.swing.JButton sendGradeBtn;
    private javax.swing.JTable studentTable;
    private javax.swing.JTable subTable;
    private javax.swing.JLabel userNameLabel;
    private javax.swing.JLabel welcomeMossLabel;
    // End of variables declaration//GEN-END:variables

   
}