//LNXTSU003
//Tsu-Shiuan Lin
//This is my honours project main class where everything starts!
//Going to implement both bluetooth and wireless file transfer for Android
//Be sure to enable permissions in the ManiFest file

package com.example.wireless;

//Lots of things to import!
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;
import java.util.UUID;

import android.widget.*;

import android.net.Uri;
import android.net.wifi.*;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.bluetooth.*;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import android.view.Menu;
import android.view.View;

public class Transfer extends Activity {
private Button button;
private WifiManager wifi;
private BluetoothServerSocket mmServerSocket;
private BluetoothSocket mmSocket;
private BluetoothDevice mmDevice;
private InputStream mmInStream;
private OutputStream mmOutStream;
//private BatteryManager battery = new BatteryManager();
boolean flag1 = true;
boolean f = true;
String result = "";

    @Override
    public void onCreate(Bundle savedInstanceState) {
    	//This is where everything starts! Implement everything here
        super.onCreate(savedInstanceState);
        setContentView(R.layout.frontend);
        //Log.d("TRANSFER", String.valueOf(getBatteryLife()));
        makeDiscover();//Makes the devices discoverable	
        message();	
        wirelessButton();//Calls the wireless function
        bluetoothButton();// Calls the bluetooth function
        server();
        client();
        send();
    }//This is where everything starts
    
    
    public void server()
    {
    	button = (Button)findViewById(R.id.server1);//Links the button to this method
		button.setOnClickListener(new View.OnClickListener() {
			public void onClick(View arg0) {
				//Log.d("TRANSFER", String.valueOf(getBatteryLife()));
				Log.d("TRANSFER", "Server clicked");
				if (f)
				{
				Thread t = new Thread(new AcceptThread("a60f35f0-b93a-11de-8a39-08002009c666"));
				t.start();
				Log.d("TRANSFER", "Started thread: a60f35...");
				f= false;
				}
				else
				{
					Thread t = new Thread(new AcceptThread("00001101-0000-1000-8000-00805F9B34FB"));
					t.start();
					Log.d("TRANSFER", "Started thread: 00001101...");
				}
			}
		});
    }
    public void send()
    {
    	button = (Button)findViewById(R.id.send);//Links the button to this method
		button.setOnClickListener(new View.OnClickListener() {
			public void onClick(View arg0) {
				Log.d("TRANSFER", "Sending Data");
				
			}
		});
    }
	public void client()
	{
		button = (Button)findViewById(R.id.client1);//Links the button to this method
		button.setOnClickListener(new View.OnClickListener() {
			public void onClick(View arg0) {
				Log.d("TRANSFER", "Client clicked");
				Thread client = new Thread(new ConnectThread());
				client.start();
			}
		});
	}
    public void wirelessButton()
    {
    	button = (Button)findViewById(R.id.wButton);//Links the button to this method
		button.setOnClickListener(new View.OnClickListener() {
			 String address = "78:47:1D:A5:CD:89";//Other device MAC address given by device discover
			
			public void onClick(View arg0) {/*Log.d("TRANSFER", "Button clicked");
				BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
				Set<BluetoothDevice> pairedDevices = adapter.getBondedDevices();
				// If there are paired devices
				if (pairedDevices.size() > 0) {
				    // Loop through paired devices
				    for (BluetoothDevice device : pairedDevices) {
				        // Add the name and address to an array adapter to show in a ListView
				    	Log.d("TRANSFER", device.getAddress());
				    }
				}
		    	BluetoothDevice b = adapter.getRemoteDevice(address);
		    	Log.d("TRANSFER", "Button clicked2");
		    	BluetoothSocket tmp = null;
		        mmDevice = b;
		        Log.d("TRANSFER", "Assigned");
		        try {
		            // MY_UUID is the app's UUID string, also used by the server code
		        	UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
		            //tmp = mmDevice.createRfcommSocketToServiceRecord(uuid);
		            Method m = mmDevice.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
		            tmp = (BluetoothSocket) m.invoke(mmDevice, 1);
		        } catch (Exception e) { Log.d("TRANSFER", "Baaaaaaaad");}
		        Log.d("TRANSFER", "EVerything good");
		        mmSocket = tmp;
		        try {
		            // Connect the device through the socket. This will block
		            // until it succeeds or throws an exception
		        	
		            mmSocket.connect();
		            Log.d("TRANSFER", "EVerything good still");
		            InputStream tmpIn = null;
		            OutputStream tmpOut = null;
		            try {
		                tmpIn = mmSocket.getInputStream();
		                tmpOut = mmSocket.getOutputStream();
		            } catch (IOException e) { Log.d("TRANSFER", "ERROR"+e.toString());}
		     
		            mmInStream = tmpIn;
		            mmOutStream = tmpOut;
		            write(mmSocket,"He");
		            Log.d("TRANSFER", "EVerything still???");
		        } catch (IOException connectException) {Log.d("TRANSFER", "ERROR1");
		            // Unable to connect; close the socket and get out
		            try {
		                mmSocket.close();
		            } catch (IOException closeException) {Log.d("TRANSFER", "ERROR2"); }
		            return;
		        }Log.d("TRANSFER", "Nothing better");
				/*
				wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
				if (!wifi.isWifiEnabled())
					wifi.setWifiEnabled(true);
				WifiInfo info = wifi.getConnectionInfo();
				List<WifiConfiguration> configs = wifi.getConfiguredNetworks();
				//This will attempt to do something with the WiFiManager
				EditText editText = (EditText)findViewById(R.id.text);
		    	editText.setText(configs.toString(), TextView.BufferType.EDITABLE);
 */
				
			}
 
		});
    }//This method listens for the button for wireless and does something when pressed
    
