package com.example.instapic;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.net.Proxy;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.kobjects.base64.Base64;
import org.ksoap2.SoapEnvelope;
import org.ksoap2.serialization.MarshalBase64;
import org.ksoap2.serialization.SoapObject;
import org.ksoap2.serialization.SoapPrimitive;
import org.ksoap2.serialization.SoapSerializationEnvelope;
import org.ksoap2.transport.HttpTransportSE;

import com.example.instapic.CustomImageView;
import com.example.instapic.MainActivity;
import com.example.instapic.R;

import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.Toast;

public class MainActivity extends Activity {
	static int effectNumber = 0;
	static String IPaddress = "172.16.2.201";
	private static final String NAMESPACE = "http://imageProcess.org/";
	private static String URL="http://"+IPaddress+":4848/ImageProcess/imgProcessService?wsdl";
	private static final String METHOD_NAME = "getImage";
	private static final String SOAP_ACTION =  "http://imageProcess.org/getImage";
	public byte[] byteToSend = null;
	private class SendImage extends AsyncTask<Integer, Void, byte[]> {
		ProgressDialog progress = new ProgressDialog(MainActivity.this);
		@Override
		protected byte[] doInBackground(Integer... params) {
			SoapObject request = new SoapObject(NAMESPACE, METHOD_NAME);
			request.addProperty("arg0",byteToSend);
			request.addProperty("arg1", params[0]);
			SoapSerializationEnvelope soapEnvelope = new SoapSerializationEnvelope(SoapEnvelope.VER11);
	        soapEnvelope.dotNet = false;
	        soapEnvelope.setOutputSoapObject(request);
	        new MarshalBase64().register(soapEnvelope);
			HttpTransportSE androidHttpTransport = new HttpTransportSE(Proxy.NO_PROXY, URL, 20000);
            try {
            	androidHttpTransport.call(SOAP_ACTION,soapEnvelope);
            	System.out.println("transported");
                SoapPrimitive response= (SoapPrimitive) soapEnvelope.getResponse();
                String str = response.toString();
                byte arr[]=Base64.decode(str);
                return arr;
            
            }catch (Exception e) {
            	showMessage("Check IP settings");
            	showIPdialog();
            	e.printStackTrace();
            	return null;
            }
		}
		
		@Override
		protected void onPostExecute(byte[] array){
			if (array!=null)
			{	
				ImageView croppedImg = (ImageView)findViewById(R.id.mainIMG);
				Bitmap bmp = BitmapFactory.decodeByteArray(array, 0, array.length);
				croppedImg.setImageBitmap(bmp);
			}
			this.progress.dismiss();
		}
		
		@Override
		protected void onPreExecute(){
			super.onPreExecute();
			this.progress.setMessage("Please Wait...");
			this.progress.show();
		}
	}
	
	@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        showIPdialog();
        
        ImageButton camera = (ImageButton)findViewById(R.id.camera);
        camera.setOnClickListener(openCamera);
        
        ImageButton gallery = (ImageButton)findViewById(R.id.gallery);
        gallery.setOnClickListener(openGallery);
        
        Button done = (Button)findViewById(R.id.done);
        done.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				CustomImageView display = (CustomImageView)findViewById(R.id.mainIMG);
				Bitmap croppedBM = display.getImage();
				ByteArrayOutputStream stream = new ByteArrayOutputStream();
				croppedBM.compress(Bitmap.CompressFormat.PNG, 100, stream);
				byteToSend = stream.toByteArray();
				System.out.println(URL);
				
