package com.aberdyne.droidnavi.client;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.CopyOnWriteArraySet;
import com.aberdyne.droidnavi.client.ServerListManager.ServerListListener.Action;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
public class ServerListManager {
private static boolean isStarted = false; // False till
private static final String PREF_SERVER_LIST = "serverList";
private ServerListManager() {}
/**
* Initialize the ServerList and inform all listeners of servers.
*
* This method only needs to be called once but should be called
* after all listeners have added them to dispatch list.
* @param context
*/
public static void init(Context context) {
if(!isStarted) {
Set<String> serverList = getSet(context);
for(String server : serverList) {
ServerConnection connection = new ServerConnection(server);
fireEvent(Action.ADD, connection, context);
}
isStarted = true;
}
}
public static void getSync(Context context) {
Set<String> set = getSet(context);
for(String ip : set) {
ServerConnection server = new ServerConnection(ip);
fireEvent(Action.SYNC, server, context);
}
}
public static void addServerListListener(ServerListListener listener) {
Dispatch.addListener(listener);
}
public static void removeServerListListener(ServerListListener listener) {
Dispatch.removeListener(listener);
}
public static synchronized boolean addServer(Context context, ServerConnection ip) {
if(ip == null || context == null) {
throw new NullPointerException();
}
String ip_str = ip.toString();
TreeSet<String> set = getSet(context);
// Add server and Update Preferences
try {
if(! set.add(ip_str))
return false;
} catch(Exception e) {
e.printStackTrace();
return false;
}
boolean result = updatePref(context, set);
if(result == true) {
fireEvent(Action.ADD, ip, context);
}
return result;
}
public static synchronized boolean removeServer(Context context, ServerConnection ip) {
if(context == null || ip == null) {
throw new NullPointerException();
}
String ip_str = ip.toString();
TreeSet<String> set = getSet(context);
// Remove server and Update Preferences
try {
if(! set.remove(ip_str))
return false;
} catch(Exception e) {
e.printStackTrace();
return false;
}
boolean result = updatePref(context, set);
if(result == true) {
fireEvent(Action.REMOVE, ip, context);
}
return result;
}
public static synchronized void updateServer(Context context, ServerConnection ip) {
fireEvent(Action.UPDATE, ip, context);
}
private static boolean updatePref(Context context, TreeSet<String> serverList) {
assert context != null;
assert serverList != null;
SharedPreferences pref =
context.getSharedPreferences(PREF_SERVER_LIST, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = pref.edit();
editor.putStringSet(PREF_SERVER_LIST, serverList);
return editor.commit();
}
private static TreeSet<String> getSet(Context context) {
SharedPreferences pref =
context.getSharedPreferences(PREF_SERVER_LIST, Context.MODE_PRIVATE);
Set<String> set = pref.getStringSet(PREF_SERVER_LIST, null);
TreeSet<String> returnSet = (set==null) ? new TreeSet<String>() : new TreeSet<String>(set);
return returnSet;
}
private static void fireEvent(Action action, ServerConnection ip, Context context) {
Log.d("ServerListManager", "Event: " + action.toString() + " Ip: " + ip.toString());
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Dispatch(action, ip));
//Thread t = new Thread(new Dispatch(action, ip));
//t.start();
}
public interface ServerListListener {
public enum Action {
ADD, // New IP added
REMOVE, // IP removed
UPDATE, // State of the server has updated
SYNC // Get all IPs
}
public void onServerListChange(Action action, ServerConnection server);
}
private static class Dispatch implements Runnable {
private static CopyOnWriteArraySet<ServerListListener> m_listeners =
new CopyOnWriteArraySet<ServerListListener>();
private Action m_action = null;
private ServerConnection m_server = null;
public Dispatch(Action action, ServerConnection server) {
assert action != null;
assert server != null;
m_action = action;
m_server = server;
}
/**
* Dispatch the new event in a thread.
*/
public void run() {
for(ServerListListener listener : m_listeners) {
listener.onServerListChange(m_action, m_server);
}
}
public static void addListener(ServerListListener listener) {
m_listeners.add(listener);
}
public static void removeListener(ServerListListener listener) {
m_listeners.remove(listener);
}
}
}