package what.whatandroid.inbox;
import android.app.Activity;
import android.os.Bundle;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.Toast;
import java.util.Collections;
import api.inbox.inbox.Inbox;
import api.inbox.inbox.Message;
import api.soup.MySoup;
import what.whatandroid.R;
import what.whatandroid.callbacks.LoadingListener;
import what.whatandroid.callbacks.OnLoggedInCallback;
/**
* Fragment for displaying a list of conversations on
* some page of the user's inbox
*/
public class InboxListFragment extends Fragment implements OnLoggedInCallback, LoaderManager.LoaderCallbacks<Inbox> {
public static final String PAGE = "what.whatandroid.inboxlistfragment.PAGE";
private static final String SCROLL_STATE = "what.whatandroid.inboxlistfragment.SCROLL_STATE";
/**
* Listener to alert when we're finished loading this page
*/
private LoadingListener<Inbox> listener;
/**
* Conversation changes passer to query after loading if there's
* been some changes made so we can update our view
*/
private ConversationChangesPasser changesPasser;
private ProgressBar loadingIndicator;
private ListView list;
private InboxListAdapter adapter;
private Parcelable scrollState;
/**
* Create a fragment displaying the list of conversations in some
* page of the users inbox
*
* @param page page of messages to show
*/
public static InboxListFragment newInstance(int page){
InboxListFragment f = new InboxListFragment();
Bundle args = new Bundle();
args.putInt(PAGE, page);
f.setArguments(args);
return f;
}
public InboxListFragment(){
//Required empty ctor
}
@Override
public void onAttach(Activity activity){
super.onAttach(activity);
try {
changesPasser = (ConversationChangesPasser)activity;
}
catch (ClassCastException e){
throw new ClassCastException(activity.toString() + " must implement ConversationChangesPasser");
}
}
@Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
if (savedInstanceState != null){
scrollState = savedInstanceState.getParcelable(SCROLL_STATE);
}
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
View view = inflater.inflate(R.layout.fragment_list_view, container, false);
list = (ListView)view.findViewById(R.id.list);
loadingIndicator = (ProgressBar)view.findViewById(R.id.loading_indicator);
adapter = new InboxListAdapter(getActivity());
list.setAdapter(adapter);
list.setOnItemClickListener(adapter);
if (MySoup.isLoggedIn()){
getLoaderManager().initLoader(0, getArguments(), this);
}
return view;
}
@Override
public void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
if (list != null){
outState.putParcelable(SCROLL_STATE, list.onSaveInstanceState());
}
}
public void setListener(LoadingListener<Inbox> listener){
this.listener = listener;
}
@Override
public void onLoggedIn(){
if (isAdded()){
getLoaderManager().initLoader(0, getArguments(), this);
}
}
@Override
public Loader<Inbox> onCreateLoader(int id, Bundle args){
loadingIndicator.setVisibility(View.VISIBLE);
return new InboxAsyncLoader(getActivity(), args);
}
@Override
public void onLoadFinished(Loader<Inbox> loader, Inbox data){
loadingIndicator.setVisibility(View.GONE);
if (data == null || data.getResponse() == null || !data.getStatus()){
Toast.makeText(getActivity(), "Could not load page", Toast.LENGTH_LONG).show();
}
else {
if (adapter.isEmpty()){
//Check if any conversation changes were made to the conversations we're showing
applyConversationChanges(data);
adapter.addAll(data.getResponse().getMessages());
adapter.notifyDataSetChanged();
if (listener != null){
listener.onLoadingComplete(data);
}
if (scrollState != null){
list.onRestoreInstanceState(scrollState);
}
}
}
}
/**
* Check if the conversation changes are being applied to
* one of the conversations we're displaying and apply them if so
*/
public void applyConversationChanges(Inbox data){
if (changesPasser.hasChanges()){
Bundle changes = changesPasser.getChanges();
int convId = changes.getInt(ConversationChangesPasser.CONVERSATION);
for (int i = 0; i < data.getResponse().getMessages().size(); ++i){
Message m = data.getResponse().getMessages().get(i);
if (m.getConvId().intValue() == convId){
if (changes.getBoolean(ConversationChangesPasser.DELETED)){
data.getResponse().getMessages().remove(i);
//Notify the passer that we've consumed the changes
changesPasser.consumeChanges();
return;
}
m.setSticky(changes.getBoolean(ConversationChangesPasser.STICKY));
m.setUnread(changes.getBoolean(ConversationChangesPasser.UNREAD));
//Re-sort the messages to put sticky posts at the top
Collections.sort(data.getResponse().getMessages(), new Message.StickyMessageComparator());
//Notify the passer that we've consumed the changes
changesPasser.consumeChanges();
}
}
}
}
@Override
public void onLoaderReset(Loader<Inbox> loader){
adapter.clear();
adapter.notifyDataSetChanged();
}
}