package com.hexonxons.leprawatch.fragment;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import org.koroed.lepra.content.LepraComment;
import org.koroed.lepra.content.LepraPost;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
import android.graphics.Typeface;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.content.LocalBroadcastManager;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.format.DateFormat;
import android.text.style.ForegroundColorSpan;
import android.text.style.StyleSpan;
import android.util.SparseIntArray;
import android.util.TypedValue;
import android.view.ActionMode;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.HeaderViewListAdapter;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import com.devspark.robototextview.util.RobotoTextViewUtils;
import com.devspark.robototextview.util.RobotoTypefaceManager;
import com.devspark.robototextview.widget.RobotoTextView;
import com.hexonxons.leprawatch.R;
import com.hexonxons.leprawatch.system.Constants;
import com.hexonxons.leprawatch.view.CommentElementView;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.listener.PauseOnScrollListener;
public class CommentsFragment extends Fragment
{
public static final String TAG = "CommentsFragment";
// Comments list.
private ArrayList<LepraComment> mComments = null;
// Today begin time.
private long mTodayBegin = Long.MIN_VALUE;
// Yesterday begin time.
private long mYesterdayBegin = Long.MIN_VALUE;
// DateFormatter
private SimpleDateFormat mSimpleDateFormat = null;
// Post.
private LepraPost mLepraPost = null;
// Action mode.
private ActionMode mActionMode = null;
// Comments listview
private ListView mListView = null;
// Current checked position
private int mCurrentCheckedPosition = ListView.INVALID_POSITION;
// Loading view
private View mLoadingView = null;
// Map offset level to parent comment.
private SparseIntArray mOffsetMap = new SparseIntArray();
// Is after rotate.
private boolean mIsAfterRotate = false;
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback()
{
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu)
{
return false;
}
@Override
public void onDestroyActionMode(ActionMode mode)
{
// Remove listview selection
mListView.setItemChecked(ListView.INVALID_POSITION, true);
// Clear selected position
mCurrentCheckedPosition = ListView.INVALID_POSITION;
// Remove action mode.
mActionMode = null;
}
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu)
{
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.comments_action_menu, menu);
return true;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item)
{
switch (item.getItemId())
{
case R.id.action_reply:
{
// Close action mode.
if(mActionMode != null)
{
mActionMode.finish();
}
// Run edit fragment.
EditFragment fragment = new EditFragment();
getActivity().getSupportFragmentManager()
.beginTransaction()
.replace(R.id.main, fragment, EditFragment.TAG)
.addToBackStack(EditFragment.TAG)
.commit();
return true;
}
default:
{
break;
}
}
return false;
}
};
private OnItemClickListener mItemClickListener = new OnItemClickListener()
{
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
{
if(mActionMode != null && mCurrentCheckedPosition == position)
{
mActionMode.finish();
}
else
{
mActionMode = getActivity().startActionMode(mActionModeCallback);
mListView.setItemChecked(position, true);
mCurrentCheckedPosition = position;
}
}
};
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver()
{
@Override
public void onReceive(Context context, Intent intent)
{
switch(intent.getAction())
{
case Constants.INTENT_FILTER.ACTION_GET_POST_COMMENTS:
{
break;
}
case Constants.INTENT_FILTER.ACTION_GET_POST_COMMENTS_RESULT_SUCCESS:
{
mComments = intent.getParcelableArrayListExtra(Constants.BUNDLE.KEY_COMMENTS);
Calendar calendar = new GregorianCalendar();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
mTodayBegin = calendar.getTime().getTime();
calendar.add(Calendar.DAY_OF_MONTH, -1);
mYesterdayBegin = calendar.getTime().getTime();
// Remove loading view.
mListView.removeFooterView(mLoadingView);
mLoadingView = null;
// Update listview.
((CommentsAdapter)((HeaderViewListAdapter)mListView.getAdapter()).getWrappedAdapter()).notifyDataSetChanged();
// Invalidate ab menu after comments is loaded.
getActivity().supportInvalidateOptionsMenu();
break;
}
}
}
};
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
if(savedInstanceState == null)
{
mLepraPost = getArguments().getParcelable(Constants.BUNDLE.KEY_POST);
}
else
{
mIsAfterRotate = true;
mLepraPost = savedInstanceState.getParcelable(Constants.BUNDLE.KEY_POST);
mComments = savedInstanceState.getParcelableArrayList(Constants.BUNDLE.KEY_COMMENTS);
}
mSimpleDateFormat = new SimpleDateFormat("HH:mm");
mSimpleDateFormat.setTimeZone(TimeZone.getTimeZone("Russia/Moscow"));
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
mListView = (ListView) inflater.inflate(R.layout.comments_list, container, false);
mListView.setAdapter(new CommentsAdapter());
mListView.setOnScrollListener(new PauseOnScrollListener(ImageLoader.getInstance(), true, true));
mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
mListView.setOnItemClickListener(mItemClickListener);
mListView.addHeaderView(createPostView());
if(mComments == null)
{
// Inflate loading layout.
mLoadingView = inflater.inflate(R.layout.loading, mListView, false);
// Add loadind view to listview bottom.
mListView.addFooterView(mLoadingView, null, false);
// Send request intent.
Intent intent = new Intent(Constants.INTENT_FILTER.ACTION_GET_POST_COMMENTS);
intent.putExtra(Constants.BUNDLE.KEY_POST, mLepraPost);
LocalBroadcastManager.getInstance(getActivity()).sendBroadcast(intent);
}
return mListView;
}
/**
* {@link https://code.google.com/p/android/issues/detail?id=25994} workaround.
*/
@Override
public Animation onCreateAnimation(int transit, boolean enter, int nextAnim)
{
if(enter)
{
if(mIsAfterRotate)
{
return super.onCreateAnimation(transit, enter, nextAnim);
}
else
{
return AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_in);
}
}
else
{
return AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out);
}
}
@Override
public void onResume()
{
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction(Constants.INTENT_FILTER.ACTION_GET_POST_COMMENTS_RESULT_FAIL);
filter.addAction(Constants.INTENT_FILTER.ACTION_GET_POST_COMMENTS_RESULT_SUCCESS);
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(mBroadcastReceiver, filter);
if(mListView.getCheckedItemPosition() != ListView.INVALID_POSITION)
{
mActionMode = getActivity().startActionMode(mActionModeCallback);
mCurrentCheckedPosition = mListView.getCheckedItemPosition();
}
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater)
{
if(mComments != null)
{
inflater.inflate(R.menu.comments_menu, menu);
}
}
@Override
public void onPause()
{
super.onPause();
LocalBroadcastManager.getInstance(getActivity()).unregisterReceiver(mBroadcastReceiver);
}
@Override
public void onSaveInstanceState(Bundle outState)
{
if(mComments != null)
{
outState.putParcelableArrayList(Constants.BUNDLE.KEY_COMMENTS, mComments);
}
outState.putParcelable(Constants.BUNDLE.KEY_POST, mLepraPost);
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case android.R.id.home:
{
getActivity().getSupportFragmentManager().popBackStack();
return true;
}
case R.id.action_new_comment:
{
// Run edit fragment.
EditFragment fragment = new EditFragment();
getFragmentManager()
.beginTransaction()
.replace(R.id.main, fragment, EditFragment.TAG)
.addToBackStack(EditFragment.TAG)
.commit();
return true;
}
default:
{
break;
}
}
return super.onOptionsItemSelected(item);
}
public View createPostView()
{
CommentElementView view = (CommentElementView) getActivity().getLayoutInflater().inflate(R.layout.comments_header, mListView, false);
// Build author text.
SpannableStringBuilder authorBuilder = new SpannableStringBuilder();
// Gender text. (Написал/Написала)
authorBuilder.append((mLepraPost.userGender.compareTo("male") == 0 ? getResources().getText(R.string.write_man) : getResources().getText(R.string.write_woman)) + " ");
// Rank.
if(mLepraPost.userTitle.length() != 0)
{
authorBuilder.append(mLepraPost.userTitle + " ");
}
int authorStart = authorBuilder.length();
// Nickname text.
authorBuilder.append(mLepraPost.userLogin);
int authorEnd = authorBuilder.length();
// Nickname color.
authorBuilder.setSpan(new ForegroundColorSpan(getResources().getColor(mLepraPost.userGender.compareTo("male") == 0 ? R.color.light_blue_500 : R.color.pink_500)), authorStart, authorEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// Bold style.
authorBuilder.setSpan(new StyleSpan(Typeface.BOLD), authorStart, authorEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// Date.
Date date = new Date(mLepraPost.date);
if(mLepraPost.date >= mTodayBegin)
{
authorBuilder.append(", " + getResources().getText(R.string.date_today) + " " + DateFormat.format("kk:mm", date));
}
else if(mLepraPost.date >= mYesterdayBegin)
{
authorBuilder.append(", " + getResources().getText(R.string.date_yesterday) + " " + DateFormat.format("kk:mm", date));
}
else
{
authorBuilder.append(", " + DateFormat.format("yyyy-MM-dd", date) + " в " + DateFormat.format("kk:mm", date));
}
view.author.setText(authorBuilder);
if(mLepraPost.rating > 0)
{
view.rating.setText("+" + mLepraPost.rating);
view.rating.setTextColor(getResources().getColor(R.color.green_500));
}
else if(mLepraPost.rating < 0)
{
view.rating.setText("" + mLepraPost.rating);
view.rating.setTextColor(getResources().getColor(R.color.red_500));
}
else
{
view.rating.setText("" + mLepraPost.rating);
view.rating.setTextColor(getResources().getColor(R.color.lepra_gray));
}
TextView text = new TextView(getActivity());
text.setText(mLepraPost.content);
view.messageWrapper.addView(text, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
return view;
}
private class CommentsAdapter extends BaseAdapter
{
@Override
public int getCount()
{
return mComments == null ? 0 : mComments.size();
}
@Override
public Object getItem(int position)
{
return position;
}
@Override
public long getItemId(int position)
{
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
CommentElementView view = (CommentElementView) convertView;
if(view == null)
{
view = (CommentElementView) getActivity().getLayoutInflater().inflate(R.layout.comment_element, parent, false);
}
view.messageWrapper.removeAllViews();
Resources res = getResources();
LepraComment comment = mComments.get(position);
int offsetLevel = 0;
if(comment.parentId == Integer.MIN_VALUE)
{
mOffsetMap.append(comment.id, offsetLevel);
}
else
{
offsetLevel = mOffsetMap.get(comment.parentId) + 1;
mOffsetMap.append(comment.id, offsetLevel);
}
view.offset.setCommentOffset(offsetLevel);
// Build author text.
SpannableStringBuilder authorBuilder = new SpannableStringBuilder();
// Gender text. (Написал/Написала)
authorBuilder.append((comment.userGender.compareTo("male") == 0 ? res.getText(R.string.write_man) : res.getText(R.string.write_woman)) + " ");
// Rank.
if(comment.userTitle.length() != 0)
{
authorBuilder.append(comment.userTitle + " ");
}
int authorStart = authorBuilder.length();
// Nickname text.
authorBuilder.append(comment.userLogin);
int authorEnd = authorBuilder.length();
// Nickname color.
authorBuilder.setSpan(new ForegroundColorSpan(res.getColor(comment.userGender.compareTo("male") == 0 ? R.color.light_blue_500 : R.color.pink_500)), authorStart, authorEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// Bold style.
authorBuilder.setSpan(new StyleSpan(Typeface.BOLD), authorStart, authorEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// Date.
Date date = new Date(comment.date);
if(comment.date >= mTodayBegin)
{
authorBuilder.append(", " + res.getText(R.string.date_today) + " " + DateFormat.format("kk:mm", date));
}
else if(comment.date >= mYesterdayBegin)
{
authorBuilder.append(", " + res.getText(R.string.date_yesterday) + " " + DateFormat.format("kk:mm", date));
}
else
{
authorBuilder.append(", " + DateFormat.format("yyyy-MM-dd", date) + " в " + DateFormat.format("kk:mm", date));
}
view.author.setText(authorBuilder);
if(comment.rating > 0)
{
view.rating.setText("+" + comment.rating);
view.rating.setTextColor(getResources().getColor(R.color.green_500));
}
else if(comment.rating < 0)
{
view.rating.setText("" + comment.rating);
view.rating.setTextColor(getResources().getColor(R.color.red_500));
}
else
{
view.rating.setText("" + comment.rating);
view.rating.setTextColor(getResources().getColor(R.color.lepra_gray));
}
RobotoTextView text = new RobotoTextView(getActivity());
RobotoTextViewUtils.setTypeface(text, RobotoTypefaceManager.obtainTypeface(getActivity(), RobotoTypefaceManager.Typeface.ROBOTO_REGULAR));
text.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
text.setText(comment.content);
view.messageWrapper.addView(text, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));
return view;
}
}
}