package com.ezio.multiwii.waypoints;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Random;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.AudioManager;
import android.os.Bundle;
import android.os.Handler;
import android.view.WindowManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.ActionMode;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.ezio.multiwii.R;
import com.ezio.multiwii.app.App;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap.OnCameraChangeListener;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerDragListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
public class MapWaypointsActivity extends SherlockFragmentActivity {
MapHelperClass mapHelperClass;
Menu ActionBarMenu;
ActionMode mMode;
float CircleRadius = 0;
int CirclePointsCount = 10;
boolean ShowWaypointControls = false;
boolean MoveMap = true;
private long centerStep = 0;
int CurrentWaypointNumber = -1;
final int distanceWhenWPReached = 5;
float distanceToNextWaypoint = 9999;
boolean killme = false;
Random random = new Random(); // for test
App app;
Handler mHandler = new Handler();
TextView TVInfoMap;
NumberFormat format = new DecimalFormat("0.00");
private Runnable update = new Runnable() {
@Override
public void run() {
app.mw.ProcessSerialData(app.loggingON);
app.frskyProtocol.ProcessSerialData(false);
// simulation
if (app.D) {
app.mw.GPS_latitude += random.nextInt(50) - 1;
app.mw.GPS_longitude += random.nextInt(50) - 1;
app.mw.GPS_fix = 1;
app.mw.head++;
if (app.mw.head > 360)
app.mw.head = 0;
}
LatLng copterPositionLatLng = new LatLng(app.mw.GPS_latitude / Math.pow(10, 7), app.mw.GPS_longitude / Math.pow(10, 7));
// Map centering
if (MoveMap && centerStep < System.currentTimeMillis()) {
if (app.mw.GPS_fix == 1) {
mapHelperClass.map.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(copterPositionLatLng, app.MapZoomLevel, 0, app.mw.head)));
} else {
mapHelperClass.map.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(new LatLng(app.sensors.PhoneLatitude, app.sensors.PhoneLongitude), app.MapZoomLevel, 0, 0)));
}
centerStep = System.currentTimeMillis() + app.MapCenterPeriod * 1000;
}
// State dissplaying ////////////////////
// String state = "";
// for (int i = 0; i < app.mw.CHECKBOXITEMS; i++) {
// if (app.mw.ActiveModes[i]) {
// state += " " + app.mw.buttonCheckboxLabel[i];
// }
// }
if (distanceToNextWaypoint < 5)
SetNextWaypoint(false);
mapHelperClass.SetCopterLocation(copterPositionLatLng, app.mw.head, app.mw.alt);
mapHelperClass.DrawFlightPath(copterPositionLatLng);
mapHelperClass.PositionHoldMarker.setPosition(new LatLng(app.mw.Waypoints[16].Lat / Math.pow(10, 7), app.mw.Waypoints[16].Lon / Math.pow(10, 7)));
mapHelperClass.HomeMarker.setPosition(new LatLng(app.mw.Waypoints[0].Lat / Math.pow(10, 7), app.mw.Waypoints[0].Lon / Math.pow(10, 7)));
if (CurrentWaypointNumber >= 0) {
distanceToNextWaypoint = (float) MapHelperClass.gps2m(copterPositionLatLng.latitude, copterPositionLatLng.longitude, mapHelperClass.markers.get(CurrentWaypointNumber).getPosition().latitude, mapHelperClass.markers.get(CurrentWaypointNumber).getPosition().longitude);
}
DisplayInfo();
app.Frequentjobs();
app.mw.SendRequest(app.MainRequestMethod);
if (!killme)
mHandler.postDelayed(update, app.RefreshRate);
}
};
void DisplayInfo() {
TVInfoMap.setText("");
if (CurrentWaypointNumber >= 0) {
TVInfoMap.setText("WP#" + String.valueOf(CurrentWaypointNumber + 1) + "\n");
TVInfoMap.append("To WP#" + String.valueOf(CurrentWaypointNumber + 1) + ":" + format.format(distanceToNextWaypoint) + "m" + "\n");
}
TVInfoMap.append("Alt:" + format.format(app.mw.alt) + "m" + "\n");
TVInfoMap.append("Bat:" + format.format(app.mw.bytevbat / 10.0) + "V" + "\n");
TVInfoMap.append("Power:" + String.valueOf(app.mw.pMeterSum) + "/" + String.valueOf(app.mw.intPowerTrigger) + "\n");
TVInfoMap.append("Sat:" + String.valueOf(app.mw.GPS_numSat) + "\n");
TVInfoMap.append("Head:" + String.valueOf((int) app.mw.head) + "\n");
TVInfoMap.append("Speed:" + String.valueOf((int) app.mw.GPS_speed) + "m/s" + "\n");
TVInfoMap.append("ToHome:" + format.format(app.mw.GPS_distanceToHome) + "m" + "\n");
TVInfoMap.append("DirToHome:" + String.valueOf((int) app.mw.GPS_directionToHome));
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (GooglePlayServicesUtil.isGooglePlayServicesAvailable(getApplicationContext()) != ConnectionResult.SUCCESS) {
Toast.makeText(this, getString(R.string.GooglePlayServiecesError), Toast.LENGTH_LONG).show();
finish();
}
app = (App) getApplication();
app.ForceLanguage();
app.ConnectionBug();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.waypoints_map_layout);
getSupportActionBar().setDisplayShowTitleEnabled(false);
getSupportActionBar().setDisplayShowHomeEnabled(false);
TVInfoMap = (TextView) findViewById(R.id.textViewInfoMap);
mapHelperClass = new MapHelperClass(((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap(), distanceWhenWPReached);
mapHelperClass.map.setOnCameraChangeListener(new OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition position) {
if (app.mw.GPS_fix == 1)
app.MapZoomLevel = (int) position.zoom;
}
});
mapHelperClass.map.setOnMarkerDragListener(new OnMarkerDragListener() {
@Override
public void onMarkerDragStart(Marker marker) {
}
@Override
public void onMarkerDragEnd(Marker marker) {
mapHelperClass.RedrawLines();
}
@Override
public void onMarkerDrag(Marker marker) {
mapHelperClass.RedrawLines();
}
});
mapHelperClass.map.setOnMapLongClickListener(new OnMapLongClickListener() {
@Override
public void onMapLongClick(LatLng point) {
Toast.makeText(getApplicationContext(), String.valueOf(point.latitude * 1e6), Toast.LENGTH_SHORT).show();
Intent i = new Intent(getApplicationContext(), WaypointActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("LAT", (long) (point.latitude * 1e6));
i.putExtra("LON", (long) (point.longitude * 1e6));
startActivity(i);
}
});
mapHelperClass.map.animateCamera(CameraUpdateFactory.newCameraPosition(new CameraPosition(new LatLng(0, 0), mapHelperClass.map.getMinZoomLevel(), 0, 0)));
Bundle extras = getIntent().getExtras();
if (extras != null) {
ShowWaypointControls = extras.getBoolean("WAYPOINT");
}
}
@Override
protected void onResume() {
super.onResume();
app.ForceLanguage();
app.Say(getString(R.string.Map));
killme = false;
mHandler.postDelayed(update, app.RefreshRate);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
}
@Override
protected void onPause() {
super.onPause();
mHandler.removeCallbacks(null);
killme = true;
if (app.mw.GPS_fix == 1) {
app.MapZoomLevel = mapHelperClass.map.getCameraPosition().zoom;
app.SaveSettings(true);
}
}
void SetNextWaypoint(boolean previous) {
if (previous) {
CurrentWaypointNumber--;
} else {
CurrentWaypointNumber++;
}
if (CurrentWaypointNumber >= mapHelperClass.markers.size() || CurrentWaypointNumber <= -1) {
CurrentWaypointNumber = -1;
mapHelperClass.CurrentWPCircle.setCenter(new LatLng(0, 0));
return;
}
int alt = 0;
app.mw.SendRequestMSP_SET_WP(new Waypoint(16, (int) (mapHelperClass.markers.get(CurrentWaypointNumber).getPosition().latitude * 1e6 * 10), (int) (mapHelperClass.markers.get(CurrentWaypointNumber).getPosition().longitude * 1e6 * 10), alt, 0, 0, 0));
app.soundManager.playSound(2);
mapHelperClass.CurrentWPCircle.setCenter(mapHelperClass.markers.get(CurrentWaypointNumber).getPosition());
for (Marker m : mapHelperClass.markers) {
m.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));
}
mapHelperClass.markers.get(CurrentWaypointNumber).setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE));
if (app.D) {
app.mw.Waypoints[16].Lat = (int) (mapHelperClass.markers.get(CurrentWaypointNumber).getPosition().latitude * 1e6 * 10);
app.mw.Waypoints[16].Lon = (int) (mapHelperClass.markers.get(CurrentWaypointNumber).getPosition().longitude * 1e6 * 10);
}
}
void AddCircleDialogShow() {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.setTitle(getString(R.string.Radius));
alert.setMessage(getString(R.string.EnterRadius));
// Set an EditText view to get user input
final EditText input = new EditText(this);
input.setText("10");
alert.setView(input);
alert.setPositiveButton(getString(R.string.OK), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
String value = input.getText().toString();
CircleRadius = Float.parseFloat(value.replace(",", "."));
AddCircle(CircleRadius, CirclePointsCount);
mMode = startActionMode(new CircleOptionsActionModeMenu());
}
});
alert.setNegativeButton(getString(R.string.Cancel), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
// Canceled.
}
});
alert.show();
}
void AddCircle(double diameterInMeters, int howManyPoints) {
float x = 360 / howManyPoints;
double azimuth = 0;
for (int i = 0; i < howManyPoints; i++) {
mapHelperClass.AddMarker((MapHelperClass.GetPointGivenRadialAndDistance(mapHelperClass.markers.get(0).getPosition(), diameterInMeters, azimuth)));
azimuth += x;
}
}
// /////menu////////
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater();
ActionBarMenu = menu;
inflater.inflate(R.menu.menu_map_waypoints, menu);
if (!ShowWaypointControls) {
menu.findItem(R.id.MenuMapWaypointAddWP).setVisible(false);
menu.findItem(R.id.MenuMapWaypointClean).setVisible(false);
menu.findItem(R.id.MenuMapWaypointNextWP).setVisible(false);
menu.findItem(R.id.MenuMapWaypointPrevWP).setVisible(false);
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.MenuMapWaypointAddWP) {
mapHelperClass.AddMarker();
if (mapHelperClass.markers.size() == 1) {
mMode = startActionMode(new AddPatternActionModeMenu());
} else {
if (mMode != null) {
mMode.finish();
}
}
return true;
}
if (item.getItemId() == R.id.MenuMapWaypointPrevWP) {
SetNextWaypoint(true);
return true;
}
if (item.getItemId() == R.id.MenuMapWaypointNextWP) {
SetNextWaypoint(false);
return true;
}
if (item.getItemId() == R.id.MenuMapWaypointClean) {
mapHelperClass.CleanMap();
CurrentWaypointNumber = -1;
return true;
}
if (item.getItemId() == R.id.MenuMapWaypointMoveMap) {
MoveMap = !MoveMap;
item.setChecked(MoveMap);
if (MoveMap)
Toast.makeText(getApplicationContext(), getString(R.string.MoveMapEnable), Toast.LENGTH_SHORT).show();
else
Toast.makeText(getApplicationContext(), getString(R.string.MoveMapDissable), Toast.LENGTH_SHORT).show();
return true;
}
return false;
}
// ///menu end//////
private final class AddPatternActionModeMenu implements ActionMode.Callback {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
menu.add(Menu.NONE, 1, Menu.NONE, getString(R.string.AddCirclePath))
// .setIcon(isLight ? R.drawable.ic_compose_inverse :
// R.drawable.ic_compose)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getItemId() == 1) {
AddCircleDialogShow();
mode.finish();
}
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
}
}
private final class CircleOptionsActionModeMenu implements ActionMode.Callback {
@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
menu.add(Menu.NONE, 1, Menu.NONE, getString(R.string.Bigger)).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
menu.add(Menu.NONE, 2, Menu.NONE, getString(R.string.Smaller)).setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
menu.add(Menu.NONE, 3, Menu.NONE, getString(R.string.AddWP)).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add(Menu.NONE, 4, Menu.NONE, getString(R.string.RemWP)).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
return true;
}
@Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
@Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
if (item.getItemId() == 1) {
CircleRadius += 1f;
while (mapHelperClass.markers.size() > 1) {
mapHelperClass.RemoveMarker(mapHelperClass.markers.size() - 1);
}
AddCircle(CircleRadius, CirclePointsCount);
mapHelperClass.RedrawLines();
}
if (item.getItemId() == 2) {
CircleRadius -= 1f;
while (mapHelperClass.markers.size() > 1) {
mapHelperClass.RemoveMarker(mapHelperClass.markers.size() - 1);
}
AddCircle(CircleRadius, CirclePointsCount);
mapHelperClass.RedrawLines();
}
if (item.getItemId() == 3) {
CirclePointsCount += 1;
while (mapHelperClass.markers.size() > 1) {
mapHelperClass.RemoveMarker(mapHelperClass.markers.size() - 1);
}
AddCircle(CircleRadius, CirclePointsCount);
mapHelperClass.RedrawLines();
}
if (item.getItemId() == 4) {
CirclePointsCount -= 1;
while (mapHelperClass.markers.size() > 1) {
mapHelperClass.RemoveMarker(mapHelperClass.markers.size() - 1);
}
AddCircle(CircleRadius, CirclePointsCount);
mapHelperClass.RedrawLines();
}
return true;
}
@Override
public void onDestroyActionMode(ActionMode mode) {
mapHelperClass.RemoveMarker(0);
mapHelperClass.RedrawLines();
}
}
}