package org.osmdroid.views.overlay;

/**
 * ScaleBarOverlay.java
 *
 * Puts a scale bar in the top-left corner of the screen, offset by a configurable
 * number of pixels. The bar is scaled to 1-inch length by querying for the physical
 * DPI of the screen. The size of the bar is printed between the tick marks. A
 * vertical (longitude) scale can be enabled. Scale is printed in metric (kilometers,
 * meters), imperial (miles, feet) and nautical (nautical miles, feet).
 *
 * Author: Erik Burrows, Griffin Systems LLC
 * 		erik@griffinsystems.org
 *
 * Change Log:
 * 		2010-10-08: Inclusion to osmdroid trunk
 * 		2015-12-17: Allow for top, bottom, left or right placement by W.  Strickling
 *
 * Usage: 
 * <code>
 * MapView map = new MapView(...);
 * ScaleBarOverlay scaleBar = new ScaleBarOverlay(map); // Thiw is an important change of calling!
 *
 * map.getOverlays().add(scaleBar);
 * </code>
 *
 * To Do List:
 * 1. Allow for top, bottom, left or right placement. // done in this changement
 * 2. Scale bar to precise displayed scale text after rounding.
 *
 */

import java.lang.reflect.Field;
import java.util.Locale;

import org.osmdroid.api.IGeoPoint;
import org.osmdroid.library.R;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.util.constants.GeoConstants;
import org.osmdroid.views.MapView;
import org.osmdroid.views.Projection;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Rect;
import android.util.DisplayMetrics;
import android.view.WindowManager;

public class ScaleBarOverlay extends Overlay implements GeoConstants {

	// ===========================================================
	// Fields
	// ===========================================================

	private static final Rect sTextBoundsRect = new Rect();

	public enum UnitsOfMeasure {
		metric, imperial, nautical
	}

	// Defaults
	int xOffset = 10;
	int yOffset = 10;
	int minZoom = 0;

	UnitsOfMeasure unitsOfMeasure = UnitsOfMeasure.metric;

	boolean latitudeBar = true;
	boolean longitudeBar = false;
	
	protected boolean alignBottom = false;
	protected boolean alignRight  = false;


	// Internal

	private Context context;
	private MapView mMapView;

	protected final Path barPath = new Path();
	protected final Rect latitudeBarRect = new Rect();
	protected final Rect longitudeBarRect = new Rect();

	private int lastZoomLevel = -1;
	private double lastLatitude = 0.0;

	public float xdpi;
	public float ydpi;
	public int screenWidth;
	public int screenHeight;

	private Paint barPaint;
	private Paint bgPaint;
	private Paint textPaint;

	private boolean centred = false;
	private boolean adjustLength = false;
	private float maxLength;

	// ===========================================================
	// Constructors
	// ===========================================================

	public ScaleBarOverlay(final MapView mapView) {
		super();
		this.mMapView = mapView;
		this.context = mapView.getContext();
		final DisplayMetrics dm = context.getResources().getDisplayMetrics();

		this.barPaint = new Paint();
		this.barPaint.setColor(Color.BLACK);
		this.barPaint.setAntiAlias(true);
		this.barPaint.setStyle(Style.STROKE);
		this.barPaint.setAlpha(255);
		this.barPaint.setStrokeWidth(2 * dm.density);
		this.bgPaint = null;

		this.textPaint = new Paint();
		this.textPaint.setColor(Color.BLACK);
		this.textPaint.setAntiAlias(true);
		this.textPaint.setStyle(Style.FILL);
		this.textPaint.setAlpha(255);
		this.textPaint.setTextSize(10 * dm.density);

		this.xdpi = dm.xdpi;
		this.ydpi = dm.ydpi;

		this.screenWidth = dm.widthPixels;
		this.screenHeight = dm.heightPixels;

		// DPI corrections for specific models
		String manufacturer = null;
		try {
			final Field field = android.os.Build.class.getField("MANUFACTURER");
			manufacturer = (String) field.get(null);
		} catch (final Exception ignore) {
		}

		if ("motorola".equals(manufacturer) && "DROIDX".equals(android.os.Build.MODEL)) {

			// If the screen is rotated, flip the x and y dpi values
			WindowManager windowManager = (WindowManager) this.context
					.getSystemService(Context.WINDOW_SERVICE);
			if (windowManager.getDefaultDisplay().getOrientation() > 0) {
				this.xdpi = (float) (this.screenWidth / 3.75);
				this.ydpi = (float) (this.screenHeight / 2.1);
			} else {
				this.xdpi = (float) (this.screenWidth / 2.1);
				this.ydpi = (float) (this.screenHeight / 3.75);
			}

		} else if ("motorola".equals(manufacturer) && "Droid".equals(android.os.Build.MODEL)) {
			// http://www.mail-archive.com/android-developers@googlegroups.com/msg109497.html
			this.xdpi = 264;
			this.ydpi = 264;
		}

		// set default max length to 1 inch
		maxLength = 2.54f;
	}

