package interactiveproject.slotmachine;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Timer;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
/**
 *
 * @author ronny
 */
public class MainFrame extends javax.swing.JFrame {

    /*to simplify it for students, reel is an integer in the slotmachine.
    * here it is represented by a seperate class.
     */
    private Reel reel1 = new Reel(2, 6);
    private Reel reel2 = new Reel(3, 6);
    private Reel reel3 = new Reel(0, 6);

    private int reel1Number = 0;
    private int reel2Number = 0;
    private int reel3Number = 0;
        
    //sizes for the Panel
    private double ratioWidth = 0.173;
    private double ratioHeight = 0.273;
    
    
    //To see if error messages in updateView have already been shown
    private boolean messageError = false;
    private boolean creditError = false;
    private boolean reelError = false;

    //link to the students implementation
    private Object studentObject;
    private Class studentClass;

    
    
    
    private int transitionTime = 2000;

    private int timeCounter = 0;
    
    private Timer checkTimer = new Timer(50, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            getReels();
            reel1.setReel(reel1Number);
            reel2.setReel(reel2Number);
            reel3.setReel(reel3Number);
            updateView();
        }
    });
    
    private Timer timer = new Timer(10, new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            timeCounter+=10;
            if (timeCounter > transitionTime+100) {
                timer.stop();
                timeCounter = 0;
                checkTimer.start();
                try {
                    Method method;
                    method = studentClass.getMethod("hasWon");
                    Object o = method.invoke(studentObject);
                    System.out.println((boolean) o);
                } catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException ex) {

                    System.out.println("Le programme ne peut pas encore contrôler si le joueur a gagné, comme la méthode hasWon n'existe pas encore.");

                }

            }
            updateView();
        }
    });

    /**
     * Creates new form MainFrame
     */
    
    public MainFrame() {
        this.setResizable(false);
        try {
            initComponents();
            reelPanel1.setReel(reel1);
            reelPanel2.setReel(reel2);
            reelPanel3.setReel(reel3);

            studentClass = Class.forName("interactiveproject.slotmachine.SlotMachine");
            studentObject = studentClass.newInstance();
            checkTimer.start();
            updateView();
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    
    public void updateView() {
        Method method;
        try {
            method = studentClass.getMethod("getMessage");
            Object o = method.invoke(studentObject);
            String str = (String) o;
            if(str.isEmpty())
                messageLabel.setText(" ");
            else
                messageLabel.setText(str);
        } catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException ex) {
            if (!messageError) {
                System.out.println("Aucun message n'est affiché comme la méthode String getMessage() n'existe pas.");
                messageError = true;
            }
        }

        try {
            method = studentClass.getMethod("getCredit");
            Object o = method.invoke(studentObject);
            String str = String.valueOf((int) o);
            if(str.isEmpty())
                creditLabel.setText(" ");
            else
                creditLabel.setText("Your credit is: " + str);
        } catch (SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException ex) {
            if (!creditError) {
                System.out.println("Le crédit restant ne peut pas être affiché comme la méthode int getCredit n'existe pas.");
                creditError = true;
            }
        }
        reelPanel1.repaint();
        reelPanel2.repaint();
        reelPanel3.repaint();
    }
    
    public boolean getReels()
    {
        boolean working = true;
        Method method;
        try {
            method = studentClass.getMethod("getReel1");
            reel1Number = (int) method.invoke(studentObject);
        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
            if(!reelError)
                System.out.println("La méthode public int getReel1() n'existe pas dans SlotMachine");
            working = false;
        }

        try {
            method = studentClass.getMethod("getReel2");
            reel2Number = (int) method.invoke(studentObject);
        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
            if(!reelError)
                System.out.println("La méthode int getReel2() n'existe pas dans SlotMachine");
            working = false;
        }

        try {
            method = studentClass.getMethod("getReel3");
            reel3Number = (int) method.invoke(studentObject);
        } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
            if(!reelError)
                System.out.println("La méthode int getReel3() n'existe pas dans SlotMachine");
            working = false;
        }
        if(!working)
            reelError = true;
        return working;
    }
    
    public void pullArm()
    {
        if(timer.isRunning())
            return;
        Method method;
        

        boolean enoughCredit = false;
        
        try {
            method = studentClass.getMethod("pullArm");
            Object o = method.invoke(studentObject);
            enoughCredit = (boolean) o;
            
        } catch (IllegalAccessException | SecurityException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException ex) {
            System.out.println("La méthode public void pullArm() n'existe pas dans SlotMachine");
            return;
        }

        if(!getReels())
            return;
        
        if (enoughCredit) 
        {
            checkTimer.stop();
            reel1.goToDestination(reel1Number, transitionTime);
            reel2.goToDestination(reel2Number, transitionTime);
            reel3.goToDestination(reel3Number, transitionTime);
            timer.start();
            
        }
    }

    public Object getStudentObject() {
        return studentObject;
    }

    public Class getStudentClass() {
        return studentClass;
    }

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

        drawPanel1 = new interactiveproject.slotmachine.DrawPanel();
        reelPanel2 = new interactiveproject.slotmachine.ReelPanel();
        reelPanel1 = new interactiveproject.slotmachine.ReelPanel();
        reelPanel3 = new interactiveproject.slotmachine.ReelPanel();
        armPanel = new javax.swing.JPanel();
        creditLabel = new javax.swing.JLabel();
        messageLabel = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        reelPanel2.addHierarchyBoundsListener(new java.awt.event.HierarchyBoundsListener() {
            public void ancestorMoved(java.awt.event.HierarchyEvent evt) {
            }
            public void ancestorResized(java.awt.event.HierarchyEvent evt) {
                reelPanel2AncestorResized(evt);
            }
        });

        javax.swing.GroupLayout reelPanel2Layout = new javax.swing.GroupLayout(reelPanel2);
        reelPanel2.setLayout(reelPanel2Layout);
        reelPanel2Layout.setHorizontalGroup(
            reelPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 71, Short.MAX_VALUE)
        );
        reelPanel2Layout.setVerticalGroup(
            reelPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 76, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout reelPanel1Layout = new javax.swing.GroupLayout(reelPanel1);
        reelPanel1.setLayout(reelPanel1Layout);
        reelPanel1Layout.setHorizontalGroup(
            reelPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 66, Short.MAX_VALUE)
        );
        reelPanel1Layout.setVerticalGroup(
            reelPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 76, Short.MAX_VALUE)
        );

        javax.swing.GroupLayout reelPanel3Layout = new javax.swing.GroupLayout(reelPanel3);
        reelPanel3.setLayout(reelPanel3Layout);
        reelPanel3Layout.setHorizontalGroup(
            reelPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 66, Short.MAX_VALUE)
        );
        reelPanel3Layout.setVerticalGroup(
            reelPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 76, Short.MAX_VALUE)
        );

        armPanel.setOpaque(false);
        armPanel.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                armPanelMouseClicked(evt);
            }
        });

        javax.swing.GroupLayout armPanelLayout = new javax.swing.GroupLayout(armPanel);
        armPanel.setLayout(armPanelLayout);
        armPanelLayout.setHorizontalGroup(
            armPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 38, Short.MAX_VALUE)
        );
        armPanelLayout.setVerticalGroup(
            armPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 210, Short.MAX_VALUE)
        );

        creditLabel.setBackground(new java.awt.Color(153, 153, 0));
        creditLabel.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        creditLabel.setText("Welcome");
        creditLabel.setOpaque(true);

        messageLabel.setBackground(new java.awt.Color(153, 153, 0));
        messageLabel.setFont(new java.awt.Font("Tahoma", 1, 18)); // NOI18N
        messageLabel.setText("Welcome");
        messageLabel.setOpaque(true);

        javax.swing.GroupLayout drawPanel1Layout = new javax.swing.GroupLayout(drawPanel1);
        drawPanel1.setLayout(drawPanel1Layout);
        drawPanel1Layout.setHorizontalGroup(
            drawPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(drawPanel1Layout.createSequentialGroup()
                .addGroup(drawPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(drawPanel1Layout.createSequentialGroup()
                        .addGap(260, 260, 260)
                        .addComponent(reelPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(reelPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(reelPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(70, 70, 70)
                        .addComponent(armPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(drawPanel1Layout.createSequentialGroup()
                        .addGap(93, 93, 93)
                        .addComponent(messageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 581, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(68, Short.MAX_VALUE))
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, drawPanel1Layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(creditLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 512, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(112, 112, 112))
        );
        drawPanel1Layout.setVerticalGroup(
            drawPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(drawPanel1Layout.createSequentialGroup()
                .addGroup(drawPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(drawPanel1Layout.createSequentialGroup()
                        .addContainerGap()
                        .addComponent(creditLabel)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGroup(drawPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(reelPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(reelPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(reelPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addGap(203, 203, 203))
                    .addGroup(drawPanel1Layout.createSequentialGroup()
                        .addGap(190, 190, 190)
                        .addComponent(armPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 160, Short.MAX_VALUE)))
                .addComponent(messageLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 34, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(26, 26, 26))
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(drawPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 116, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(drawPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(0, 0, Short.MAX_VALUE))
        );

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

    private void armPanelMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_armPanelMouseClicked
        pullArm();
    }//GEN-LAST:event_armPanelMouseClicked

    private void reelPanel2AncestorResized(java.awt.event.HierarchyEvent evt) {//GEN-FIRST:event_reelPanel2AncestorResized
        //System.out.println(evt.getChanged().getWidth());
    }//GEN-LAST:event_reelPanel2AncestorResized

    /**
     * @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 ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(MainFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new MainFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JPanel armPanel;
    private javax.swing.JLabel creditLabel;
    private interactiveproject.slotmachine.DrawPanel drawPanel1;
    private javax.swing.JLabel messageLabel;
    private interactiveproject.slotmachine.ReelPanel reelPanel1;
    private interactiveproject.slotmachine.ReelPanel reelPanel2;
    private interactiveproject.slotmachine.ReelPanel reelPanel3;
    // End of variables declaration//GEN-END:variables
}
