package com.camera.simplemjpeg;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.URI;
import java.net.UnknownHostException;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.content.Intent;
import android.content.SharedPreferences;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

public class MjpegActivity extends Activity {
	private static final boolean DEBUG=false;
    private static final String TAG = "MJPEG";

    private MjpegView mv = null;
    String URL;
    
    // for settings (network and resolution)
    private static final int REQUEST_SETTINGS = 0;
    
    private int width = 640;
    private int height = 480;
    
    private int ip_ad1 = 192;
    private int ip_ad2 = 168;
    private int ip_ad3 = 2;
    private int ip_ad4 = 1;
    private int ip_port = 80;
    private String ip_command = "?action=stream";
    
    private boolean suspending = false;
 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        SharedPreferences preferences = getSharedPreferences("SAVED_VALUES", MODE_PRIVATE);
        width = preferences.getInt("width", width);
        height = preferences.getInt("height", height);
        ip_ad1 = preferences.getInt("ip_ad1", ip_ad1);
        ip_ad2 = preferences.getInt("ip_ad2", ip_ad2);
        ip_ad3 = preferences.getInt("ip_ad3", ip_ad3);
        ip_ad4 = preferences.getInt("ip_ad4", ip_ad4);
        ip_port = preferences.getInt("ip_port", ip_port);
        ip_command = preferences.getString("ip_command", ip_command);
                
        StringBuilder sb = new StringBuilder();
        String s_http = "http://";
        String s_dot = ".";
        String s_colon = ":";
        String s_slash = "/";
        sb.append(s_http);
        sb.append(ip_ad1);
        sb.append(s_dot);
        sb.append(ip_ad2);
        sb.append(s_dot);
        sb.append(ip_ad3);
        sb.append(s_dot);
        sb.append(ip_ad4);
        sb.append(s_colon);
        sb.append(ip_port);
        sb.append(s_slash);
        sb.append(ip_command);
        URL = new String(sb);