	// ===========================================================
	// Getter & Setter
	// ===========================================================

	/**
	 * Sets the minimum zoom level for the scale bar to be drawn.
	 * 
	 * @param zoom
	 *            minimum zoom level
	 */
	public void setMinZoom(final int zoom) {
		this.minZoom = zoom;
	}

	/**
	 * Sets the scale bar screen offset for the bar. Note: if the bar is set to be drawn centered,
	 * this will be the middle of the bar, otherwise the top left corner.
	 * 
	 * @param x
	 *            x screen offset
	 * @param y
	 *            z screen offset
	 */
	public void setScaleBarOffset(final int x, final int y) {
		xOffset = x;
		yOffset = y;
	}

	/**
	 * Sets the bar's line width. (the default is 2)
	 * 
	 * @param width
	 *            the new line width
	 */
	public void setLineWidth(final float width) {
		this.barPaint.setStrokeWidth(width);
	}

	/**
	 * Sets the text size. (the default is 12)
	 * 
	 * @param size
	 *            the new text size
	 */
	public void setTextSize(final float size) {
		this.textPaint.setTextSize(size);
	}

	/**
	 * Sets the units of measure to be shown in the scale bar
	 */
	public void setUnitsOfMeasure(UnitsOfMeasure unitsOfMeasure) {
		this.unitsOfMeasure = unitsOfMeasure;
		lastZoomLevel = -1; // Force redraw of scalebar
	}

	/**
	 * Gets the units of measure to be shown in the scale bar
	 */
	public UnitsOfMeasure getUnitsOfMeasure() {
		return unitsOfMeasure;
	}

	/**
	 * Latitudinal / horizontal scale bar flag
	 * 
	 * @param latitude
	 */
	public void drawLatitudeScale(final boolean latitude) {
		this.latitudeBar = latitude;
		lastZoomLevel = -1; // Force redraw of scalebar
	}

	/**
	 * Longitudinal / vertical scale bar flag
	 * 
	 * @param longitude
	 */
	public void drawLongitudeScale(final boolean longitude) {
		this.longitudeBar = longitude;
		lastZoomLevel = -1; // Force redraw of scalebar
	}

	/**
	 * Flag to draw the bar centered around the set offset coordinates or to the right/bottom of the
	 * coordinates (default)
	 * 
	 * @param centred
	 *            set true to centre the bar around the given screen coordinates
	 */
	public void setCentred(final boolean centred) {
		this.centred = centred;
		alignBottom  = !centred;
		alignRight   = !centred;
		lastZoomLevel = -1; // Force redraw of scalebar
	}

	public void setAlignBottom(final boolean alignBottom) {
		this.centred = false;
		this.alignBottom  = alignBottom;
		lastZoomLevel = -1; // Force redraw of scalebar
	}

	public void setAlignRight(final boolean alignRight) {
		this.centred = false;
		this.alignRight  = alignRight;
		lastZoomLevel = -1; // Force redraw of scalebar
	}
	/**
	 * Return's the paint used to draw the bar
	 * 
	 * @return the paint used to draw the bar
	 */
	public Paint getBarPaint() {
		return barPaint;
	}

