package pokus.sd;

//konverze a prevody mezi souradnicemi
public class Conversion {
	
	public int getDegrees(double coordinate) {
		return (int) Math.floor(coordinate);
	}
	
	public int getMinutes(double coordinate) {
		return (int) Math.floor((coordinate - (double) getDegrees(coordinate))*60);
	}
	
	public int getSeconds(double coordinate) {
		double min;
		int sec;
		min= ((coordinate - Math.floor(coordinate))*60);
		sec = (int) Math.floor((min - Math.floor(min))*60);
		return sec;
	}
	
	public double convert(double deg, double min, double sec, char quarter) {	
		switch (quarter) {
			//case 'N': deg = deg; break;
			case 'S': deg = -deg; break;	
			case 'W': deg = -deg; break;
			//case 'E': deg = deg; break;
			default: break;
		}
		return (deg + min/60.0d + sec/3600.0d);
	}
	
	public double rad2deg(double rad) {
		return (180/Math.PI)*rad;
	}
	
	public double deg2rad(double deg) {
		return (Math.PI/180)*deg;
	}
	
	public double getDistance(double lat1, double lng1, double lat2, double lng2) {
	    double earthRadius = 6371100;	//m
	    //ortodroma
	    return Math.acos(
	    		Math.cos(deg2rad(lat1))*Math.cos(deg2rad(lng1))*Math.cos(deg2rad(lat2))*Math.cos(deg2rad(lng2))
	        + Math.cos(deg2rad(lat1))*Math.sin(deg2rad(lng1))*Math.cos(deg2rad(lat2))*Math.sin(deg2rad(lng2))
	        + Math.sin(deg2rad(lat1))*Math.sin(deg2rad(lat2))
	    ) * earthRadius;		
	}
	
	public double getDistance(Landmark A, Landmark B) {
	    double earthRadius = 6371100;	//m	
	    double lat1 = A.getLatitude();
	    double lng1 = A.getLongitude();
	    double lat2 = B.getLatitude();
	    double lng2 = B.getLongitude();
	    return Math.acos(
	    		Math.cos(deg2rad(lat1))*Math.cos(deg2rad(lng1))*Math.cos(deg2rad(lat2))*Math.cos(deg2rad(lng2))
	        + Math.cos(deg2rad(lat1))*Math.sin(deg2rad(lng1))*Math.cos(deg2rad(lat2))*Math.sin(deg2rad(lng2))
	        + Math.sin(deg2rad(lat1))*Math.sin(deg2rad(lat2))
	    ) * earthRadius;

	}
	
	public double getDistance2(double lat1, double lng1, double lat2, double lng2) {
	    lat1 = lat1*(Math.PI/180);
	    lng1 = lng1*(Math.PI/180);
	    lat2 = lat2*(Math.PI/180);
	    lng2 = lng2*(Math.PI/180);
	    
		double a = 6378137.0, b = 6356752.3142;
		double f = 1/298.257223563;	//flattening
		double L = Math.abs(lng1 - lng2);
		double u1 = Math.atan((1-f)*Math.tan(lat1));
		double u2 = Math.atan((1-f)*Math.tan(lat2));
		double sinSigma=0, cosSigma=0, sigma=0, sinAlfa=0, cosSquareAlfa=0, cos2sigmaM=0, c=0, uSquare=0;
		double lambda = L, lambda2 = Math.PI*2;
		int i=0;
		
		while(Math.abs(lambda-lambda2) > Math.pow(10, -12) && i++<20) {
			sinSigma = Math.sqrt(Math.cos(u2)*Math.sin(lambda)*Math.cos(u2)*Math.sin(lambda) + 
					(Math.cos(u1)*Math.sin(u2) - Math.sin(u1)*Math.cos(u2)*Math.cos(lambda))*
					(Math.cos(u1)*Math.sin(u2) - Math.sin(u1)*Math.cos(u2)*Math.cos(lambda)));
			cosSigma = Math.sin(u1)*Math.sin(u2) + Math.cos(u1)*Math.cos(u2)*Math.cos(lambda);
			sigma = Math.atan2(sinSigma, cosSigma);
			sinAlfa = (Math.cos(u1)*Math.cos(u2)*Math.sin(lambda))/sinSigma;
			cosSquareAlfa = 1 - sinAlfa*sinAlfa;
			cos2sigmaM = cosSigma - (2*Math.sin(u1)*Math.sin(u2))/cosSquareAlfa;
			c = f/(16*cosSquareAlfa*(4 + f*(4 - 3*cosSquareAlfa)));
			lambda2 = lambda;
			lambda = L + (1 - c)*f*sinAlfa*(sigma + c*sinSigma*(cos2sigmaM + c*cosSigma*(-1 + 2*cos2sigmaM*cos2sigmaM)));
		}
		uSquare = (cosSquareAlfa*(a*a - b*b))/(b*b);
		double aa = 1 + (uSquare/16384)*(4096 + uSquare*(-768 + uSquare*(320 - 175*uSquare)));
		double bb = (uSquare/1024)*(256 + uSquare*(-128 + uSquare*(74 - 47*uSquare)));
		double deltaSigma = bb*sinSigma*(cos2sigmaM + (bb/4)*(cosSigma*(-1 + 2*cos2sigmaM*cos2sigmaM) - (bb/6)*cos2sigmaM*(-3 + 4*sinSigma*sinSigma)*(-3 + 4*cos2sigmaM*cos2sigmaM)));
		double s = b*aa*(sigma - deltaSigma);
		
		return s;
	}
	