				if(effectNumber>0)
					new SendImage().execute(effectNumber);
				else if(effectNumber==0)
					display.setImageBitmap(croppedBM);
				else{
					showMessage("Please provide valid option");
				}
					
			}
		});
    }
	
	private void showIPdialog(){
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.IPsettings);
        final EditText inputIP = new EditText(this);
        inputIP.setText(IPaddress);
        LinearLayout temp = new LinearLayout(this);
        temp.addView(inputIP);
        builder.setView(temp);
        
        builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				IPaddress = inputIP.getText().toString();
				URL = "http://"+IPaddress+":4848/ImageProcess/imgProcessService?wsdl";
				showMessage("IP settings saved");
			}
		})
        .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                // User cancelled the dialog
            }
        });
        AlertDialog dialog = builder.create();
        
        dialog.show();
	}
	
    private void showMessage(CharSequence text){
    	Context context = getApplicationContext();
    	Toast.makeText(context, text, Toast.LENGTH_SHORT).show();
    }
    
    /** Create a file Uri for saving an image or video */
    private static Uri getOutputMediaFileUri(){
        // To be safe, you should check that the SDCard is mounted
        // using Environment.getExternalStorageState() before doing this.
        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
                  Environment.DIRECTORY_PICTURES), "InstaPic");

        // Create the storage directory if it does not exist
        if (! mediaStorageDir.exists()){
            if (! mediaStorageDir.mkdirs()){
                Log.d("InstaPic", "failed to create directory");
                return null;
            }
        }
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File mediaFile = new File(mediaStorageDir.getPath() + File.separator +"IMG_.jpg"+timeStamp);

        return Uri.fromFile(mediaFile);
    }

    private Uri fileUri;
    private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
    private static final int SELECT_IMAGE_REQUEST_CODE = 200;
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    	String picturePath="";
        switch(requestCode){
        	case CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE:
        		if (resultCode == RESULT_OK) {
        			picturePath = fileUri.getPath();
        		}
        		break;
        		
        	case SELECT_IMAGE_REQUEST_CODE:
        		if (resultCode == RESULT_OK && data!=null){
        			fileUri = data.getData();
        			String[] filePathColumn = { MediaStore.Images.Media.DATA};
        			
        			Cursor cursor = getContentResolver().query(fileUri,filePathColumn, null, null, null);
        			cursor.moveToFirst();
        			
        			int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
        			picturePath = cursor.getString(columnIndex);
        			cursor.close();
        		}
        		break;
        }
        CustomImageView display = (CustomImageView)findViewById(R.id.mainIMG);
        if (picturePath!="")
        	display.setImageBitmap(BitmapFactory.decodeFile(picturePath));
    }

    private OnClickListener openCamera = new OnClickListener() {
    	public void onClick(View v) {
    		Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    		fileUri = getOutputMediaFileUri(); // create a file to save the image
    	    intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name

    	    startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
		}
	};
    	
    private OnClickListener openGallery = new OnClickListener() {
		public void onClick(View v) {
			Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);					
			startActivityForResult(intent, SELECT_IMAGE_REQUEST_CODE);
		}
    };
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu){
    	getMenuInflater().inflate(R.menu.main, menu);
    	return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle presses on the action bar items
    	Button done = (Button)findViewById(R.id.done);
        switch (item.getItemId()) {
            case R.id.settings:
            	showIPdialog();
                return true;
            
            case R.id.none:
            	effectNumber = 0;
            	done.setText("No Effect");
            	return true;
            	
            case R.id.blur:
            	effectNumber = 1;
            	done.setText("Blur");
            	return true;
            	
            case R.id.grayscale:
            	effectNumber = 2;
            	done.setText("Grayscale");
            	return true;
            	
            case R.id.edgeDetection:
            	effectNumber=3;
            	done.setText("Edge Detection");
            	return true;
            	
            case R.id.negative:
            	effectNumber=4;
            	done.setText("Negative");
            	return true;
            	
            case R.id.sepia:
            	effectNumber=5;
            	done.setText("Sepia");
            	return true;
            
            case R.id.noise:
            	effectNumber=6;
            	done.setText("Noise");
            	return true;
            	
            default:
                return super.onOptionsItemSelected(item);
        }
    }
}