	/**
	 * Sets the paint for drawing the bar
	 * 
	 * @param pBarPaint
	 *            bar drawing paint
	 */
	public void setBarPaint(final Paint pBarPaint) {
		if (pBarPaint == null) {
			throw new IllegalArgumentException("pBarPaint argument cannot be null");
		}
		barPaint = pBarPaint;
		lastZoomLevel = -1; // Force redraw of scalebar
	}

	/**
	 * Returns the paint used to draw the text
	 * 
	 * @return the paint used to draw the text
	 */
	public Paint getTextPaint() {
		return textPaint;
	}

	/**
	 * Sets the paint for drawing the text
	 * 
	 * @param pTextPaint
	 *            text drawing paint
	 */
	public void setTextPaint(final Paint pTextPaint) {
		if (pTextPaint == null) {
			throw new IllegalArgumentException("pTextPaint argument cannot be null");
		}
		textPaint = pTextPaint;
		lastZoomLevel = -1; // Force redraw of scalebar
	}

	/**
	 * Sets the background paint. Set to null to disable drawing of background (default)
	 * 
	 * @param pBgPaint
	 *            the paint for colouring the bar background
	 */
	public void setBackgroundPaint(final Paint pBgPaint) {
		bgPaint = pBgPaint;
		lastZoomLevel = -1; // Force redraw of scalebar
	}

	/**
	 * If enabled, the bar will automatically adjust the length to reflect a round number (starting
	 * with 1, 2 or 5). If disabled, the bar will always be drawn in full length representing a
	 * fractional distance.
	 */
	public void setEnableAdjustLength(boolean adjustLength) {
		this.adjustLength = adjustLength;
		lastZoomLevel = -1; // Force redraw of scalebar
	}

	/**
	 * Sets the maximum bar length. If adjustLength is disabled this will match exactly the length
	 * of the bar. If adjustLength is enabled, the bar will be shortened to reflect a round number
	 * in length.
	 * 
	 * @param pMaxLengthInCm
	 *            maximum length of the bar in the screen in cm. Default is 2.54 (=1 inch)
	 */
	public void setMaxLength(final float pMaxLengthInCm) {
		this.maxLength = pMaxLengthInCm;
		lastZoomLevel = -1; // Force redraw of scalebar
	}

	// ===========================================================
	// Methods from SuperClass/Interfaces
	// ===========================================================

	@Override
	public void draw(Canvas c, MapView mapView, boolean shadow) {
		if (shadow) {
			return;
		}

		// If map view is animating, don't update, scale will be wrong.
		if (mapView.isAnimating()) {
			return;
		}

		final int zoomLevel = mapView.getZoomLevel();

		if (zoomLevel >= minZoom) {
			final Projection projection = mapView.getProjection();

			if (projection == null) {
				return;
			}

			int _screenWidth	   = mapView.getWidth();
			int _screenHeight   = mapView.getHeight();
			boolean screenSizeChanged = _screenHeight!=screenHeight || _screenWidth != screenWidth;
			screenHeight = _screenHeight;
			screenWidth = _screenWidth;
			final IGeoPoint center = projection.fromPixels(screenWidth / 2, screenHeight / 2, null);
			if (zoomLevel != lastZoomLevel
				|| (int) center.getLatitude() != (int) lastLatitude || screenSizeChanged) {
				lastZoomLevel = zoomLevel;
				lastLatitude = center.getLatitude();
				rebuildBarPath(projection);
			}

			int offsetX = (int) xOffset;
			int offsetY = (int) yOffset;
			if (alignBottom) offsetY *=-1;
			if (alignRight ) offsetX *=-1;
			if (centred && latitudeBar)
				offsetX += -latitudeBarRect.width() / 2;
			if (centred && longitudeBar)
				offsetY += -longitudeBarRect.height() / 2;

			projection.save(c, false, true);
			c.translate(offsetX, offsetY);

			if (latitudeBar && bgPaint != null)
				c.drawRect(latitudeBarRect, bgPaint);
			if (longitudeBar && bgPaint != null) {
				// Don't draw on top of latitude background...
				int offsetTop = latitudeBar ? latitudeBarRect.height() : 0;
				c.drawRect(longitudeBarRect.left, longitudeBarRect.top + offsetTop,
						longitudeBarRect.right, longitudeBarRect.bottom, bgPaint);
			}
			c.drawPath(barPath, barPaint);
			if (latitudeBar) {
				drawLatitudeText(c, projection);
			}
			if (longitudeBar) {
				drawLongitudeText(c, projection);
			}
			projection.restore(c, true);
		}
	}

