package com.aberdyne.droidnavi;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.aberdyne.droidnavi.MulticastTestDialog.MulticastTestCallback;
import com.aberdyne.droidnavi.R;
import com.aberdyne.droidnavi.client.CallMonitorService;
import com.aberdyne.droidnavi.client.MulticastSender;
import com.aberdyne.droidnavi.client.NetworkDispatch;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.ListFragment;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.style.ForegroundColorSpan;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
/**
* The fragment for the Status tab
*
* @author Jeremy May
*
*/
public class StatusFragment extends Fragment {
private View m_view = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
/*
* View is recycled and removed from parent on each create.
*
* This is done to avoid creating a new fragment with the same
* id and causing an inflation exception
*/
if(m_view != null) {
ViewGroup parent = (ViewGroup) m_view.getParent();
if(parent != null) {
parent.removeView(m_view);
}
}
try {
m_view = inflater.inflate(R.layout.layout_status, container, false);
} catch(InflateException e) {}
return m_view;
}
/**
* The List Fragment implementation
*
* @author Jeremy May
*
*/
public static class StatusListFragment extends ListFragment {
private ServiceStatusView m_service = null;
private MulticastStatusView m_multi = null;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
List<HashMap<String, String>> array = new ArrayList<HashMap<String, String>>();
// Status
HashMap<String, String> temp = new HashMap<String, String>();
temp.put("title", "status");
temp.put("desc", "test desc");
array.add(0, temp);
// Multicast
temp = new HashMap<String, String>();
temp.put("title", "multicast");
temp.put("desc", "multicast desc");
array.add(1, temp);
StatusAdapter adapter = new StatusAdapter(inflater.getContext(), array,
android.R.layout.simple_list_item_2,
new String[] {"title", "desc"},
new int[] { android.R.id.text1,
android.R.id.text2 });
this.setListAdapter(adapter);
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
switch(position) {
case 0: // Service Status
boolean running = false;
if(!CallMonitorService.isRunning()) {
ComponentName name = getActivity().startService(new Intent(getActivity(), CallMonitorService.class));
running = (name == null) ? false : true;
}
else {
getActivity().stopService(new Intent(getActivity(), CallMonitorService.class));
}
m_service.update(running);
break;
case 1: // Multicast Status
if(MulticastSender.checkMulticastAvailability()) {
MulticastTestDialog.showDialog(getActivity(), new MulticastTestCallback() {
public void onTestFinish() {
m_multi.update();
}
});
}
break;
}
super.onListItemClick(l, v, position, id);
}
/**
* The list adapter
*
* @author Jeremy May
*
*/
class StatusAdapter extends SimpleAdapter {
public StatusAdapter(Context context,
List<? extends Map<String, String>> data, int resource,
String[] from, int[] to) {
super(context, data, resource, from, to);
m_service = new ServiceStatusView(context);
m_multi = new MulticastStatusView(context);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
StatusView item = null;
switch(position) {
case 0:
item = m_service;
break;
case 1:
item = m_multi;
break;
}
return item.getView(position, convertView, parent);
}
}
/**
* Abstract class for both items on the status list
*
* @author Jeremy May
*
*/
abstract class StatusView extends LinearLayout {
protected TextView m_status = null;
protected TextView m_desc = null;
abstract public void update();
private StatusView(Context context) {
super(context);
this.setLayoutParams(new ListView.LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT,
android.view.ViewGroup.LayoutParams.MATCH_PARENT));
this.setOrientation(LinearLayout.VERTICAL);
// Set the padding using screen density
float scale = getResources().getDisplayMetrics().density;
int size = (int) (50 * scale * 0.5f);
int padding_left = (int)(30 * scale * 0.5f);
this.setPadding(padding_left, size, 0, size);
m_status = new TextView(getContext());
m_desc = new TextView(getContext());
}
public StatusView(Context context, String desc) {
this(context);
m_desc.setText(desc);
m_status.setTextSize(18);
m_desc.setTextSize(10);
this.addView(m_status, 0);
this.addView(m_desc, 1);
}
public View getView(int position, View convertView, ViewGroup parent) {
update();
return this;
}
protected Spannable createSpan(String start_text, String color_text, int color) {
String full = start_text + color_text;
int start = full.indexOf(color_text);
int end = full.length();
Spannable span = new SpannableString(start_text + color_text);
span.setSpan(new ForegroundColorSpan(color), start, end, Spanned.SPAN_INCLUSIVE_INCLUSIVE);
return span;
}
}
/**
* The multicast status row view
* @author Jeremy May
*
*/
class MulticastStatusView extends StatusView {
NetworkDispatch dispatch = null;
public MulticastStatusView(Context context) {
super(context, "Click to test multicast network availability");
dispatch = new NetworkDispatch(context);
}
@Override
public void update() {
String status = getStatusText();
int status_color = getStatusColor();
Spannable span = createSpan("Multicast Status: ", status, getResources().getColor(status_color));
m_status.setText(span, TextView.BufferType.SPANNABLE);
}
protected int getStatusColor() {
if(dispatch.hasMulticast()) {
SharedPreferences pref = getContext().getSharedPreferences("settings", Context.MODE_PRIVATE);
if(pref.getBoolean(NetworkDispatch.MULTI_IS_NETWORK_TESTED_SETTING, false)) {
return pref.getBoolean(NetworkDispatch.MULTI_NETWORK_TEST_RESULT_SETTING, false) ?
android.R.color.holo_green_dark : android.R.color.holo_red_dark;
}
else {
return android.R.color.holo_blue_dark;
}
}
return android.R.color.primary_text_dark;
}
protected String getStatusText() {
if(dispatch.hasMulticast()) {
SharedPreferences pref = getContext().getSharedPreferences("settings", Context.MODE_PRIVATE);
if(pref.getBoolean(NetworkDispatch.MULTI_IS_NETWORK_TESTED_SETTING, false)) {
return pref.getBoolean(NetworkDispatch.MULTI_NETWORK_TEST_RESULT_SETTING, false) ?
"Available / Network OK" : "Available / Network FAIL";
}
else {
return "Available / Network not tested";
}
}
else {
return "Unavailable";
}
}
}
/**
* The row view showing the current status of the background
* service.
*
* @author Jeremy May
*
*/
class ServiceStatusView extends StatusView {
public ServiceStatusView(Context context) {
super(context,"Toggle sending events to PC");
}
@Override
public void update() {
update(CallMonitorService.isRunning());
}
public void update(boolean running) {
String status = getStatusText(running);
int status_color = getStatusColor(running);
Spannable span = createSpan("Service Status: ", status, getResources().getColor(status_color));
m_status.setText(span, TextView.BufferType.SPANNABLE);
}
protected int getStatusColor (boolean running) {
return running ? android.R.color.holo_green_light : android.R.color.holo_red_dark;
}
protected String getStatusText(boolean running) {
return running ? "Running" : "Off";
}
}
}
}