package org.oobd.ui.android;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Hashtable;
import org.oobd.base.OOBDConstants;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.text.Html;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
import android.widget.ToggleButton;
//http://code.google.com/p/android-file-dialog/
public class OutputActivity extends Activity implements
org.oobd.base.OOBDConstants {
public static Handler myRefreshHandler;
private EditText mytext;
private ToggleButton myLogActiveButton;
public static OutputActivity myOutputActivityInstance = null;
private Hashtable<String, ArrayList<Character>> outputBuffers = new Hashtable<String, ArrayList<Character>>();
private String actualBufferName = OB_DEFAULT_NAME; // name of the actual
// writestring output,
// default is "display"
// for screen output
private char[] actBuffer; //acts as temporary buffer for the output content, while we waiting for the result of the file save dialog
private boolean actFileAppend; //acts as temporary flag for the file Dialog intent, if the ouput should be appended to the file or not
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myOutputActivityInstance = this;
setContentView(R.layout.output);
mytext = (EditText) findViewById(R.id.outputText);
myLogActiveButton = (ToggleButton) findViewById(R.id.loggingToggleButton);
myRefreshHandler = new Handler() {
@Override
public void handleMessage(Message msgObject) {
OutputText myOutputText = (OutputText) msgObject.obj;
String msg = myOutputText.text;
String modifier = myOutputText.modifier;
if (!"".equalsIgnoreCase(modifier)) {
if (modifier.equalsIgnoreCase(OB_CMD_SETBUFFER)) {
actualBufferName = msg.toLowerCase().trim();
if (!actualBufferName.equals(OB_DEFAULT_NAME)) {
if (!outputBuffers.containsKey(actualBufferName)) {
outputBuffers.put(actualBufferName,
new ArrayList<Character>());
actBuffer = new char[0];
}
}
}
if (modifier.equalsIgnoreCase(OB_CMD_CLEAR)) {
if (actualBufferName.equals(OB_DEFAULT_NAME)) { // do
// the
// special
// handling
// of
// the
// UI
// textbox
// here
mytext.setText("");
} else {
outputBuffers.put(actualBufferName,
new ArrayList<Character>());
actBuffer = new char[0];
}
} else if (modifier.equalsIgnoreCase(OB_CMD_CLEARALL)) {
mytext.setText("");
outputBuffers = new Hashtable<String, ArrayList<Character>>();
actBuffer = new char[0];
} else {
// here we need the buffer content, so we need to do the
// time consuming conversion here
if (actualBufferName.equals(OB_DEFAULT_NAME)) {
actBuffer = mytext.getText().toString()
.toCharArray();
} else {
if (outputBuffers.containsKey(actualBufferName)) {
actBuffer = arrayListToCharArray(outputBuffers
.get(actualBufferName));
} else {
outputBuffers.put(actualBufferName,
new ArrayList<Character>());
actBuffer = new char[0];
}
}
if (modifier.equalsIgnoreCase(OB_CMD_SAVEAS)) {
saveBufferAsFileRequest(msg, false);
}
if (modifier.equalsIgnoreCase(OB_CMD_SAVE)) {
saveBufferToFile(msg, false);
}
if (modifier.equalsIgnoreCase(OB_CMD_APPENDAS)) {
saveBufferAsFileRequest(msg, true);
}
if (modifier.equalsIgnoreCase(OB_CMD_APPEND)) {
saveBufferToFile(msg, true);
}
}
} else {
if (actualBufferName.equals(OB_DEFAULT_NAME)) {
if (myLogActiveButton.isChecked()) {
mytext.setText(mytext.getText().toString() + msg
+ "\n");
}
} else {
ArrayList<Character> actBufferArrayList = outputBuffers
.get(actualBufferName);
for (char c : msg.toCharArray()) {
actBufferArrayList.add(c);
}
}
}
}
};
((ImageButton) findViewById(R.id.clearButton))
.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
mytext.setText("");
}
});
((ImageButton) findViewById(R.id.diskButton))
.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
final CharSequence[] items = { "Save as File..",
"Send as Text..", "Attach as .txt ..",
"Attach as .xml .." };
AlertDialog.Builder builder = new AlertDialog.Builder(
myOutputActivityInstance);
builder.setTitle("Handle Output..");
builder.setItems(items,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int item) {
if (item == 0) { // save locally
/*
* Intent intent = new Intent(
* OutputActivity .getInstance()
* .getBaseContext(),
* FileDialog.class);
* intent.putExtra(
* FileDialog.START_PATH,
* "/sdcard/OOBD");
* startActivityForResult(intent,
* 1);
*/
Intent intent = new Intent(
"org.openintents.action.PICK_FILE");
intent.putExtra(Intent.EXTRA_TITLE,
"Save as text");
startActivityForResult(intent, 1);
} else { // send it somehow
Intent intent = new Intent(
Intent.ACTION_SEND);
intent.putExtra(
Intent.EXTRA_SUBJECT,
"OOBD Mail");
if (item == 1) {// the body contains
// the text
// intent.putExtra(Intent.EXTRA_EMAIL,
// new String[]
// {"email@example.com"});
intent.setType("text/plain");
intent.putExtra(
Intent.EXTRA_TEXT,
mytext.getText()
.toString());
} else { // create a attachment
intent.setType("text/html");
String fileName = "";
if (item == 2) {
fileName = "OOBD-textfile.txt";
}
if (item == 3) {
fileName = "OOBD-xmlfile.xml";
}
// first
String extStorageDirectory = Environment
.getExternalStorageDirectory()
.toString()
+ "/OOBD/";
File file = new File(
extStorageDirectory,
fileName);
actBuffer=mytext.getText().toString().toCharArray(); //.toString().getBytes();
saveBufferToFile(file,false);
if (!file.exists()
|| !file.canRead()) {
Toast.makeText(
myOutputActivityInstance,
"Attachment Error",
Toast.LENGTH_SHORT)
.show();
return;
}
intent.putExtra(
Intent.EXTRA_TEXT,
Html.fromHtml("<html><body>With best regards from <a href='http://oobd.org'>OOBD</a></body></html>"));
Uri uri = Uri.parse("file://"
+ file);
intent.putExtra(
Intent.EXTRA_STREAM,
uri);
}
startActivity(Intent.createChooser(
intent,
"Forward Output Text..."));
}
}
});
AlertDialog alert = builder.create();
alert.show();
}
});
}
/*
* as char[] and Arraylist<Character> are not compatible, we need to handle
* Display output and normal buffer handling independent from each other and
* only convert, when really needed.
*/
char[] arrayListToCharArray(ArrayList<Character> input) {
char[] actBuffer = new char[input.size()];
int position = 0;
for (char i : input) {
actBuffer[position] = i;
position++;
}
return actBuffer;
}
boolean saveBufferToFile(String fileName, boolean append) {
File file = new File(fileName);
return saveBufferToFile(file, append);
}
boolean saveBufferToFile(File fileHandle , boolean append) {
try {
FileWriter os = new FileWriter(fileHandle, append);
os.write(actBuffer);
os.close();
return true;
} catch (IOException ex) {
// Unable to create file,
// likely because external
// storage is
// not currently mounted.
Log.w("ExternalStorage", "Error writing " + fileHandle.getName(), ex);
return false;
}
}
private void saveBufferAsFileRequest(String FileName,
boolean append) {
actFileAppend=append;
Intent intent = new Intent(
"org.openintents.action.PICK_FILE");
intent.putExtra(Intent.EXTRA_TITLE,
"Save to file");
startActivityForResult(intent, 1);
}
public synchronized void onActivityResult(final int requestCode,
int resultCode, final Intent data) {
if (resultCode == Activity.RESULT_OK) {
URI filePath = null;
try {
filePath = new URI(data.getDataString());
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
final File file = new File(filePath);
if (file.exists()) {
AlertDialog alertDialog = new AlertDialog.Builder(
myOutputActivityInstance).create();
alertDialog.setTitle("File already exist!");
alertDialog.setMessage("OK to overwrite?");
alertDialog.setButton(DialogInterface.BUTTON_POSITIVE, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,
int which) {
saveBufferToFile(file,false);
}
});
alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE,
"Cancel", (DialogInterface.OnClickListener) null);
alertDialog.show();
} else {
saveBufferToFile(file,false);
}
} else if (resultCode == Activity.RESULT_CANCELED) {
}
}
public static OutputActivity getInstance() {
return myOutputActivityInstance;
}
public void addText(String text, String modifier) {
myRefreshHandler.sendMessage(Message.obtain(myRefreshHandler, 2,
new OutputText(text, modifier)));
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
// if back- button is pressed
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
DiagnoseTab.getInstance().getTabHost().setCurrentTab(0);
return true; // stop further handling of the
// back-button
}
return super.onKeyDown(keyCode, event);
}
}
class OutputText {
public String text;
public String modifier;
public OutputText(String text, String modifier) {
this.text = text;
this.modifier = modifier;
}
}