	// ===========================================================
	// Methods
	// ===========================================================

	public void disableScaleBar() {
		setEnabled(false);
	}

	public void enableScaleBar() {
		setEnabled(true);
	}

	private void drawLatitudeText(final Canvas canvas, final Projection projection) {
		// calculate dots per centimeter
		int xdpcm = (int) ((float) xdpi / 2.54);

		// get length in pixel
		int xLen = (int) (maxLength * xdpcm);

		// Two points, xLen apart, at scale bar screen location
		IGeoPoint p1 = projection.fromPixels((screenWidth / 2) - (xLen / 2), yOffset, null);
		IGeoPoint p2 = projection.fromPixels((screenWidth / 2) + (xLen / 2), yOffset, null);

		// get distance in meters between points
        final double xMeters = ((GeoPoint) p1).distanceToAsDouble(p2);
		// get adjusted distance, shortened to the next lower number starting with 1, 2 or 5
		final double xMetersAdjusted = this.adjustLength ? adjustScaleBarLength(xMeters) : xMeters;
		// get adjusted length in pixels
		final int xBarLengthPixels = (int) (xLen * xMetersAdjusted / xMeters);

		// create text
        final String xMsg = scaleBarLengthText(xMetersAdjusted);
		textPaint.getTextBounds(xMsg, 0, xMsg.length(), sTextBoundsRect);
		final int xTextSpacing = (int) (sTextBoundsRect.height() / 5.0);

		float x = xBarLengthPixels / 2 - sTextBoundsRect.width() / 2;
		if (alignRight)  x+= screenWidth -xBarLengthPixels;
		float y; 
		if (alignBottom) { y = screenHeight   -xTextSpacing*2; }
		else y = sTextBoundsRect.height() + xTextSpacing;
		canvas.drawText(xMsg, x, y, textPaint);
	}

	private void drawLongitudeText(final Canvas canvas, final Projection projection) {
		// calculate dots per centimeter
		int ydpcm = (int) ((float) ydpi / 2.54);

		// get length in pixel
		int yLen = (int) (maxLength * ydpcm);

		// Two points, yLen apart, at scale bar screen location
		IGeoPoint p1 = projection
				.fromPixels(screenWidth / 2, (screenHeight / 2) - (yLen / 2), null);
		IGeoPoint p2 = projection
				.fromPixels(screenWidth / 2, (screenHeight / 2) + (yLen / 2), null);

		// get distance in meters between points
        final double yMeters = ((GeoPoint) p1).distanceToAsDouble(p2);
		// get adjusted distance, shortened to the next lower number starting with 1, 2 or 5
		final double yMetersAdjusted = this.adjustLength ? adjustScaleBarLength(yMeters) : yMeters;
		// get adjusted length in pixels
		final int yBarLengthPixels = (int) (yLen * yMetersAdjusted / yMeters);

		// create text
        final String yMsg = scaleBarLengthText(yMetersAdjusted);
		textPaint.getTextBounds(yMsg, 0, yMsg.length(), sTextBoundsRect);
		final int yTextSpacing = (int) (sTextBoundsRect.height() / 5.0);

		float x; 
		if (alignRight)  {x = screenWidth  -yTextSpacing*2;}
		else x = sTextBoundsRect.height() + yTextSpacing;
		float y = yBarLengthPixels / 2 + sTextBoundsRect.width() / 2;
		if (alignBottom) y+= screenHeight -yBarLengthPixels;
		canvas.save();
		canvas.rotate(-90, x, y);
		canvas.drawText(yMsg, x, y, textPaint);
		canvas.restore();
	}

