package edu.centenary.stego;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;

public class StegoActivity extends Activity {
	
	private ImageView mainImage;
	private EditText stegoMessage;
	private Button encodeButton;
	private Button decodeButton;
	private Button shareButton;
	private Bitmap bMap;
	private final int choiceRes = R.drawable.dirigible;
	private final String filename = "stego.png";
    private ProgressDialog pd;


    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        initializeImages();
        
        mainImage = (ImageView) findViewById(R.id.mainImage);
        stegoMessage = (EditText) findViewById(R.id.stegoMessage);
        
        encodeButton = (Button) findViewById(R.id.encode);
        encodeButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				new EncodeTask().execute("" + stegoMessage.getText());			
			}
        	
        });
        
        decodeButton = (Button) findViewById(R.id.decode);
        decodeButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				new DecodeTask().execute();			
			}
        	
        });
        
        shareButton = (Button) findViewById(R.id.share);
        shareButton.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				startShareMediaActivity();		
			}
        	
        });
        
        Intent intent = getIntent();
        String action = intent.getAction();

        // if this is from the view menu
        if (Intent.ACTION_VIEW.equals(action)) {
        	Uri uri = intent.getData();
                 try {
                    // Get resource path from intent callee
                    ContentResolver cr = getContentResolver();
                    InputStream is = cr.openInputStream(uri);
                    bMap = BitmapFactory.decodeStream(is);
                    saveToFile();
                } catch (IOException ioe) {
                	ioe.printStackTrace();
                }
        } else {
        	updateBMap();
        }
        
        updateViews();
    }
    
    /**
     * If this is the first time running ever, create the image file in the 
     * context of this program, since we cannot write to resource files.
     */
    private void initializeImages() {
    	Log.d("Stego", "length = " + fileList().length);
        if (fileList().length == 0) {
        	Log.d("Stego", "writing out files");
    		try {
        		FileOutputStream fos = openFileOutput(filename, Context.MODE_WORLD_READABLE);
        		Bitmap tMap = BitmapFactory.decodeResource(getResources(), choiceRes);
    			tMap.compress(Bitmap.CompressFormat.PNG, 100, fos);
    			fos.close();
    		} catch (IOException ioe) {
    			Log.d("Stego", ioe.toString());
    		}
        }
    }
    
    /**
     * Update the Bitmap based on the image in filename
     */
    private void updateBMap() {
		try {
			FileInputStream fis = openFileInput(filename);
			BufferedInputStream buf = new BufferedInputStream(fis);
	        bMap = BitmapFactory.decodeStream(buf);
	        fis.close();
	        buf.close();
		} catch (IOException ioe) {
			Log.d("Stego", ioe.toString());
		}
    }
    
    /**
     * Change the main image to have the current Bitmap
     */
    private void updateViews() {
    	mainImage.setImageBitmap(bMap);
    }
    
    /**
     * Share the current picture with any Intent on the Share list
     */
    private void startShareMediaActivity() {
    	Intent share = new Intent(Intent.ACTION_SEND);
    	share.setType("image/png");
    	
    	share.putExtra(Intent.EXTRA_STREAM,
    	  Uri.fromFile(getFileStreamPath(filename)));
    	Log.d("Stego", "uri=" + Uri.fromFile(getFileStreamPath(filename)));
    	startActivity(Intent.createChooser(share, "Share Image"));
    }
    
    /**
     * Save the current image to the filename location
     */
    private void saveToFile() {
    	try {
			FileOutputStream out = openFileOutput(filename, Context.MODE_WORLD_READABLE);
			bMap.compress(Bitmap.CompressFormat.PNG, 100, out);
			out.close();
		} catch (Exception e) {
			Log.e("OOPS", e.toString()); 
		}
    }
    
    /** 
     * Decodes the hidden message in the Bitmap
     * @return the message found
     */
    private String decodeBMap() {
    	
    	StringBuffer message = new StringBuffer("");
    	
    	// TODO Write your code here
    	
    	return message.toString();
    }

    
    /***********
     * DecodeTask runs the decoding in the background, since it might take a while and
     * interrupt the UI Thread
     */
	private class DecodeTask extends AsyncTask<String, Void, String> {
		protected void onPreExecute() {
  			pd = ProgressDialog.show(StegoActivity.this,"Decoding File","Interpreting Information...",true,false,null);
		}
		
	     protected String doInBackground(String... urls) {
	         return decodeBMap();
	     }

	     protected void onPostExecute(String message) {
	    	 pd.dismiss();
	    	 stegoMessage.setText("" + message);
	     }
	}
	
    
    /**
     * For each pixel, get rgb values and create pixels array. Shift integers to right argb place.
     * @param message what to encode
     */
    public Bitmap encodeBMap(String message) {
    	int width = bMap.getWidth();
    	int height = bMap.getHeight();
        int[] pixels = new int[width * height];

        // TODO Write your code here
        
    	Bitmap bMap1 = Bitmap.createBitmap(pixels, width, height, Bitmap.Config.valueOf("ARGB_8888"));
    	return bMap1;    	
    }	
    
    /*********
     * EncodeTask runs the decoding in the background, since it might take a while and
     * interrupt the UI Thread
     */
	private class EncodeTask extends AsyncTask<String, Void, Bitmap> {
		protected void onPreExecute() {
  			pd = ProgressDialog.show(StegoActivity.this,"Encoding File","Writing Information...",true,false,null);
		}
		
		protected Bitmap doInBackground(String... urls) {
			return encodeBMap(urls[0]);
		}	
	
		protected void onPostExecute(Bitmap bitmap) {
			bMap = bitmap;
			saveToFile();
			updateBMap();
			updateViews();
			pd.dismiss();
		}
	}
}