package com.tomclaw.mandarin.im;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.text.TextUtils;
import com.tomclaw.mandarin.core.CoreService;
import com.tomclaw.mandarin.core.QueryHelper;
import com.tomclaw.mandarin.core.exceptions.AccountNotFoundException;
import com.tomclaw.mandarin.util.Unobfuscatable;
/**
* Created with IntelliJ IDEA.
* User: solkin
* Date: 3/28/13
* Time: 1:54 AM
*/
public abstract class AccountRoot implements Unobfuscatable {
public static final String AUTH_LOST = "auth_lost";
/**
* User info
*/
protected String userId;
protected String userNick;
protected String userPassword;
protected int statusIndex;
protected String statusTitle;
protected String statusMessage;
protected String avatarHash;
protected boolean connectingFlag;
protected boolean isAutoStatus;
protected int backupStatusIndex;
protected String backupStatusTitle;
protected String backupStatusMessage;
/**
* Staff
*/
protected transient Context context;
protected transient int accountDbId;
public void setContext(Context context) {
this.context = context;
}
public Context getContext() {
return context;
}
public ContentResolver getContentResolver() {
return context.getContentResolver();
}
public Resources getResources() {
return context.getResources();
}
public void setAccountDbId(int accountDbId) {
this.accountDbId = accountDbId;
}
public int getAccountDbId() {
return accountDbId;
}
public String getUserId() {
return userId;
}
public void setUserId(String userId) {
this.userId = userId;
}
public void setAvatarHash(String avatarHash) {
this.avatarHash = avatarHash;
}
public String getUserNick() {
return userNick;
}
public void setUserNick(String userNick) {
this.userNick = userNick;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
public int getStatusIndex() {
return statusIndex;
}
public String getStatusTitle() {
return statusTitle;
}
public String getStatusMessage() {
return statusMessage;
}
public String getAvatarHash() {
return avatarHash;
}
public boolean isConnecting() {
return connectingFlag;
}
public abstract void connect();
public abstract void disconnect();
/**
* Set up logic and network status for account. Some online status will connect account
* in case of account was offline. Offline status will disconnect account.
*
* @param statusIndex - non-protocol status index.
*/
public void setStatus(int statusIndex) {
setStatus(statusIndex, StatusUtil.getStatusTitle(getAccountType(), statusIndex), "");
}
/**
* Set up logic and network status for account. Some online status will connect account
* in case of account was offline. Offline status will disconnect account.
*
* @param statusIndex - non-protocol status index.
* @param statusTitle - status title.
* @param statusMessage - status description.
*/
public void setStatus(int statusIndex, String statusTitle, String statusMessage) {
if (getStatusIndex() != statusIndex
|| !TextUtils.equals(getStatusTitle(), statusTitle)
|| !TextUtils.equals(getStatusMessage(), statusMessage)) {
if (getStatusIndex() == StatusUtil.STATUS_OFFLINE) {
updateAccountState(statusIndex, statusTitle, statusMessage, true);
connect();
} else if (statusIndex == StatusUtil.STATUS_OFFLINE) {
updateAccountState(statusIndex, true);
disconnect();
} else {
updateAccountState(statusIndex, statusTitle, statusMessage, false);
// This will create request in database.
updateStatus();
}
}
}
/**
* This will connect account with actual status.
*/
public void actualizeStatus() {
// Checking for connection purpose.
if (getStatusIndex() != StatusUtil.STATUS_OFFLINE) {
// Update account state in database.
updateAccountState(true);
// Yeah, connect!
connect();
} else if (isConnecting()) {
// Disconnection process is not completed. Let's became offline.
updateAccountState(StatusUtil.STATUS_OFFLINE, false);
}
}
public void setAutoStatus(int statusIndex, String statusTitle, String statusMessage) {
// Checking for we are here right now.
if (!isOffline()) {
// Backup manual user status.
backupStatus();
// Update current status.
setStatus(statusIndex, statusTitle, statusMessage);
}
}
public void resetAutoStatus() {
// Trying to restore status.
if (restoreStatus()) {
// Status was restored.
updateStatus();
}
}
private void backupStatus() {
// Checking for this is not already auto-status.
// In case of auto-status we ready to replace it, but save original.
if (!isAutoStatus) {
backupStatusIndex = statusIndex;
backupStatusTitle = statusTitle;
backupStatusMessage = statusMessage;
isAutoStatus = true;
}
}
private boolean restoreStatus() {
if (isAutoStatus) {
statusIndex = backupStatusIndex;
statusTitle = backupStatusTitle;
statusMessage = backupStatusMessage;
isAutoStatus = false;
return true;
}
return false;
}
public abstract void checkCredentials(CredentialsCheckCallback callback);
/**
* This will manual disconnect account after network connection stopped.
* Invokes after account connection closed.
*/
public void carriedOff() {
updateAccountState(StatusUtil.STATUS_OFFLINE, false);
}
public boolean isOffline() {
return getStatusIndex() == StatusUtil.STATUS_OFFLINE && !isConnecting();
}
public boolean isOnline() {
return getStatusIndex() != StatusUtil.STATUS_OFFLINE && !isConnecting();
}
/**
* Setup only connecting flag and updates account in database.
*
* @param isConnecting - connecting flag.
*/
protected void updateAccountState(boolean isConnecting) {
this.connectingFlag = isConnecting;
updateAccount();
}
/**
* Setup status index with default status title and empty message,
* setup connecting flag and update account in database.
*
* @param statusIndex - non-protocol status index.
* @param isConnecting - connecting flag.
*/
protected void updateAccountState(int statusIndex, boolean isConnecting) {
updateAccountState(statusIndex, StatusUtil.getStatusTitle(getAccountType(), statusIndex), "", isConnecting);
}
/**
* Setup status index, title, message and connecting flag and updates account in database.
*
* @param statusIndex - non-protocol status index.
* @param statusTitle - status title
* @param statusMessage - status description
* @param isConnecting - connecting flag.
*/
protected void updateAccountState(int statusIndex, String statusTitle, String statusMessage,
boolean isConnecting) {
// Setup local variables.
this.statusIndex = statusIndex;
this.statusTitle = statusTitle;
this.statusMessage = statusMessage;
this.connectingFlag = isConnecting;
// Save account data in database.
updateAccount();
}
/**
* This will update account info in database
*/
public void updateAccount() {
// Update database info.
try {
QueryHelper.updateAccount(context, this);
} catch (AccountNotFoundException ignored) {
// Impossible case.
}
}
public void onAuthLost() {
// Context is always service if account managed by SessionHolder.
if (context instanceof CoreService) {
CoreService service = (CoreService) context;
Intent intent = new Intent(CoreService.ACTION_CORE_SERVICE);
intent.putExtra(CoreService.EXTRA_STAFF_PARAM, false);
intent.putExtra(AUTH_LOST, true);
service.sendBroadcast(intent);
}
}
/**
* Update protocol online status.
*/
public abstract void updateStatus();
public abstract String getAccountType();
}