/*
 * uNav http://launchpad.net/unav
 * Copyright (C) 2015-2016 Marcos Alvarez Costales https://launchpad.net/~costales
 *
 * uNav is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * uNav is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

function Maths() {
}

Maths.prototype.M2KM = 0.001;
Maths.prototype.M2MI = 0.000621371192;
Maths.prototype.M2YD = 1.0936133;
Maths.prototype.MS2KMH = 3.6;
Maths.prototype.KMH2MIH = 0.62137119223733;
Maths.prototype.KM = 'km';


Maths.prototype._toRad = function(deg) {
	 return deg * Math.PI / 180;
}

Maths.prototype._toDeg = function(rad) {
	return rad * 180 / Math.PI;
}

// Angle for rotating map
Maths.prototype.get_angle = function(lat_from, lng_from, lat_to, lng_to) {
	var dLon = this._toRad(lng_to-lng_from);
	var y = Math.sin(dLon) * Math.cos(this._toRad(lat_to));
	var x = Math.cos(this._toRad(lat_from))*Math.sin(this._toRad(lat_to)) - Math.sin(this._toRad(lat_from))*Math.cos(this._toRad(lat_to))*Math.cos(dLon);
	var brng = this._toDeg(Math.atan2(y, x));
	var brng_final = (-brng + 360) % 360;
	return this._toRad(brng_final);
}

Maths.prototype.speed2human = function(ms) {
	if (ms !== null)
		return parseInt(ms * this.MS2KMH);
	else
		return 0;
}

Maths.prototype.get_speed = function(kmh, unit) {
	if (unit == this.KM)
		return kmh.toFixed(0) + 'km/h';
	else
		return (kmh * this.KMH2MIH).toFixed(0) + 'mi/h';
}

Maths.prototype.time2human = function(seconds, time_arrive) {
	if (time_arrive) { // Show final hour when you arrive
		var timeObject = new Date();
		timeObject = new Date(timeObject.getTime() + 1000*seconds);
		var m = (timeObject.getMinutes() < 10 ? "0" : "") + timeObject.getMinutes();
		return (timeObject.getHours() + ':' + m);
	}
	
	if (seconds > 0) { // Show hours:minutes to arrive
		var h = parseInt(seconds / 3600);
		var m = parseInt((seconds % 3600) / 60);
		if (h == 0)
			if (m > 0)
				return (m.toString() + "min");
			else
				return (" < 1min");
		else
			return (h.toString() + 'h' + m.toString() + 'min');
	}
}

Maths.prototype.dist2human = function(m, unit2convert) {
	var value = 0;
	var unit = '';

	if (unit2convert == this.KM) {
		if (m > 999) {
			value = m * this.M2KM;	// return km
			unit = 'km';
		}
		else {
			value = m;				// return meters
			unit = 'm';
		}
	}
	else {
		value = m * this.M2YD;		// return yards
		unit = 'yd';
		if (value > 999) {
			value = m * this.M2MI;	// return milles
			unit = 'mi';
		}
	}
		
	return String(parseInt(value) + unit);
}

Maths.prototype.decode = function(encoded, lat1st) {
	var precision = 6;
	var len = encoded.length,
		index=0,
		lat=0,
		lng = 0,
		array = [];

	precision = Math.pow(10, -precision);

	while (index < len) {
		var b,
			shift = 0,
			result = 0;
		do {
			b = encoded.charCodeAt(index++) - 63;
			result |= (b & 0x1f) << shift;
			shift += 5;
		} while (b >= 0x20);
		var dlat = ((result & 1) ? ~(result >> 1) : (result >> 1));
		lat += dlat;
		shift = 0;
		result = 0;
		do {
			b = encoded.charCodeAt(index++) - 63;
			result |= (b & 0x1f) << shift;
			shift += 5;
		} while (b >= 0x20);
		var dlng = ((result & 1) ? ~(result >> 1) : (result >> 1));
		lng += dlng;
		if (lat1st)
			array.push( [lat * precision, lng * precision] );
		else
			array.push( [lng * precision, lat * precision] );
	}
	return array;
}