	protected void rebuildBarPath(final Projection projection) {   //** modified to protected
		// We want the scale bar to be as long as the closest round-number miles/kilometers
		// to 1-inch at the latitude at the current center of the screen.

		// calculate dots per centimeter
		int xdpcm = (int) ((float) xdpi / 2.54);
		int ydpcm = (int) ((float) ydpi / 2.54);

		// get length in pixel
		int xLen = (int) (maxLength * xdpcm);
		int yLen = (int) (maxLength * ydpcm);

		// Two points, xLen apart, at scale bar screen location
		IGeoPoint p1 = projection.fromPixels((screenWidth / 2) - (xLen / 2), yOffset, null);
		IGeoPoint p2 = projection.fromPixels((screenWidth / 2) + (xLen / 2), yOffset, null);

		// get distance in meters between points
        final double xMeters = ((GeoPoint) p1).distanceToAsDouble(p2);
		// get adjusted distance, shortened to the next lower number starting with 1, 2 or 5
		final double xMetersAdjusted = this.adjustLength ? adjustScaleBarLength(xMeters) : xMeters;
		// get adjusted length in pixels
		final int xBarLengthPixels = (int) (xLen * xMetersAdjusted / xMeters);

		// Two points, yLen apart, at scale bar screen location
		p1 = projection.fromPixels(screenWidth / 2, (screenHeight / 2) - (yLen / 2), null);
		p2 = projection.fromPixels(screenWidth / 2, (screenHeight / 2) + (yLen / 2), null);

		// get distance in meters between points
        final double yMeters = ((GeoPoint) p1).distanceToAsDouble(p2);
		// get adjusted distance, shortened to the next lower number starting with 1, 2 or 5
		final double yMetersAdjusted = this.adjustLength ? adjustScaleBarLength(yMeters) : yMeters;
		// get adjusted length in pixels
		final int yBarLengthPixels = (int) (yLen * yMetersAdjusted / yMeters);

		// create text
        final String xMsg = scaleBarLengthText(xMetersAdjusted);
		final Rect xTextRect = new Rect();
		textPaint.getTextBounds(xMsg, 0, xMsg.length(), xTextRect);
		int xTextSpacing = (int) (xTextRect.height() / 5.0);           

		// create text
        final String yMsg = scaleBarLengthText(yMetersAdjusted);
		final Rect yTextRect = new Rect();
		textPaint.getTextBounds(yMsg, 0, yMsg.length(), yTextRect);
		int yTextSpacing = (int) (yTextRect.height() / 5.0);
		int xTextHeight  = xTextRect.height();
		int yTextHeight  = yTextRect.height();

		barPath.rewind();
		
		//** alignBottom ad-ons
		int barOriginX = 0;
		int barOriginY = 0;
		int barToX     = xBarLengthPixels;
		int barToY	   = yBarLengthPixels;
		if (alignBottom) {
			xTextSpacing *= -1;
			xTextHeight  *= -1;
			barOriginY   = mMapView.getHeight();
			barToY       = barOriginY -yBarLengthPixels;
		}
				
		if (alignRight) {
			yTextSpacing *= -1;
			yTextHeight  *= -1;		
			barOriginX   = mMapView.getWidth();
			barToX       = barOriginX -xBarLengthPixels;    
		}
		
		if (latitudeBar) {
			// draw latitude bar
			barPath.moveTo(barToX, barOriginY +xTextHeight + xTextSpacing * 2);
			barPath.lineTo(barToX, barOriginY);
			barPath.lineTo(barOriginX, barOriginY);

			if (!longitudeBar) {
				barPath.lineTo(barOriginX,  barOriginY +xTextHeight + xTextSpacing * 2);
			}
			latitudeBarRect.set(barOriginX, barOriginY, barToX, barOriginY +xTextHeight + xTextSpacing * 2);
		}

		if (longitudeBar) {
			// draw longitude bar
			if (!latitudeBar) {
				barPath.moveTo(barOriginX +yTextHeight + yTextSpacing * 2, barOriginY);
				barPath.lineTo(barOriginX, barOriginY);
			}

			barPath.lineTo(barOriginX, barToY);
			barPath.lineTo(barOriginX +yTextHeight + yTextSpacing * 2, barToY);

			longitudeBarRect.set(barOriginX, barOriginY, barOriginX +yTextHeight + yTextSpacing * 2, barToY);
		}
	}

