package kc.spark.pixels.android.ui.corelist;
import kc.get.pixel.list.android.R;
import kc.spark.pixels.android.app.DeviceState;
import kc.spark.pixels.android.cloud.ApiFacade;
import kc.spark.pixels.android.cloud.api.Device;
import kc.spark.pixels.android.storage.TinkerPrefs;
import kc.spark.pixels.android.ui.tinker.PixelFragment;
import kc.spark.pixels.android.ui.util.Ui;
import org.solemnsilence.util.EZ;
import org.solemnsilence.util.Py;
import org.solemnsilence.util.Py.Ranger.IntValue;
import org.solemnsilence.util.TLog;
import android.app.Activity;
import android.app.ListFragment;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.ListView;
/**
* A list fragment representing a list of Cores. This fragment also supports
* tablet devices by allowing list items to be given an 'activated' state upon
* selection. This helps indicate which item is currently being viewed in a
* {@link PixelFragment}.
* <p>
* Activities containing this fragment MUST implement the {@link Callbacks}
* interface.
*/
public class CoreListFragment extends ListFragment {
private static final TLog log = new TLog(CoreListFragment.class);
/**
* The fragment's current callback object, which is notified of list item
* clicks.
*/
private Callbacks mCallbacks = sDummyCallbacks;
/**
* The current activated item position. Only used on tablets.
*/
private int mActivatedPosition = ListView.INVALID_POSITION;
/**
* A callback interface that all activities containing this fragment must
* implement. This mechanism allows activities to be notified of item
* selections.
*/
public interface Callbacks {
/**
* Callback for when an item has been selected.
*/
public void onItemSelected(String id);
}
/**
* A dummy implementation of the {@link Callbacks} interface that does
* nothing. Used only when this fragment is not attached to an activity.
*/
private static Callbacks sDummyCallbacks = new Callbacks() {
@Override
public void onItemSelected(String id) {
}
};
DeviceListAdapter deviceAdapter;
DevicesUpdatedReceiver updatesReceiver;
LocalBroadcastManager broadcastMgr;
ApiFacade api;
String selectedDeviceId = null;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
*/
public CoreListFragment() {
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Activities containing this fragment must implement its callbacks.
if (!(activity instanceof Callbacks)) {
throw new IllegalStateException("Activity must implement fragment's callbacks.");
}
mCallbacks = (Callbacks) activity;
broadcastMgr = LocalBroadcastManager.getInstance(activity);
api = ApiFacade.getInstance(activity);
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
updatesReceiver = new DevicesUpdatedReceiver();
deviceAdapter = new DeviceListAdapter(getActivity());
setListAdapter(deviceAdapter);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_core_list, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
/*
if (TinkerPrefs.getInstance().isFirstVisit()) {
showInstructions();
}
*/
updateDevicesList();
}
@Override
public void onStart() {
super.onStart();
broadcastMgr.registerReceiver(updatesReceiver, updatesReceiver.getIntentFilter());
}
@Override
public void onStop() {
broadcastMgr.unregisterReceiver(updatesReceiver);
super.onStop();
}
@Override
public void onDetach() {
super.onDetach();
// Reset the active callbacks interface to the dummy implementation.
mCallbacks = sDummyCallbacks;
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.core_list, menu);
//inflater.inflate(R.menu.pref_menu, menu);
}
@Override
public void onListItemClick(ListView listView, View view, int position, long id) {
super.onListItemClick(listView, view, position, id);
Device selectedDevice = deviceAdapter.getItem(position);
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mCallbacks.onItemSelected(selectedDevice.id);
mActivatedPosition = position;
}
public void setActivatedItem(String id) {
Device device = DeviceState.getDeviceById(id);
if (device == null) {
log.w("Device was null when trying to set active list item??");
return;
}
selectedDeviceId = device.id;
mActivatedPosition = deviceAdapter.getPosition(device);
setActiveCoreView();
}
private void updateDevicesList() {
log.d("updateDevicesList()");
deviceAdapter.clear();
deviceAdapter.addAll(DeviceState.getKnownDevices());
if (selectedDeviceId != null) {
setActivatedItem(selectedDeviceId);
setActiveCoreView();
}
}
private void setActiveCoreView() {
// This is just *ugly*, but all of this seems to be necessary to
// *always* show the colored stripe next to the selected core.
for (IntValue intValue : Py.range(getListView().getChildCount())) {
View child = getListView().getChildAt(intValue.value);
if (intValue.value == mActivatedPosition) {
Ui.findView(child, R.id.active_core_stripe).setVisibility(View.VISIBLE);
child.setActivated(true);
} else {
Ui.findView(child, R.id.active_core_stripe).setVisibility(View.INVISIBLE);
}
}
EZ.runOnMainThread(new Runnable() {
@Override
public void run() {
ListView lv = null;
try {
lv = getListView();
if (getActivity() == null || getActivity().isFinishing() || lv == null) {
return;
}
} catch (IllegalStateException e) {
return;
}
for (IntValue intValue : Py.range(lv.getChildCount())) {
View child = lv.getChildAt(intValue.value);
if (intValue.value == mActivatedPosition) {
Ui.findView(child, R.id.active_core_stripe).setVisibility(View.VISIBLE);
child.setActivated(true);
} else {
Ui.findView(child, R.id.active_core_stripe).setVisibility(View.INVISIBLE);
}
}
}
});
}
class DevicesUpdatedReceiver extends BroadcastReceiver {
IntentFilter getIntentFilter() {
return new IntentFilter(ApiFacade.BROADCAST_DEVICES_UPDATED);
}
@Override
public void onReceive(Context context, Intent intent) {
updateDevicesList();
}
}
/*
private void showInstructions() {
View instructions = Ui.findView(this, R.id.tinker_instructions);
// set visible and then set it to disappear when we're done. and then
// never show up again.
instructions.setVisibility(View.VISIBLE);
instructions.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
v.setVisibility(View.GONE);
TinkerPrefs.getInstance().setVisited(true);
}
});
}
*/
}