package com.tomclaw.mandarin.main.adapters;
import android.app.Activity;
import android.app.LoaderManager;
import android.content.Context;
import android.content.Loader;
import android.database.Cursor;
import android.graphics.Typeface;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.StyleSpan;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.FilterQueryProvider;
import android.widget.ImageView;
import android.widget.TextView;
import com.tomclaw.mandarin.R;
import com.tomclaw.mandarin.core.BitmapCache;
import com.tomclaw.mandarin.core.GlobalProvider;
import com.tomclaw.mandarin.core.PreferenceHelper;
import com.tomclaw.mandarin.core.Settings;
import com.tomclaw.mandarin.core.TaskExecutor;
import com.tomclaw.mandarin.im.BuddyCursor;
import com.tomclaw.mandarin.im.StatusUtil;
import com.tomclaw.mandarin.main.tasks.BuddyInfoTask;
import com.tomclaw.mandarin.main.views.ContactBadge;
import com.tomclaw.mandarin.util.Logger;
import com.tomclaw.mandarin.util.QueryBuilder;
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
/**
* Created by solkin on 04.08.14.
*/
public abstract class RosterStickyAdapter extends CursorAdapter
implements LoaderManager.LoaderCallbacks<Cursor>, StickyListHeadersAdapter {
/**
* Adapter ID
*/
private static final int ADAPTER_STICKY_ID = -1;
/**
* Filter
*/
public static final int FILTER_ALL_BUDDIES = 0x00;
public static final int FILTER_ONLINE_ONLY = 0x01;
/**
* Variables
*/
private Context context;
protected LayoutInflater inflater;
private int filter;
private boolean isShowTemp;
private LoaderManager loaderManager;
private BuddyCursor buddyCursor;
public RosterStickyAdapter(Activity context, LoaderManager loaderManager, int filter) {
super(context, null, 0x00);
this.context = context;
this.inflater = context.getLayoutInflater();
this.loaderManager = loaderManager;
this.filter = filter;
this.isShowTemp = PreferenceHelper.isShowTemp(context);
this.buddyCursor = new BuddyCursor();
initLoader();
setFilterQueryProvider(new RosterFilterQueryProvider());
}
public void initLoader() {
// Initialize loader for dialogs Id.
loaderManager.restartLoader(ADAPTER_STICKY_ID, null, this);
}
public Context getContext() {
return context;
}
/**
* @see android.widget.ListAdapter#getView(int, android.view.View, android.view.ViewGroup)
*/
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
Cursor cursor = getCursor();
View view;
try {
if (cursor == null || !cursor.moveToPosition(position)) {
throw new IllegalStateException("couldn't move cursor to position " + position);
}
if (convertView == null) {
view = newView(context, cursor, parent);
} else {
view = convertView;
}
bindView(view, context, cursor);
} catch (Throwable ex) {
view = inflater.inflate(R.layout.buddy_item, parent, false);
Logger.log("exception in getView: " + ex.getMessage());
}
return view;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return inflater.inflate(R.layout.buddy_item, parent, false);
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
// Status image.
String accountType = buddyCursor.getBuddyAccountType();
int statusIndex = buddyCursor.getBuddyStatus();
int statusImageResource = StatusUtil.getStatusDrawable(accountType, statusIndex);
// Status text.
String statusTitle = buddyCursor.getBuddyStatusTitle();
String statusMessage = buddyCursor.getBuddyStatusMessage();
if (statusIndex == StatusUtil.STATUS_OFFLINE
|| TextUtils.equals(statusTitle, statusMessage)) {
// Buddy status is offline now or status message is only status title.
// No status message could be displayed.
statusMessage = "";
}
SpannableString statusString = new SpannableString(statusTitle + " " + statusMessage);
statusString.setSpan(new StyleSpan(Typeface.BOLD), 0, statusTitle.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
// Unread count.
int unreadCount = buddyCursor.getBuddyUnreadCount();
// Applying values.
((TextView) view.findViewById(R.id.buddy_nick)).setText(buddyCursor.getBuddyNick());
((ImageView) view.findViewById(R.id.buddy_status)).setImageResource(statusImageResource);
((TextView) view.findViewById(R.id.buddy_status_message)).setText(statusString);
if (unreadCount > 0) {
view.findViewById(R.id.counter_layout).setVisibility(View.VISIBLE);
((TextView) view.findViewById(R.id.counter_text)).setText(String.valueOf(unreadCount));
} else {
view.findViewById(R.id.counter_layout).setVisibility(View.GONE);
}
// Draft message.
String buddyDraft = buddyCursor.getBuddyDraft();
view.findViewById(R.id.draft_indicator).setVisibility(
TextUtils.isEmpty(buddyDraft) ? View.GONE : View.VISIBLE);
// Avatar.
final String avatarHash = buddyCursor.getBuddyAvatarHash();
ContactBadge contactBadge = (ContactBadge) view.findViewById(R.id.buddy_badge);
BitmapCache.getInstance().getBitmapAsync(contactBadge, avatarHash, R.drawable.def_avatar_x48, false);
// On-avatar click listener.
final int buddyDbId = buddyCursor.getBuddyDbId();
final BuddyInfoTask buddyInfoTask = new BuddyInfoTask(context, buddyDbId);
contactBadge.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
TaskExecutor.getInstance().execute(buddyInfoTask);
}
});
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return getDefaultQueryBuilder().createCursorLoader(context, Settings.BUDDY_RESOLVER_URI);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
if (cursor != null && !cursor.isClosed()) {
swapCursor(cursor);
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
Cursor cursor = swapCursor(null);
// Maybe, previous non-closed cursor present?
if (cursor != null && !cursor.isClosed()) {
cursor.close();
}
}
@Override
public Cursor swapCursor(Cursor newCursor) {
buddyCursor.switchCursor(newCursor);
return super.swapCursor(newCursor);
}
public BuddyCursor getBuddyCursor() {
return buddyCursor;
}
public int getBuddyDbId(int position) {
BuddyCursor cursor = getBuddyCursor();
if (cursor == null || !cursor.moveToPosition(position)) {
throw new IllegalStateException("couldn't move cursor to position " + position);
}
return cursor.getBuddyDbId();
}
public void setRosterFilter(int filter) {
this.filter = filter;
}
public int getRosterFilter() {
return filter;
}
private QueryBuilder getDefaultQueryBuilder() {
QueryBuilder queryBuilder = new QueryBuilder();
switch (filter) {
case FILTER_ONLINE_ONLY: {
queryBuilder.columnNotEquals(GlobalProvider.ROSTER_BUDDY_STATUS, StatusUtil.STATUS_OFFLINE);
break;
}
case FILTER_ALL_BUDDIES:
default:
}
if (!isShowTemp) {
queryBuilder.and().columnNotEquals(GlobalProvider.ROSTER_BUDDY_GROUP_ID, GlobalProvider.GROUP_ID_RECYCLE);
}
queryBuilder.and().columnNotEquals(GlobalProvider.ROSTER_BUDDY_OPERATION,
GlobalProvider.ROSTER_BUDDY_OPERATION_REMOVE);
postQueryBuilder(queryBuilder);
return queryBuilder;
}
protected abstract void postQueryBuilder(QueryBuilder queryBuilder);
private class RosterFilterQueryProvider implements FilterQueryProvider {
@Override
public Cursor runQuery(CharSequence constraint) {
String searchField = constraint.toString().toUpperCase();
QueryBuilder queryBuilder = getDefaultQueryBuilder();
queryBuilder.and().startComplexExpression().like(GlobalProvider.ROSTER_BUDDY_SEARCH_FIELD, searchField)
.or().like(GlobalProvider.ROSTER_BUDDY_ID, constraint).finishComplexExpression();
return queryBuilder.query(context.getContentResolver(), Settings.BUDDY_RESOLVER_URI);
}
}
}