/********************************************************
* Speaker Verification Implemented Security             *
* CA4 Project                                           *
* Written by: Ronan Crowley (97084603)                  *
*        and  Paul Connolly (97307599)                  *
********************************************************/

import Audio.*;
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Record extends JDialog {
    private Container c;
    private GridLayout grid;
    private String contents;
    private Audio.SoundBite s = null;
    private int numseconds = 10;
    ObjectInputStream input;
    ObjectOutputStream output;
    String IPAddress;
    String username;
    Icon sv = new ImageIcon("sv.gif");

    /** Constructor
        @param stream ObjectInputStream which is already established between Client and Server
        @param whatToSay The randomly generated text for what to say
        @param parent The calling Frame
    **/
    public Record(ObjectInputStream istream, ObjectOutputStream ostream, String whatToSay, Frame parent, String IP, String un) {
     super(parent);
     
     //Assign passed-in variables to private
     contents = whatToSay;
     username =un;
     input = istream;
     output = ostream;
     IPAddress = IP;
     try {
      init();
     }
     catch(Exception e) {
      e.printStackTrace();
     }
     pack();
    }
     
   /** Component initialization **/
   private void init() throws Exception
   {
      this.setTitle("Say this......");

      grid = new GridLayout( 1, 2 );

      c = getContentPane();
      c.setLayout( grid );

      //Setup GUI
      JTextArea jTextArea1 = new JTextArea();
      JButton record = new JButton();
      jTextArea1.setText("\n\n"+contents+"\n\n");
      jTextArea1.setEditable(false);
      jTextArea1.setBackground(Color.white);
      jTextArea1.setToolTipText("Press record and say this !");
      record.setText("RECORD");
      record.setMnemonic('r');
      c.add(jTextArea1);
      c.add(record);
      record.addActionListener(new ActionListener()  {
            public void actionPerformed(ActionEvent e) {
                record_actionPerformed(e);
            }
      });

      // Setup recording at 22050 kHz
      s = new Audio.SoundBite(false, false, Audio.SampleRate.R_22050, numseconds * Audio.SampleRate.R_22050 .toInt());

      setSize( 300, 200 );
      show();
   }

   /** Record the sample, send to server and test ! **/
   public void record_actionPerformed(ActionEvent e) {
         try {
            System.out.println("\tStarting recording");

            {
                s.recordStart();
                // s.recordWaitFor();
                // or

                int i=10;
                String time = "\t"+i+" Seconds";
                long finishTime = System.currentTimeMillis()+1000;
                while (i>0) {
                    if (System.currentTimeMillis() >= finishTime) {
                        finishTime += 1000;
                        time = "\t"+i+" Seconds";
                        i--;
                        System.out.println(time);
                    }
                }

                s.recordWaitForGet();
            }

            System.out.println("\tRecording done");

            s.save("speech.wav");
            s.dispose();
        } catch (Audio.SoundBiteException aud) {
            aud.printStackTrace();
            System.err.println("Audio Exception: " + aud.getMessage());
        }

        //Once recorded, send file.
        Sendfile transmit = new Sendfile();
        transmit.send(IPAddress, "speech.wav");

        dispose();
        
        //Finished sending WAV now recieve result !
        try{
            String message=(String) input.readObject();
        
            int i=0;
            while (message.charAt(i) != '.'){
                i++;
            }
            int compare = Integer.parseInt(message.substring(0, i));
            
            //Receive individual Threshold from Server
            String threshold = (String) input.readObject();
            i=0;
            while (threshold.charAt(i) != '.'){
                i++;
            }
            int compare1 = Integer.parseInt(threshold.substring(0, i));

            System.out.println("Sum of log liklihoods: "+compare);
            System.out.println("Individual Threshold:  "+compare1);

            //Test !
            //10000 and above indicates all silence (i.e. Broken Microphone)
            if ((compare >= compare1) && (compare < 10000)) {
                JOptionPane.showMessageDialog(this, 
                    "You have successfuly logged in to the System.\n\nYour x: has been mapped to a secure area.", 
                    "Successful Logon", 1, sv);
                try
                {   
                    //Map hidden and secure drive
                    Runtime.getRuntime().exec("net use x: \\\\l114-129\\secure sv /User:sv");
                    
                    /** Will not appear to work in demo, as with Ronan and Paul are admin's on both PC's,
                        thus attempts to run this would result in:
                    
                        "ERROR 1219: The credentials supplied conflict with an existing set of credentials."
                    **/
                }
                catch(IOException ioe)
                {
                    System.err.println("Error : " + ioe.toString());
                }

            }
            else {
                JOptionPane.showMessageDialog(this, 
                    "Your voice was not within an acceptable threshold.\n\nAccess denied.", 
                    "Unsuccessful Logon", 1, sv);
            }

        }
        catch (ClassNotFoundException cnfex){
            System.out.println("Unknown object type received");
        }
        catch (EOFException eof) {
            System.out.println("Server terminated connection");
        }
        catch ( IOException io)
        {
          io.printStackTrace();
        }
        catch ( NumberFormatException n) {
            System.out.println(n);
        }
  }

}