	/**
	 * Returns a reduced length that starts with 1, 2 or 5 and trailing zeros. If set to nautical or
	 * imperial the input will be transformed before and after the reduction so that the result
	 * holds in that respective unit.
	 * 
	 * @param length
	 *            length to round
	 * @return reduced, rounded (in m, nm or mi depending on setting) result
	 */
	private double adjustScaleBarLength(double length) {
		long pow = 0;
		boolean feet = false;
		if (unitsOfMeasure == UnitsOfMeasure.imperial) {
			if (length >= GeoConstants.METERS_PER_STATUTE_MILE / 5)
				length = length / GeoConstants.METERS_PER_STATUTE_MILE;
			else {
				length = length * GeoConstants.FEET_PER_METER;
				feet = true;
			}
		} else if (unitsOfMeasure == UnitsOfMeasure.nautical) {
			if (length >= GeoConstants.METERS_PER_NAUTICAL_MILE / 5)
				length = length / GeoConstants.METERS_PER_NAUTICAL_MILE;
			else {
				length = length * GeoConstants.FEET_PER_METER;
				feet = true;
			}
		}

		while (length >= 10) {
			pow++;
			length /= 10;
		}
		while (length < 1 && length > 0) {
			pow--;
			length *= 10;
		}

		if (length < 2) {
			length = 1;
		} else if (length < 5) {
			length = 2;
		} else {
			length = 5;
		}
		if (feet)
			length = length / GeoConstants.FEET_PER_METER;
		else if (unitsOfMeasure == UnitsOfMeasure.imperial)
			length = length * GeoConstants.METERS_PER_STATUTE_MILE;
		else if (unitsOfMeasure == UnitsOfMeasure.nautical)
			length = length * GeoConstants.METERS_PER_NAUTICAL_MILE;
		length *= Math.pow(10, pow);
		return length;
	}

	protected String scaleBarLengthText(final double meters) {
		switch (unitsOfMeasure) {
		default:
		case metric:
			if (meters >= 1000 * 5) {
                return getScaleString(R.string.format_distance_kilometers, "%.0f", meters / 1000);
			} else if (meters >= 1000 / 5) {
				return getScaleString(R.string.format_distance_kilometers, "%.1f", meters / 1000);
			} else if (meters >= 20){
                return getScaleString(R.string.format_distance_meters, "%.0f", meters);
			} else {
				return getScaleString(R.string.format_distance_meters, "%.2f", meters);
			}
		case imperial:
			if (meters >= METERS_PER_STATUTE_MILE * 5) {
				return getScaleString(R.string.format_distance_miles, "%.0f", meters / METERS_PER_STATUTE_MILE);

			} else if (meters >= METERS_PER_STATUTE_MILE / 5) {
				return getScaleString(R.string.format_distance_miles, "%.1f", meters / METERS_PER_STATUTE_MILE);
			} else {
				return getScaleString(R.string.format_distance_feet, "%.0f", meters * FEET_PER_METER);
			}
		case nautical:
			if (meters >= METERS_PER_NAUTICAL_MILE * 5) {
				return getScaleString(R.string.format_distance_nautical_miles, "%.0f", meters / METERS_PER_NAUTICAL_MILE);
			} else if (meters >= METERS_PER_NAUTICAL_MILE / 5) {
				return getScaleString(R.string.format_distance_nautical_miles, "%.1f", meters / METERS_PER_NAUTICAL_MILE);
			} else {
				return getScaleString(R.string.format_distance_feet, "%.0f", meters * FEET_PER_METER);
			}
		}
	}

	@Override
	public void onDetach(MapView mapView){
		this.context=null;
		this.mMapView=null;
		barPaint=null;
		bgPaint=null;
		textPaint=null;
	}

	/**
	 * @since 5.6.6
	 */
	private String getScaleString(final int pStringResId, final String pFormat, final double pValue) {
		return context.getResources().getString(pStringResId, String.format(Locale.getDefault(), pFormat, pValue));
	}
}