    public void bluetoothButton()
    {
    	//This will attempt to do something with bluetooth
    	button = (Button)findViewById(R.id.bButton);
		button.setOnClickListener(new View.OnClickListener() {
			 
			public void onClick(View arg0) {
				
				
				bLife();
				
				/*
				//Starting fresh!
				//AcceptThread server = new AcceptThread();
				BluetoothServerSocket tmp = null;
				//a60f35f0-b93a-11de-8a39-08002009c666
				
				try {
		        	BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
		        	//Set<BluetoothDevice> devices = adapter.getBondedDevices();
		        	UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");//Generating a random UUID
		        	//This UUID must be in HEX
		            tmp = adapter.listenUsingRfcommWithServiceRecord("DeviceTest", uuid);

		        } catch (Exception e) {Log.d("TRANSFER", e.toString()); }
		        
		        mmServerSocket = tmp;
				Runnable server = new Runnable()
	                     {
					public void run()//What is run in the thread
                    {
						
						BluetoothSocket socket = null;
						boolean flag = true;
						while (flag) {
				            try {
				            	Log.d("TRANSFER", "Waiting for connection");
				                socket = mmServerSocket.accept();
				                Log.d("TRANSFER", "Accepted connection");
				            } catch (IOException e) {
				            	Log.d("TRANSFER", e.getMessage());
				                break;
				            }
				            if (socket != null) {
				                // Do work to manage the connection (in a separate thread)
				            	Log.d("TRANSFER", "Managing stuff.....");
				            	String address = "50:01:BB:3D:AC:D1";
				            	
				            	BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
				            	BluetoothDevice b = adapter.getRemoteDevice(address);
						    	BluetoothSocket tmp = null;
						        mmDevice = b;
						        try {
						            // MY_UUID is the app's UUID string, also used by the server code
						        	UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
						            tmp = mmDevice.createRfcommSocketToServiceRecord(uuid);
						        	//Method m = mmDevice.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
						            //tmp = (BluetoothSocket) m.invoke(mmDevice, 1);
						        } catch (Exception e) { Log.d("TRANSFER", "Baaaaaaaad");}
						        Log.d("TRANSFER", "EVerything good");
						        mmSocket = tmp;
				            	InputStream tmpIn = null;
					            OutputStream tmpOut = null;
					            try {
					                tmpIn = mmSocket.getInputStream();
					                tmpOut = mmSocket.getOutputStream();
					            } catch (IOException e) { }
					            
					            mmInStream = tmpIn;
					            mmOutStream = tmpOut; 
					            //flag1 = false;
					            //Now we have the sockets and streams working fine...
					           
				                //manageConnectedSocket(socket);
				                try {
				                	//while(!flag1)
				                	//{
				                	
				                	//}
				                	Log.d("TRANSFER", "Kicks!");
				                	mmServerSocket.close();Log.d("TRANSFER", "Closing socket.....");}
				                catch (IOException e){}
				                break;
				            }
				        }
						Log.d("TRANSFER", "Out of the while loop.....");
						flag1 = false;
						 
						
                    }
                    };
	                 
                    Thread t = new Thread(server);
                    t.start();
                    Runnable r = new Runnable()
                    {
				public void run()//What is run in the thread 
               {
					while (flag1){
					
					}
					int bufferSize = 1024;
					byte[] buffer = new byte[bufferSize];
					/*try {
						Log.d("TRANSFER", "Just before reading...");
						InputStream instream = mmSocket.getInputStream();
						int bytesRead = -1;
						
		            	while (true)
		            	{
		            		Log.d("TRANSFER", "Hello1");
		            	bytesRead = instream.read(buffer);
		            	//instream.read(buffer, bytesRead, buffersize-bytesRead);
		            	Log.d("TRANSFER", "Hello2");
		            	if (bytesRead!=-1)
		            	{
		            		while ((bytesRead== bufferSize) && (buffer[bufferSize-1]!=0))
		            		{
		            			result = result + new String(buffer,0,bytesRead);
		            			bytesRead = instream.read(buffer);
		            		}
		            		result = result + new String(buffer,0,bytesRead);
		            		break;
		            	}
		            	}
		            	Log.d("TRANSFER", "READING");
		            	Log.d("TRANSFER", result);
		                flag1 = true;
		            } catch (IOException e) {Log.d("TRANSFER", "ERROR"+e.toString()); */
			
                    };
                    //Thread read = new Thread(r);
                    //read.start();
                    //read();
                    
               
				//server.cancel();
				
				/*
				BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
				if (!adapter.isEnabled()) {
				    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
				    startActivityForResult(enableBtIntent, 1);
				}
				adapter.startDiscovery();
				Set<BluetoothDevice> devices = adapter.getBondedDevices();	
				String text = "";
				for (BluetoothDevice device : devices) {
				      text = text+"\nFound device: " + device;
				}
				BluetoothSocket mBluetoothSocket = null;
				OutputStream outStream;
				try {
			        outStream = mBluetoothSocket.getOutputStream();
			        text = text+"/n connection?";
			    } catch (IOException e) {
			    	text = text+"/n no connection?";
			    }
			    I am facing a problem in sending large files over bluetooth sockets. Smaller files get transferred correctly. I believe upto 161280 bytes get transferred correctly.

				EDIT: I did some more testing and narrowed down the cause. It seems that

				outStream.write(mybytearray, 0, mybytearray.length);		
				
				EditText editText = (EditText)findViewById(R.id.text);
		    	editText.setText(text, TextView.BufferType.EDITABLE);
 */
			//}
 
		});
    }//This method listens for the button for bluetooth and does something when pressed

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.frontend, menu);
        return true;
    }
    public void message()
    {
    	Context context = getApplicationContext();
    	CharSequence text = "Hello toast!";
    	int duration = Toast.LENGTH_SHORT;

    	Toast toast = Toast.makeText(context, text, duration);
    	toast.show();
    }//Displays hello toast for debugging purposes
    public Context getContext()
    {
    	return getApplicationContext();
    }
    public void makeDiscover()
    {
    	Intent discoverableIntent = new
    			Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
    			discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
    			startActivity(discoverableIntent);
    }
    public void write(BluetoothSocket socket, String msg) {
        try {
        	OutputStream outstream;
        	try {outstream = socket.getOutputStream();
        	Log.d("TRANSFER", "Just before writing...");
        	byte[] byteString = (msg+" ").getBytes();
        	byteString[byteString.length-1]= 0;
            outstream.write(byteString);
            Log.d("TRANSFER", "Just after writing...");
            }
        	catch (Exception e){Log.d("TRANSFER", "ERROR"+e.toString());}
        	
        } catch (Exception e) {Log.d("TRANSFER", "ERROR"+e.toString()); }
    }
    public void read() {
    	try {
			InputStream instream = mmSocket.getInputStream();
			int bytesRead = -1;
			
			int bufferSize = 1024;
			byte[] buffer = new byte[bufferSize];
        	Log.d("TRANSFER", "Just before reading...");
        	while (true)
        	{
        	bytesRead = instream.read(buffer);
        	Log.d("TRANSFER", "Gets past first read");
        	if (bytesRead!=-1)
        	{
        		while ((bytesRead== bufferSize) && (buffer[bufferSize-1]!=0))
        		{
        			result = result + new String(buffer,0,bytesRead);
        			bytesRead = instream.read(buffer);
        		}
        		result = result + new String(buffer,0,bytesRead);
        		break;
        	}
        	}
        	Log.d("TRANSFER", "READING");
        	Log.d("TRANSFER", result);
            flag1 = true;
        } catch (IOException e) {Log.d("TRANSFER", "ERROR"+e.toString()); }
   
    }
    public double getBatteryLife()
	{
		IntentFilter ifilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        Intent batteryStatus = MyApplication.getAppContext().registerReceiver(null, ifilter);
        int level = batteryStatus.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
        int scale = batteryStatus.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
        double bat = level/ (float)scale;
        Log.d("TRANSFER", "Battery level:"+bat);
        return bat;
	
	}
    public void bLife() {
        BroadcastReceiver batteryReceiver = new BroadcastReceiver() {
            double scale = -1;
             double level = -1;
            double voltage = -1;
            double temp = -1;
            @Override
            public void onReceive(Context context, Intent intent) {
                level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
                scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE, 100);
                //temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, -1);
                //voltage = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, -1);
                double k = (float) level/ scale;
                Log.d("TRANSFER", "level is "+k+", temp is "+temp+", voltage is "+voltage);
                EditText editText = (EditText)findViewById(R.id.text);
		    	editText.setText(String.valueOf(k), TextView.BufferType.EDITABLE);
            }
        };
        IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        registerReceiver(batteryReceiver, filter);
    }
}
