package org.redpin.android.ui;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.redpin.android.ApplicationContext;
import org.redpin.android.Constants;
import org.redpin.android.R;
import org.redpin.android.core.Location;
import org.redpin.android.core.Map;
import org.redpin.android.core.Measurement;
import org.redpin.android.db.EntityHomeFactory;
import org.redpin.android.json.GsonFactory;
import org.redpin.android.net.HttpGetCommand;
import org.redpin.android.net.HttpPostCommand;
import org.redpin.android.net.wifi.WifiSniffer;
import org.redpin.android.provider.RedpinContract;
import org.redpin.android.ui.list.MapListActivity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
public class AdminActivity extends ActionBarActivity {
private ActionBar actionBar;
private Button btnAdd, btnDetect, btnManageMap, btnAddMap;
ProgressDialog progressDialog;
WifiSniffer mWifiService;
Location mLocation;
private static final String TAG = AdminActivity.class.getSimpleName();
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.admin_layout);
actionBar = getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(true);
actionBar.show();
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME,
ActionBar.DISPLAY_SHOW_CUSTOM);
actionBar.setTitle("Indoor Location Tracker");
actionBar.setSubtitle("beta");
btnAdd = (Button) findViewById(R.id.btnAdd);
btnAdd.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(AdminActivity.this,
AddLocationActivity.class);
startActivity(intent);
}
});
btnDetect = (Button) findViewById(R.id.btnDetect);
btnDetect.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
detectCurrentLocation();
}
});
btnManageMap = (Button) findViewById(R.id.btnManageMap);
btnManageMap.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
if (getContentResolver().query(RedpinContract.Map.CONTENT_URI,
new String[] { RedpinContract.Map.NAME }, null, null,
null).getCount() == 0) {
new AlertDialog.Builder(AdminActivity.this)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
@Override
public void onClick(
DialogInterface dialog,
int which) {
progressDialog
.setMessage("Fetching maps");
progressDialog.show();
new FetchMapTask(
Constants.FETCH_MAP_URL)
.execute();
}
})
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
@Override
public void onClick(
DialogInterface dialog,
int which) {
}
})
.setTitle("Maps")
.setMessage(
"No map founds, search for map on server?")
.create().show();
} else {
Intent intent = new Intent(AdminActivity.this,
MapListActivity.class);
startActivity(intent);
}
}
});
btnAddMap = (Button) findViewById(R.id.btnAddMap);
btnAddMap.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(AdminActivity.this,
AddNewMapActivity.class);
startActivity(intent);
}
});
progressDialog = new ProgressDialog(this);
progressDialog.setCancelable(true);
progressDialog.setIndeterminate(true);
progressDialog.setMessage("Detecting location...");
}
private void detectCurrentLocation() {
progressDialog.show();
mWifiService.forceMeasurement();
}
private void startWifiSniffer() {
bindService(new Intent(this, WifiSniffer.class), mWifiConnection,
Context.BIND_AUTO_CREATE);
registerReceiver(wifiReceiver,
new IntentFilter(WifiSniffer.WIFI_ACTION));
Log.i(TAG, "Started WifiSniffer");
}
private void stopWifiSniffer() {
if (mWifiService != null) {
mWifiService.stopMeasuring();
}
unbindService(mWifiConnection);
unregisterReceiver(wifiReceiver);
Log.i(TAG, "Stopped WifiSniffer");
}
@Override
protected void onResume() {
super.onResume();
startWifiSniffer();
}
@Override
protected void onPause() {
stopWifiSniffer();
super.onPause();
}
@Override
protected void onDestroy() {
try {
stopWifiSniffer();
} catch (Exception e) { }
super.onDestroy();
}
private ServiceConnection mWifiConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName className, IBinder service) {
mWifiService = ((WifiSniffer.LocalBinder) service).getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
mWifiService = null;
}
};
private BroadcastReceiver wifiReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Measurement m = mWifiService.retrieveLastMeasurement();
if (m == null)
return;
mWifiService.stopMeasuring();
new ServerTask("http://" + ApplicationContext.serverIP + ":"
+ ApplicationContext.serverPort
+ ApplicationContext.applicationName + "/location/find", m)
.execute();
}
};
private class FetchMapTask extends AsyncTask<Void, Void, List<Map>> {
private Gson gson = GsonFactory.getGsonInstance();
String url;
public FetchMapTask(String url) {
this.url = url;
}
@Override
protected List<Map> doInBackground(Void... params) {
List<Map> maps = new ArrayList<Map>();
try {
String str = new HttpGetCommand<String>(this.url,
new String[] {}) {
@Override
public String execute() throws IOException, JSONException {
return streamToString(requestStream());
}
}.execute();
JSONArray arr = new JSONObject(str).getJSONArray("map");
for (int i = 0; i < arr.length(); i++) {
Map m = gson.fromJson(arr.getJSONObject(i).toString(),
new TypeToken<Map>() {
}.getType());
maps.add(m);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return maps;
}
@Override
protected void onPostExecute(List<Map> maps) {
progressDialog.cancel();
if (maps != null && maps.size() > 0) {
EntityHomeFactory.getMapHome().add(maps);
Intent intent = new Intent(AdminActivity.this,
MapListActivity.class);
startActivity(intent);
} else {
Toast.makeText(AdminActivity.this,
"No maps found, please add new", Toast.LENGTH_SHORT)
.show();
}
}
}
private class ServerTask extends AsyncTask<Void, Void, Location> {
private Gson gson = GsonFactory.getGsonInstance();
String url;
Measurement m;
public ServerTask(String url, Measurement m) {
this.url = url;
this.m = m;
}
@Override
protected Location doInBackground(Void... params) {
try {
String str = new HttpPostCommand<String>(this.url, gson.toJson(
this.m, new TypeToken<Measurement>() {
}.getType())) {
@Override
public String execute() throws IOException, JSONException {
return streamToString(requestStream());
}
}.execute();
return gson.fromJson(str, new TypeToken<Location>() {
}.getType());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Location location) {
if (location == null) {
new AlertDialog.Builder(AdminActivity.this)
.setPositiveButton(android.R.string.ok, null)
.setTitle("Add new location")
.setMessage("No matching location find").create()
.show();
} else {
new AlertDialog.Builder(AdminActivity.this)
.setPositiveButton(android.R.string.ok, null)
.setTitle("Add new location")
.setMessage(
"You are at:" + location.getSymbolicID()
+ " [accuracy: "
+ location.getAccuracy() + "]")
.create().show();
}
progressDialog.cancel();
}
}
}