	public double getDistance2(Landmark A, Landmark B) {
	    double lat1 = A.getLatitude()*(Math.PI/180);
	    double lng1 = A.getLongitude()*(Math.PI/180);
	    double lat2 = B.getLatitude()*(Math.PI/180);
	    double lng2 = B.getLongitude()*(Math.PI/180);
	    
		double a = 6378137.0, b = 6356752.3142;
		double f = 1/298.257223563;	//flattening
		double L = Math.abs(lng1 - lng2);
		double u1 = Math.atan((1-f)*Math.tan(lat1));
		double u2 = Math.atan((1-f)*Math.tan(lat2));
		double sinSigma=0, cosSigma=0, sigma=0, sinAlfa=0, cosSquareAlfa=0, cos2sigmaM=0, c=0, uSquare=0;
		double lambda = L, lambda2 = Math.PI*2;
		int i=0;
		
		while(Math.abs(lambda-lambda2) > Math.pow(10, -12) && i++<20) {
			sinSigma = Math.sqrt(Math.cos(u2)*Math.sin(lambda)*Math.cos(u2)*Math.sin(lambda) + 
					(Math.cos(u1)*Math.sin(u2) - Math.sin(u1)*Math.cos(u2)*Math.cos(lambda))*
					(Math.cos(u1)*Math.sin(u2) - Math.sin(u1)*Math.cos(u2)*Math.cos(lambda)));
			cosSigma = Math.sin(u1)*Math.sin(u2) + Math.cos(u1)*Math.cos(u2)*Math.cos(lambda);
			sigma = Math.atan2(sinSigma, cosSigma);
			sinAlfa = (Math.cos(u1)*Math.cos(u2)*Math.sin(lambda))/sinSigma;
			cosSquareAlfa = 1 - sinAlfa*sinAlfa;
			cos2sigmaM = cosSigma - (2*Math.sin(u1)*Math.sin(u2))/cosSquareAlfa;
			c = f/(16*cosSquareAlfa*(4 + f*(4 - 3*cosSquareAlfa)));
			lambda2 = lambda;
			lambda = L + (1 - c)*f*sinAlfa*(sigma + c*sinSigma*(cos2sigmaM + c*cosSigma*(-1 + 2*cos2sigmaM*cos2sigmaM)));
		}
		uSquare = (cosSquareAlfa*(a*a - b*b))/(b*b);
		double aa = 1 + (uSquare/16384)*(4096 + uSquare*(-768 + uSquare*(320 - 175*uSquare)));
		double bb = (uSquare/1024)*(256 + uSquare*(-128 + uSquare*(74 - 47*uSquare)));
		double deltaSigma = bb*sinSigma*(cos2sigmaM + (bb/4)*(cosSigma*(-1 + 2*cos2sigmaM*cos2sigmaM) - (bb/6)*cos2sigmaM*(-3 + 4*sinSigma*sinSigma)*(-3 + 4*cos2sigmaM*cos2sigmaM)));
		double s = b*aa*(sigma - deltaSigma);
		
		return s;
	}

}
