package eu.hgross.blaubot.android.views;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Handler;
import android.os.Looper;
import android.text.Html;
import android.util.AttributeSet;
import android.view.View;
import android.widget.CheckBox;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import eu.hgross.blaubot.android.R;
import eu.hgross.blaubot.core.Blaubot;
import eu.hgross.blaubot.core.BlaubotKingdomConnection;
import eu.hgross.blaubot.core.BlaubotServerConnector;
import eu.hgross.blaubot.core.IBlaubotConnection;
import eu.hgross.blaubot.core.statemachine.IBlaubotConnectionStateMachineListener;
import eu.hgross.blaubot.core.statemachine.states.IBlaubotState;
import eu.hgross.blaubot.core.statemachine.states.KingState;
import eu.hgross.blaubot.ui.IBlaubotDebugView;
/**
* Android view to display informations about the ServerConnector and the connection to the server
*
* Add this view to a blaubot instance like this: view.registerBlaubotInstance(blaubot);
*
* @author Henning Gross {@literal (mail.to@henning-gross.de)}
*
*/
public class ServerConnectorView extends FrameLayout implements IBlaubotDebugView {
/**
* The interval to check the state of the ServerConnector and update the ui
*/
public static final long UPDATE_INTERVAL = 1500;
private ToggleButton mToggleButton;
private View mServerConnectionInfoContainer;
private ConnectionView mConnectionView;
private TextView mConnectionInfoTextView;
private CheckBox mHasServerConnectionCheckBox;
private Handler mUiHandler;
private Blaubot mBlaubot;
private IBlaubotState currentSstate;
private ScheduledExecutorService scheduledThreadPoolExecutor;
private volatile boolean initalized = false;
/**
* Hacky way to update the state of the ServerConnector.
*/
private Runnable updateUiTask = new Runnable() {
@Override
public void run() {
mUiHandler.post(new Runnable() {
@Override
public void run() {
if(!initalized) {
return;
}
if(mBlaubot != null) {
final BlaubotServerConnector serverConnector = mBlaubot.getServerConnector();
final IBlaubotConnection serverConnection = serverConnector != null ? serverConnector.getServerConnection() : null;
final BlaubotKingdomConnection currentlyUsedServerConnection = mBlaubot.getServerConnectionManager().getCurrentlyUsedServerConnection();
// gather data
boolean inKingState = currentSstate != null && currentSstate instanceof KingState;
boolean connectorIsSet = serverConnector != null;
boolean connectorIsActive = serverConnector != null && serverConnector.getDoConnect();
boolean hasConnection = serverConnector != null && serverConnection != null;
boolean hasUsedConnection = currentlyUsedServerConnection != null;
// if in kingstate, visualize which connection we are using to speak to the server
if (inKingState) {
final List<IBlaubotConnection> connectionsToServer = mBlaubot.getServerConnectionManager().getConnectionsToServer();
final int connectionsToServerCount = connectionsToServer.size();
mConnectionView.clearConnections();
mConnectionView.addConnections(connectionsToServer);
StringBuilder sb = new StringBuilder("<html><b>Using server connection:</b><br>");
if(hasUsedConnection) {
sb.append(currentlyUsedServerConnection.toString());
} else {
sb.append("No connection to server :-(");
}
mConnectionInfoTextView.setText(Html.fromHtml(sb.toString()));
mConnectionInfoTextView.setVisibility(VISIBLE);
mServerConnectionInfoContainer.setVisibility(VISIBLE);
} else {
mConnectionInfoTextView.setVisibility(GONE);
mServerConnectionInfoContainer.setVisibility(GONE);
}
// update ui
mToggleButton.setEnabled(true);
mToggleButton.setChecked(connectorIsActive);
mHasServerConnectionCheckBox.setChecked(hasConnection);
} else {
mHasServerConnectionCheckBox.setChecked(false);
mConnectionInfoTextView.setText("");
mToggleButton.setEnabled(false);
mToggleButton.setChecked(false);
}
}
});
}
};
public ServerConnectorView(Context context, AttributeSet attrs) {
super(context, attrs);
initView(context, attrs);
}
public ServerConnectorView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initView(context, attrs);
}
private void initView(Context context, AttributeSet attrs) {
this.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
// start updates
scheduledThreadPoolExecutor = Executors.newSingleThreadScheduledExecutor();
scheduledThreadPoolExecutor.scheduleAtFixedRate(updateUiTask, (long) 0, UPDATE_INTERVAL, TimeUnit.MILLISECONDS);
}
@Override
public void onViewDetachedFromWindow(View v) {
// stop updates
if (scheduledThreadPoolExecutor != null) {
scheduledThreadPoolExecutor.shutdown();
scheduledThreadPoolExecutor = null;
}
}
});
View view = inflate(getContext(), R.layout.blaubot_serverconnector_view, null);
if (attrs != null) {
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.StateView,
0, 0);
try {
// mShowOwnUniqueId = a.getBoolean(R.styleable.StateView_showOwnUniqueId, mShowOwnUniqueId);
} finally {
a.recycle();
}
}
mConnectionInfoTextView = (TextView) view.findViewById(R.id.serverConnectorConnectionInfoTextView);
mToggleButton = (ToggleButton) view.findViewById(R.id.serverConnectorToggleButton);
mHasServerConnectionCheckBox = (CheckBox) view.findViewById(R.id.hasServerConnectionCheckBox);
mServerConnectionInfoContainer = view.findViewById(R.id.serverConnectionInfoContainer);
mConnectionView = (ConnectionView) view.findViewById(R.id.connectionView);
mHasServerConnectionCheckBox.setEnabled(false);
mToggleButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if(mBlaubot != null) {
BlaubotServerConnector serverConnector = mBlaubot.getServerConnector();
if (serverConnector != null) {
serverConnector.setDoConnect(mToggleButton.isChecked());
} else {
Toast.makeText(getContext(), "Can not activate: No server connector attached!", Toast.LENGTH_LONG).show();
}
}
}
});
addView(view);
mUiHandler = new Handler(Looper.getMainLooper());
initalized = true;
}
private IBlaubotConnectionStateMachineListener connectionStateMachineListener = new IBlaubotConnectionStateMachineListener() {
@Override
public void onStateChanged(IBlaubotState oldState, IBlaubotState newState) {
currentSstate = newState;
}
@Override
public void onStateMachineStopped() {
}
@Override
public void onStateMachineStarted() {
}
};
/**
* Register this view with the given blaubot instance
*
* @param blaubot
* the blaubot instance to connect with
*/
public void registerBlaubotInstance(Blaubot blaubot) {
if (mBlaubot != null) {
unregisterBlaubotInstance();
}
this.mBlaubot = blaubot;
this.mBlaubot.getConnectionStateMachine().addConnectionStateMachineListener(connectionStateMachineListener);
}
@Override
public void unregisterBlaubotInstance() {
if(mBlaubot != null) {
this.mBlaubot.getConnectionStateMachine().removeConnectionStateMachineListener(connectionStateMachineListener);
this.mBlaubot = null;
}
}
}