package interdroid.swan.engine;
import interdroid.swan.R;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import android.app.ListActivity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.graphics.PorterDuff.Mode;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.content.LocalBroadcastManager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class ExpressionViewerActivity extends ListActivity {
private double mMaxEvalRate = Double.MIN_VALUE;
private long mMaxAvgEvalDelay = Long.MIN_VALUE;
private long mMaxAvgEvalTime = Long.MIN_VALUE;
private long mMaxMinEvalTime = Long.MIN_VALUE;
private long mMaxMaxEvalTime = Long.MIN_VALUE;
private boolean mAscending = true;
private String mSortType = "name";
private int mSortVisible = R.id.evalRate;
private int mSortVisibleOld = R.id.evalPercentage;
private boolean mExpandAll = false;
private boolean mExpandAllSelected = false;
private Comparator<Bundle> mComparator = getComparator(mSortType,
mAscending);
private List<Bundle> mExpressions = new ArrayList<Bundle>();
private ExpressionAdapter mAdapter = new ExpressionAdapter();
private BroadcastReceiver mUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// get the data stuff it in the base adapter
Parcelable[] expressions = intent
.getParcelableArrayExtra("expressions");
mExpressions.clear();
for (Parcelable expression : expressions) {
mExpressions.add((Bundle) expression);
}
mMaxEvalRate = Double.MIN_VALUE;
mMaxAvgEvalDelay = Long.MIN_VALUE;
mMaxAvgEvalTime = Long.MIN_VALUE;
mMaxMinEvalTime = Long.MIN_VALUE;
mMaxMaxEvalTime = Long.MIN_VALUE;
// get maximum value variables of all expressions (used for Progress
// Bar)
for (Bundle expression : mExpressions) {
mMaxEvalRate = Math.max(
expression.getDouble("evaluation-rate"), mMaxEvalRate);
mMaxAvgEvalDelay = Math.max(
expression.getLong("avg-evaluation-delay"),
mMaxAvgEvalDelay);
mMaxAvgEvalTime = Math.max(
expression.getLong("avg-evaluation-time"),
mMaxAvgEvalTime);
mMaxMinEvalTime = Math.max(
expression.getLong("min-evaluation-time"),
mMaxMinEvalTime);
mMaxMaxEvalTime = Math.max(
expression.getLong("max-evaluation-time"),
mMaxMaxEvalTime);
}
Collections.sort(mExpressions, mComparator);
mAdapter.notifyDataSetChanged();
}
};
private static Comparator<Bundle> getComparator(final String key,
final boolean ascending) {
return new Comparator<Bundle>() {
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public int compare(Bundle lhs, Bundle rhs) {
Bundle first = ascending ? lhs : rhs;
Bundle last = ascending ? rhs : lhs;
return ((Comparable) first.get(key))
.compareTo((Comparable) last.get(key));
}
};
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setListAdapter(mAdapter);
}
@Override
protected void onResume() {
super.onResume();
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(ExpressionViewerActivity.this,
"updating with service", Toast.LENGTH_SHORT).show();
}
});
LocalBroadcastManager.getInstance(this).registerReceiver(
mUpdateReceiver,
new IntentFilter(EvaluationEngineService.UPDATE_EXPRESSIONS));
// let the service know that we want to get updates...
startService(new Intent(EvaluationEngineService.UPDATE_EXPRESSIONS)
.setClass(this, EvaluationEngineService.class));
}
@Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(
mUpdateReceiver);
super.onPause();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.expressionviewer, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_refresh:
startService(new Intent(EvaluationEngineService.UPDATE_EXPRESSIONS)
.setClass(this, EvaluationEngineService.class));
mExpandAllSelected = false;
break;
case R.id.menu_sort:
return super.onOptionsItemSelected(item);
case R.id.sort_name:
mSortType = "name";
mExpandAllSelected = false;
break;
case R.id.sort_eval_per:
mSortType = "evaluation-percentage";
mSortVisibleOld = mSortVisible;
mSortVisible = R.id.evalPercentage;
mExpandAllSelected = false;
break;
case R.id.sort_eval_rate:
mSortType = "evaluation-rate";
mSortVisibleOld = mSortVisible;
mSortVisible = R.id.evalRate;
mExpandAllSelected = false;
break;
case R.id.sort_eval_delay:
mSortType = "avg-evaluation-delay";
mSortVisibleOld = mSortVisible;
mSortVisible = R.id.evalDelay;
mExpandAllSelected = false;
break;
case R.id.sort_eval_avg_time:
mSortType = "avg-evaluation-time";
mSortVisibleOld = mSortVisible;
mSortVisible = R.id.evalTimeAvg;
mExpandAllSelected = false;
break;
case R.id.sort_eval_min_time:
mSortType = "min-evaluation-time";
mSortVisibleOld = mSortVisible;
mSortVisible = R.id.evalTimeMin;
mExpandAllSelected = false;
break;
case R.id.sort_eval_max_time:
mSortType = "max-evaluation-time";
mSortVisibleOld = mSortVisible;
mSortVisible = R.id.evalTimeMax;
mExpandAllSelected = false;
break;
case R.id.sort_order:
if(mAscending == true){
mAscending = false;
item.setIcon(R.drawable.ic_action_descend);
}else{
mAscending = true;
item.setIcon(R.drawable.ic_action_ascend);
}
mExpandAllSelected = false;
break;
case R.id.expand_all:
if(mExpandAll == true){
mExpandAll = false;
item.setIcon(R.drawable.expandoff);
}else{
mExpandAll = true;
item.setIcon(R.drawable.expandon);
}
mExpandAllSelected = true;
break;
case R.id.sensor_activity:
Intent intent = new Intent(ExpressionViewerActivity.this, SensorViewerActivity.class);
ExpressionViewerActivity.this.startActivity(intent);
mExpandAllSelected = false;
break;
default:
break;
}
mComparator = getComparator(mSortType, mAscending);
Collections.sort(mExpressions, mComparator);
mAdapter.notifyDataSetChanged();
return super.onOptionsItemSelected(item);
}
class ExpressionAdapter extends BaseAdapter {
@Override
public int getCount() {
return mExpressions.size();
}
@Override
public Object getItem(int position) {
return mExpressions.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = LayoutInflater
.from(ExpressionViewerActivity.this).inflate(
R.layout.expression_viewer, null);
}
Bundle expression = mExpressions.get(position);
// Expression Name
((TextView) ((LinearLayout) convertView)
.findViewById(R.id.expressionName)).setText(expression
.getString("name"));
// Evaluation Percentage
((TextView) ((LinearLayout) convertView)
.findViewById(R.id.evalPercentageName)).setText("Time");
((ProgressBar) ((LinearLayout) convertView)
.findViewById(R.id.evalPercentagePB)).setProgress(Math
.round(expression.getFloat("evaluation-percentage")));
((TextView) ((LinearLayout) convertView)
.findViewById(R.id.evalPercentageValue)).setText(String
.format("%.2f",
expression.getFloat("evaluation-percentage"))
+ " %");
// Evaluation Rate
((TextView) ((LinearLayout) convertView)
.findViewById(R.id.evalRateName)).setText("Frequency");
((ProgressBar) ((LinearLayout) convertView)
.findViewById(R.id.evalRatePB))
.setMax((int) (mMaxEvalRate * 1.2));
((ProgressBar) ((LinearLayout) convertView)
.findViewById(R.id.evalRatePB))
.setProgress((int) expression.getDouble("evaluation-rate"));
((TextView) ((LinearLayout) convertView)
.findViewById(R.id.evalRateValue)).setText(String.format(
"%.2f", expression.getDouble("evaluation-rate")) + " Hz");
// Evaluation Delay
((TextView) ((LinearLayout) convertView)
.findViewById(R.id.evalDelayName)).setText("Delay");
((ProgressBar) ((LinearLayout) convertView)
.findViewById(R.id.evalDelayPB))
.setMax((int) (mMaxAvgEvalDelay * 1.2));
((ProgressBar) ((LinearLayout) convertView)
.findViewById(R.id.evalDelayPB)).setProgress(Math
.round(expression.getLong("avg-evaluation-delay")));
((TextView) ((LinearLayout) convertView)
.findViewById(R.id.evalDelayValue)).setText(Long
.toString(expression.getLong("avg-evaluation-delay"))
+ " ms");
// Min Evaluation Time
((TextView) ((LinearLayout) convertView)
.findViewById(R.id.evalTimeMinName)).setText("Min");
((ProgressBar) ((LinearLayout) convertView)
.findViewById(R.id.evalTimeMinPB))
.setMax((int) (mMaxMinEvalTime * 1.2));
((ProgressBar) ((LinearLayout) convertView)
.findViewById(R.id.evalTimeMinPB)).setProgress(Math
.round(expression.getLong("min-evaluation-time")));
((TextView) ((LinearLayout) convertView)
.findViewById(R.id.evalTimeMinValue)).setText(Long
.toString(expression.getLong("min-evaluation-time"))
+ " ms");
// Max Evaluation Time
((TextView) ((LinearLayout) convertView)
.findViewById(R.id.evalTimeMaxName)).setText("Max");
((ProgressBar) ((LinearLayout) convertView)
.findViewById(R.id.evalTimeMaxPB))
.setMax((int) (mMaxMaxEvalTime * 1.2));
((ProgressBar) ((LinearLayout) convertView)
.findViewById(R.id.evalTimeMaxPB)).setProgress(Math
.round(expression.getLong("max-evaluation-time")));
((TextView) ((LinearLayout) convertView)
.findViewById(R.id.evalTimeMaxValue)).setText(Long
.toString(expression.getLong("max-evaluation-time"))
+ " ms");
// Avg Evaluation Time
((TextView) ((LinearLayout) convertView)
.findViewById(R.id.evalTimeAvgName)).setText("Avg");
((ProgressBar) ((LinearLayout) convertView)
.findViewById(R.id.evalTimeAvgPB))
.setMax((int) (mMaxAvgEvalTime * 1.2));
((ProgressBar) ((LinearLayout) convertView)
.findViewById(R.id.evalTimeAvgPB)).setProgress(Math
.round(expression.getLong("avg-evaluation-time")));
((TextView) ((LinearLayout) convertView)
.findViewById(R.id.evalTimeAvgValue)).setText(Long
.toString(expression.getLong("avg-evaluation-time"))
+ " ms");
CheckBox expandButton = (CheckBox) convertView
.findViewById(R.id.expandButton);
expandButton.setTag(position);
expandButton
.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
LinearLayout parent = ((LinearLayout) buttonView
.getParent().getParent());
parent.findViewById(R.id.evalPercentage)
.setVisibility(
isChecked ? View.VISIBLE
: View.GONE);
parent.findViewById(R.id.evalDelay).setVisibility(
isChecked ? View.VISIBLE : View.GONE);
parent.findViewById(R.id.evalRate).setVisibility(
isChecked ? View.VISIBLE : View.GONE);
parent.findViewById(R.id.evalTimeMax)
.setVisibility(
isChecked ? View.VISIBLE
: View.GONE);
parent.findViewById(R.id.evalTimeMin)
.setVisibility(
isChecked ? View.VISIBLE
: View.GONE);
parent.findViewById(R.id.evalTimeAvg)
.setVisibility(
isChecked ? View.VISIBLE
: View.GONE);
parent.findViewById(mSortVisible).setVisibility(
View.VISIBLE);
}
});
//if checkbox is not checked but you change sort variable, remove old variable,
//show new variable
if (!expandButton.isChecked()) {
((LinearLayout) convertView).findViewById(mSortVisibleOld)
.setVisibility(View.GONE);
}
((LinearLayout) convertView).findViewById(mSortVisible)
.setVisibility(View.VISIBLE);
//unfold all values based on mExpandAll value
if(mExpandAllSelected == true){
expandButton.setChecked(mExpandAll);
}
//progress bar color
ProgressBar mySeekBar;
mySeekBar = ((ProgressBar) ((LinearLayout) ((LinearLayout) convertView)
.findViewById(mSortVisibleOld)).getChildAt(1));
mySeekBar.getProgressDrawable().setColorFilter(
getResources().getColor(android.R.color.holo_blue_light),
Mode.SRC_IN);
mySeekBar = ((ProgressBar) ((LinearLayout) ((LinearLayout) convertView)
.findViewById(mSortVisible)).getChildAt(1));
mySeekBar.getProgressDrawable().setColorFilter(Color.RED,
Mode.SRC_IN);
return convertView;
}
}
}