/**
*
*/
package org.awesomeapp.messenger.ui;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.awesomeapp.messenger.ImApp;
import org.awesomeapp.messenger.provider.Imps;
import org.awesomeapp.messenger.service.IImConnection;
import org.awesomeapp.messenger.ui.legacy.SignInHelper;
public class AccountAdapter extends CursorAdapter implements AccountListItem.SignInManager {
private LayoutInflater mInflater;
private int mResId;
private Cursor mStashCursor;
private AsyncTask<Void, Void, List<AccountSetting>> mBindTask;
private Listener mListener;
private Activity mActivity;
private static Handler sHandler = new Handler()
{
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
//update notifications from async task
}
};
public AccountAdapter(Activity context,
LayoutInflater.Factory factory, int resId) {
super(context, null, 0);
mActivity = context;
mInflater = LayoutInflater.from(context).cloneInContext(context);
mInflater.setFactory(factory);
mResId = resId;
}
public void setListener(Listener listener) {
this.mListener = listener;
}
@Override
public Cursor swapCursor(Cursor newCursor) {
if(mBindTask != null) {
mBindTask.cancel(false);
mBindTask = null ;
}
if (mStashCursor != null && (!mStashCursor.isClosed()))
mStashCursor.close();
mStashCursor = newCursor;
if (mStashCursor != null) {
// Delay swapping in the cursor until we get the extra info
// List<AccountInfo> accountInfoList = getAccountInfoList(mStashCursor) ;
// runBindTask((Activity)mContext, accountInfoList);
}
return super.swapCursor(mStashCursor);
};
/**
* @param cursor
* @return
*/
private List<AccountInfo> getAccountInfoList(Cursor cursor) {
List<AccountInfo> aiList = new ArrayList<AccountInfo>();
cursor.moveToPosition(-1);
while( cursor.moveToNext() ) {
aiList.add( getAccountInfo(cursor));
}
return aiList;
}
static class AccountInfo {
int providerId;
String activeUserName;
int dbConnectionStatus;
int presenceStatus;
}
static class AccountSetting {
String mProviderNameText;
String mSecondRowText;
boolean mSwitchOn;
String activeUserName;
int connectionStatus ;
String domain;
String host;
int port;
boolean isTor;
}
AccountInfo getAccountInfo( Cursor cursor ) {
AccountInfo accountInfo = new AccountInfo();
accountInfo.providerId = cursor.getInt(cursor.getColumnIndexOrThrow(Imps.Provider._ID));
if (!cursor.isNull(cursor.getColumnIndexOrThrow(Imps.Provider.ACTIVE_ACCOUNT_ID))) {
accountInfo.activeUserName = cursor.getString(cursor.getColumnIndexOrThrow(Imps.Provider.ACTIVE_ACCOUNT_USERNAME));
accountInfo.dbConnectionStatus = cursor.getInt(cursor.getColumnIndexOrThrow(Imps.Provider.ACCOUNT_PRESENCE_STATUS));
accountInfo.presenceStatus = cursor.getInt(cursor.getColumnIndexOrThrow(Imps.Provider.ACCOUNT_CONNECTION_STATUS));
}
return accountInfo;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// create a custom view, so we can manage it ourselves. Mainly, we want to
// initialize the widget views (by calling getViewById()) in newView() instead of in
// bindView(), which can be called more often.
AccountListItem view = (AccountListItem) mInflater.inflate(mResId, parent, false);
boolean showLongName = false;
view.init(mActivity, cursor, showLongName, this);
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
((AccountListItem) view).bindView(cursor);
}
private void runBindTask( final Activity context, final List<AccountInfo> accountInfoList ) {
final Resources resources = context.getResources();
final ContentResolver resolver = context.getContentResolver();
final ImApp mApp = (ImApp)context.getApplication();
// if called multiple times
if (mBindTask != null)
mBindTask.cancel(false);
//
mBindTask = new AsyncTask<Void, Void, List<AccountSetting>>() {
@Override
protected List<AccountSetting> doInBackground(Void... params) {
List<AccountSetting> accountSettingList = new ArrayList<AccountSetting>();
for( AccountInfo ai : accountInfoList ) {
accountSettingList.add( getAccountSettings(ai) );
}
return accountSettingList;
}
private AccountSetting getAccountSettings(AccountInfo ai) {
AccountSetting as = new AccountSetting();
Cursor pCursor = resolver.query(Imps.ProviderSettings.CONTENT_URI,new String[] {Imps.ProviderSettings.NAME, Imps.ProviderSettings.VALUE},Imps.ProviderSettings.PROVIDER + "=?",new String[] { Long.toString(ai.providerId)},null);
if (pCursor != null)
{
Imps.ProviderSettings.QueryMap settings =
new Imps.ProviderSettings.QueryMap(pCursor, resolver, ai.providerId, false , null);
as.connectionStatus = ai.dbConnectionStatus;
as.activeUserName = ai.activeUserName;
as.domain = settings.getDomain();
as.host = settings.getServer();
as.port = settings.getPort();
as.isTor = settings.getUseTor();
/**
IImConnection conn = mApp.getConnection(ai.providerId,settings.get);
if (conn == null) {
as.connectionStatus = ImConnection.DISCONNECTED;
} else {
try {
as.connectionStatus = conn.getState();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}*/
settings.close();
}
return as;
}
@Override
protected void onPostExecute(List<AccountSetting> result) {
// store
mBindTask = null;
// swap
AccountAdapter.super.swapCursor(mStashCursor);
if (mListener != null)
mListener.onPopulate();
}
};
mBindTask.execute();
}
public interface Listener {
void onPopulate();
}
public void signIn(long providerId, long accountId) {
if (accountId <= 0) {
return;
}
Cursor cursor = getCursor();
cursor.moveToFirst();
while (!cursor.isAfterLast())
{
long cAccountId = cursor.getLong(ACTIVE_ACCOUNT_ID_COLUMN);
if (cAccountId == accountId)
break;
cursor.moveToNext();
}
// Remember that the user signed in.
setKeepSignedIn(accountId, true);
// long providerId = cursor.getLong(PROVIDER_ID_COLUMN);
String password = cursor.getString(ACTIVE_ACCOUNT_PW_COLUMN);
boolean isActive = true; // TODO(miron)
new SignInHelper(mActivity, sHandler).signIn(password, providerId, accountId, isActive);
cursor.moveToPosition(-1);
}
public void signOut(final long providerId, final long accountId) {
// Remember that the user signed out and do not auto sign in until they
// explicitly do so
setKeepSignedIn(accountId, false);
try {
IImConnection conn = ((ImApp)mActivity.getApplication()).getConnection(providerId, accountId);
if (conn != null) {
conn.logout();
}
} catch (Exception ex) {
}
}
private void setKeepSignedIn(final long accountId, boolean signin) {
Uri mAccountUri = ContentUris.withAppendedId(Imps.Account.CONTENT_URI, accountId);
ContentValues values = new ContentValues();
values.put(Imps.Account.KEEP_SIGNED_IN, signin);
mActivity.getContentResolver().update(mAccountUri, values, null, null);
}
static final int PROVIDER_ID_COLUMN = 0;
static final int PROVIDER_NAME_COLUMN = 1;
static final int PROVIDER_FULLNAME_COLUMN = 2;
static final int PROVIDER_CATEGORY_COLUMN = 3;
static final int ACTIVE_ACCOUNT_ID_COLUMN = 4;
static final int ACTIVE_ACCOUNT_USERNAME_COLUMN = 5;
static final int ACTIVE_ACCOUNT_PW_COLUMN = 6;
static final int ACTIVE_ACCOUNT_LOCKED = 7;
static final int ACTIVE_ACCOUNT_KEEP_SIGNED_IN = 8;
static final int ACCOUNT_PRESENCE_STATUS = 9;
static final int ACCOUNT_CONNECTION_STATUS = 10;
}