package net.osmand.plus.dashboard;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import net.osmand.Location;
import net.osmand.data.LatLon;
import net.osmand.plus.OsmAndFormatter;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.views.DirectionDrawable;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Denis
* on 26.01.2015.
*/
@SuppressLint("ResourceAsColor")
public abstract class DashLocationFragment extends DashBaseFragment {
private static final int ORIENTATION_0 = 0;
private static final int ORIENTATION_90 = 3;
private static final int ORIENTATION_270 = 1;
private static final int ORIENTATION_180 = 2;
protected List<DashLocationView> distances = new ArrayList<DashLocationFragment.DashLocationView>();
private int screenOrientation;
protected LatLon lastUpdatedLocation;
public static class DashLocationView {
public ImageView arrow;
public TextView txt;
public LatLon loc;
public int arrowResId;
public boolean paint = true;
public DashLocationView(ImageView arrow, TextView txt, LatLon loc) {
super();
this.arrow = arrow;
this.txt = txt;
this.loc = loc;
}
}
@Override
public void onOpenDash() {
//Hardy: getRotation() is the correction if device's screen orientation != the default display's standard orientation
screenOrientation = getScreenOrientation(getActivity());
}
public static int getScreenOrientation(Activity a) {
int screenOrientation = ((WindowManager) a.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getRotation();
switch (screenOrientation) {
case ORIENTATION_0: // Device default (normally portrait)
screenOrientation = 0;
break;
case ORIENTATION_90: // Landscape right
screenOrientation = 90;
break;
case ORIENTATION_270: // Landscape left
screenOrientation = 270;
break;
case ORIENTATION_180: // Upside down
screenOrientation = 180;
break;
}
//Looks like screenOrientation correction must not be applied for devices without compass?
Sensor compass = ((SensorManager) a.getSystemService(Context.SENSOR_SERVICE)).getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
if (compass == null) {
screenOrientation = 0;
}
return screenOrientation;
}
public LatLon getDefaultLocation() {
DashboardOnMap d = dashboard;
if (d == null) {
return null;
}
return d.getMapViewLocation();
}
public void updateAllWidgets() {
DashboardOnMap d = dashboard;
if (d == null) {
return;
}
float head = d.getHeading();
float mapRotation = d.getMapRotation();
LatLon mw = d.getMapViewLocation();
Location l = d.getMyLocation();
boolean mapLinked = d.isMapLinkedToLocation() && l != null;
LatLon myLoc = l == null ? null : new LatLon(l.getLatitude(), l.getLongitude());
boolean useCenter = !mapLinked;
LatLon loc = (useCenter ? mw : myLoc);
float h = useCenter ? -mapRotation : head;
lastUpdatedLocation = loc;
for (DashLocationView lv : distances) {
updateLocationView(useCenter, loc, h, lv.arrow, lv.arrowResId, lv.txt, lv.loc, screenOrientation,
getMyApplication(), getActivity(), lv.paint);
}
}
public static void updateLocationView(boolean useCenter, LatLon fromLoc, Float h,
ImageView arrow, TextView txt, double toLat, double toLon,
int screenOrientation, OsmandApplication app, Context ctx) {
updateLocationView(useCenter, fromLoc, h, arrow, 0, txt, new LatLon(toLat, toLon), screenOrientation, app, ctx, true);
}
public static void updateLocationView(boolean useCenter, LatLon fromLoc, Float h,
ImageView arrow, int arrowResId, TextView txt, LatLon toLoc,
int screenOrientation, OsmandApplication app, Context ctx, boolean paint) {
float[] mes = new float[2];
if (fromLoc != null && toLoc != null) {
Location.distanceBetween(toLoc.getLatitude(), toLoc.getLongitude(), fromLoc.getLatitude(), fromLoc.getLongitude(), mes);
}
if (arrow != null) {
boolean newImage = false;
if (arrowResId == 0) {
arrowResId = R.drawable.ic_direction_arrow;
}
DirectionDrawable dd;
if(!(arrow.getDrawable() instanceof DirectionDrawable)) {
newImage = true;
dd = new DirectionDrawable(ctx, arrow.getWidth(), arrow.getHeight());
} else {
dd = (DirectionDrawable) arrow.getDrawable();
}
dd.setImage(arrowResId, useCenter ? R.color.color_distance : R.color.color_myloc_distance);
if (fromLoc == null || h == null || toLoc == null) {
dd.setAngle(0);
} else {
dd.setAngle(mes[1] - h + 180 + screenOrientation);
}
if (newImage) {
arrow.setImageDrawable(dd);
}
arrow.invalidate();
}
if (txt != null) {
if (fromLoc != null && toLoc != null) {
if (paint) {
txt.setTextColor(app.getResources().getColor(
useCenter ? R.color.color_distance : R.color.color_myloc_distance));
}
txt.setText(OsmAndFormatter.getFormattedDistance(mes[0], app));
} else {
txt.setText("");
}
}
}
public void updateLocation(boolean centerChanged, boolean locationChanged, boolean compassChanged) {
if (compassChanged && !dashboard.isMapLinkedToLocation()) {
return;
}
updateAllWidgets();
}
}