        setContentView(R.layout.main);
        mv = (MjpegView) findViewById(R.id.mv);  
        if(mv != null){
        	mv.setResolution(width, height);
        }
        new DoRead().execute(URL);
    }

    
    public void onResume() {
    	if(DEBUG) Log.d(TAG,"onResume()");
        super.onResume();
        if(mv!=null){
        	if(suspending){
        		new DoRead().execute(URL);
        		suspending = false;
        	}
        }

    }

    public void onStart() {
    	if(DEBUG) Log.d(TAG,"onStart()");
        super.onStart();
        communication_start start_obj = new communication_start("82.234.53.234", 8080);
        start_obj.execute();

    }
    public void onPause() {
    	if(DEBUG) Log.d(TAG,"onPause()");
        super.onPause();
        if(mv!=null){
        	if(mv.isStreaming()){
		        mv.stopPlayback();
		        suspending = true;
        	}
        }
    }
    public void onStop() {
    	if(DEBUG) Log.d(TAG,"onStop()");
        super.onStop();
		   communication_stop stop_obj = new communication_stop("82.234.53.234", 8080);
		   stop_obj.execute();

    }

    public void onDestroy() {
    	if(DEBUG) Log.d(TAG,"onDestroy()");
    	
    	if(mv!=null){
    		mv.freeCameraMemory();
    	}
    	
        super.onDestroy();
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	MenuInflater inflater = getMenuInflater();
    	inflater.inflate(R.layout.option_menu, menu);
    	return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	switch (item.getItemId()) {
    		case R.id.settings:
    			Intent settings_intent = new Intent(MjpegActivity.this, SettingsActivity.class);
    			settings_intent.putExtra("width", width);
    			settings_intent.putExtra("height", height);
    			settings_intent.putExtra("ip_ad1", ip_ad1);
    			settings_intent.putExtra("ip_ad2", ip_ad2);
    			settings_intent.putExtra("ip_ad3", ip_ad3);
    			settings_intent.putExtra("ip_ad4", ip_ad4);
    			settings_intent.putExtra("ip_port", ip_port);
    			settings_intent.putExtra("ip_command", ip_command);
    			startActivityForResult(settings_intent, REQUEST_SETTINGS);
    			return true;
    	}
    	return false;
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
    	switch (requestCode) {
    		case REQUEST_SETTINGS:
    			if (resultCode == Activity.RESULT_OK) {
    				width = data.getIntExtra("width", width);
    				height = data.getIntExtra("height", height);
    				ip_ad1 = data.getIntExtra("ip_ad1", ip_ad1);
    				ip_ad2 = data.getIntExtra("ip_ad2", ip_ad2);
    				ip_ad3 = data.getIntExtra("ip_ad3", ip_ad3);
    				ip_ad4 = data.getIntExtra("ip_ad4", ip_ad4);
    				ip_port = data.getIntExtra("ip_port", ip_port);
    				ip_command = data.getStringExtra("ip_command");

    				if(mv!=null){
    					mv.setResolution(width, height);
    				}
    				SharedPreferences preferences = getSharedPreferences("SAVED_VALUES", MODE_PRIVATE);
    				SharedPreferences.Editor editor = preferences.edit();
    				editor.putInt("width", width);
    				editor.putInt("height", height);
    				editor.putInt("ip_ad1", ip_ad1);
    				editor.putInt("ip_ad2", ip_ad2);
    				editor.putInt("ip_ad3", ip_ad3);
    				editor.putInt("ip_ad4", ip_ad4);
    				editor.putInt("ip_port", ip_port);
    				editor.putString("ip_command", ip_command);

    				editor.commit();

    				new RestartApp().execute();
    			}
    			break;
    	}
    }

    
    public class DoRead extends AsyncTask<String, Void, MjpegInputStream> {
        protected MjpegInputStream doInBackground(String... url) {
            //TODO: if camera has authentication deal with it and don't just not work
            HttpResponse res = null;
            DefaultHttpClient httpclient = new DefaultHttpClient(); 
            HttpParams httpParams = httpclient.getParams();
            HttpConnectionParams.setConnectionTimeout(httpParams, 5*1000);
            Log.d(TAG, "1. Sending http request");
            try {
                res = httpclient.execute(new HttpGet(URI.create(url[0])));
                Log.d(TAG, "2. Request finished, status = " + res.getStatusLine().getStatusCode());
                if(res.getStatusLine().getStatusCode()==401){
                    //You must turn off camera User Access Control before this will work
                    return null;
                }
                return new MjpegInputStream(res.getEntity().getContent());  
            } catch (ClientProtocolException e) {
                e.printStackTrace();
                Log.d(TAG, "Request failed-ClientProtocolException", e);
                //Error connecting to camera
            } catch (IOException e) {
                e.printStackTrace();
                Log.d(TAG, "Request failed-IOException", e);
                //Error connecting to camera
            }
            return null;
        }

        protected void onPostExecute(MjpegInputStream result) {
            mv.setSource(result);
            if(result!=null) result.setSkip(1);
            mv.setDisplayMode(MjpegView.SIZE_BEST_FIT);
            mv.showFps(false);
        }
    }
    
    public class RestartApp extends AsyncTask<Void, Void, Void> {
        protected Void doInBackground(Void... v) {
			MjpegActivity.this.finish();
            return null;
        }

        protected void onPostExecute(Void v) {
        	startActivity((new Intent(MjpegActivity.this, MjpegActivity.class)));
        }
    }
    
    
    
    /************************************************/
    
	public class communication_start extends AsyncTask<Void, Void, Void> 
	{
		  
		  String dstAddress;
		  int dstPort;
		  String response = "";
		  
		  communication_start(String addr, int port)
		  {
			  dstAddress = addr;
			  dstPort = port;
		  }

		  @Override
		  protected Void doInBackground(Void... arg0)
		  {
		   
			  		Socket socket = null;
		   
			  		try {
			  				socket = new Socket(dstAddress, dstPort);
		    
			  				// envoi un message au serveur
			  				BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			  				PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
			  				pw.println("cmd_flux_start");
			
			  			
		                     if (socket != null) socket.close();
			  				
			 
			  		} 
			  		
			  		catch (UnknownHostException e)
			  		{
			  			// TODO Auto-generated catch block
			  			e.printStackTrace();
			  			response = "UnknownHostException: " + e.toString();
			  		} 
			  		
			  		catch (IOException e)
			  		{
			  			// TODO Auto-generated catch block
			  			e.printStackTrace();
			  			response = "IOException: " + e.toString();
			  		}
			  		
			  		finally
			  		{
			  			
			  			if(socket != null)
			  			{
			  				try {
			  						socket.close();
			  				} 
			  				
			  				catch (IOException e) 
			  				{
			  					// TODO Auto-generated catch block
			  					e.printStackTrace();
			  				}
			  			}
			  		}
			  		
			  		return null;
		  }

		  @Override
		  protected void onPostExecute(Void result) 
		  {
			    
			  	super.onPostExecute(result);
		  }
		  
	}		
	
	
	public class communication_stop extends AsyncTask<Void, Void, Void> 
	{
		  
		  String dstAddress;
		  int dstPort;
		  String response = "";
		  
		  communication_stop(String addr, int port)
		  {
			  dstAddress = addr;
			  dstPort = port;
		  }

		  @Override
		  protected Void doInBackground(Void... arg0)
		  {
		   
			  		Socket patoche = null;
		   
			  		try {
			  				patoche = new Socket(dstAddress, dstPort);
		    
			  				// envoi un message au serveur
			  				BufferedReader br = new BufferedReader(new InputStreamReader(patoche.getInputStream()));
			  				PrintWriter pw = new PrintWriter(patoche.getOutputStream(), true);
			  				pw.println("cmd_flux_stop");
			
			  			
		                     if (patoche != null) patoche.close();
			  				
			 
			  		} 
			  		
			  		catch (UnknownHostException e)
			  		{
			  			// TODO Auto-generated catch block
			  			e.printStackTrace();
			  			response = "UnknownHostException: " + e.toString();
			  		} 
			  		
			  		catch (IOException e)
			  		{
			  			// TODO Auto-generated catch block
			  			e.printStackTrace();
			  			response = "IOException: " + e.toString();
			  		}
			  		
			  		finally
			  		{
			  			
			  			if(patoche != null)
			  			{
			  				try {
			  						patoche.close();
			  				} 
			  				
			  				catch (IOException e) 
			  				{
			  					// TODO Auto-generated catch block
			  					e.printStackTrace();
			  				}
			  			}
			  		}
			  		
			  		return null;
		  }

		  @Override
		  protected void onPostExecute(Void result) 
		  {
			  	super.onPostExecute(result);
		  }
		  
	}		

    
}
