// JavaScript Document

function AbsGpsTrack(json)
{
	this.trackpoints;	
	this.trackpoints = new Array();
	this.profile;
	this.alpha = ""; //ff
	this.colors = new Array();
	this.colors["1"] = "#c2c2c2";
	this.colors["2"] = "#646567";
	this.colors["3"] = "#6a8914";
	this.colors["4"] = "#9fc20a";
	this.colors["5"] = "#cee12f";
	this.colors["6"] = "#dfe6a0"; 
	this.colors["7"] = "#c8e9f8";
	this.colors[null]= '#c2c2c2';
	
	this.minEle;
	this.minEle = 10000;
	this.maxEle;
	this.maxEle = -10000;
	this.distance;
	this.profile;
	this.anz_preview = 200;
	
	this.EAST = -180;
	this.WEST =  180;
	this.NORTH = -90;
	this.SOUTH = 90;
	
	this.readJson(json);
}

AbsGpsTrack.prototype.getUG = function (ug)
{
	return this.colors[ug];	
}

AbsGpsTrack.prototype.getTrackpoints = function()
{
	return this.trackpoints;
}

AbsGpsTrack.prototype.addTrackpoint = function(tp)
{
	this.trackpoints.push(tp);	
}

AbsGpsTrack.prototype.getTrackpointAt = function(i)
{
	return this.trackpoints[i];	
}

AbsGpsTrack.prototype.getMinEle = function(){return this.minEle;}
AbsGpsTrack.prototype.getMaxEle = function(){return this.maxEle;}
AbsGpsTrack.prototype.getEAST = function(){return this.EAST;}
AbsGpsTrack.prototype.getWEST = function(){return this.WEST;}
AbsGpsTrack.prototype.getNORTH = function(){return this.NORTH;}
AbsGpsTrack.prototype.getSOUTH = function(){return this.SOUTH;}
AbsGpsTrack.prototype.getCenter = function(){
	return new AbsGpsTrackpoint( (this.NORTH+this.SOUTH)/2, (this.EAST+this.WEST)/2 );	
}
	

AbsGpsTrack.prototype.readJson = function(json)
{
	var i=0;
	var dis = 0;
	var pretp;
	var head = 0;
	var anst = 0;
	
	var a = new Array();
		
	for (var i = 0; i < json.length; i++)
	{

		var lat = json[i][0];
		var lon = json[i][1];
		var ele = json[i][2];
		var ug  = json[i][3];
		
		lat = lat*10/10;
		lon = lon*10/10;
		ele = ele*10/10;
		
		if(ele > this.maxEle)
			this.maxEle = ele;
		if(ele < this.minEle)
			this.minEle = ele;
		if(lat > this.NORTH)
			this.NORTH = lat;
		if(lat < this.SOUTH)
			this.SOUTH = lat;
		if(lon > this.EAST)
			this.EAST = lon;
		if(lon < this.WEST)
			this.WEST = lon;
		
		if(i==0)
			dis = 0;
		else
		{
			dis = dis + getDistance(pretp.lat, pretp.lon, lat, lon);
		}
		
		var tp = new AbsGpsTrackpoint(lat, lon, ele, ug, dis);
				
		pretp = tp;
		a.push(tp);
	}
	
	for(i=0;i<a.length;i++)
	{
		if(i<a.length-1)
		{
			var tp = a[i];
			var tppos = a[i+1];
			
			head = getAngle(tppos.lat, tppos.lon, tp.lat, tp.lon);	
			anst = getAnstieg(tppos.lat, tppos.lon, tppos.ele, tp.lat, tp.lon, tp.ele);
		}
		a[i].anst = anst;
		a[i].head = head;
	}
	
	this.trackpoints = a;
	this.distance = dis;
	
}

AbsGpsTrack.prototype.getHeightProfile = function(w, update, onlyView)
{
	if(update == null)
		update = true;
	if(onlyView == null)
		onlyView = false;
	
	if(update)
	{
		// Gesamtstreckenlänge aktualisieren
		this.updateDistance();
		// Laufvariablen
		var n = 0, i = 0;
		// Temporäres Array
		var tempProfile = new Array();
		// Gesamtstreckenlänge lesen
		// Variable zur Teilstreckenberechnung
		var disTemp = 0;
		// Zwei aufeinander folgende Punkte
		var p1 = this.getTPat(0);
		var p2 = this.getTPat(0);
		
		var test = 0;
		// Schleife für alle Punkte
		while(n<=w-2)
		{
			test++;
			// Erechnete Teilstrecke
			var lengthAt = (this.distance/w)*n;
			// solang Teilstrecke kleiner ist, werden Punkte hinzugenommen
			while(disTemp<lengthAt)
			{	
				// Punkte lesen
				p1 = this.getTPat(i);
				p2 = this.getTPat(i+1);
				try{
				// Strecke zwischen den Punkten berechnen
				var dis = getDistance(p1.lat, p1.lon ,p2.lat, p2.lon);
				}
				catch(e)
				{
					
				}
				// Zum Teilstück addieren
				disTemp = disTemp + dis;
				// Laufvariable
				i = i + 1;
			} 
			// Wenn Teilstrecke lang genug ist Distanzinformation in Punkt schreiben
			try{
			p1.dis = disTemp;
			// Originalindexinformation setzen
			p1.trackIndex = i;
			// Kopie des Trackpoints hinzufügen
			tempProfile.push(p1);
			}
			catch(e)
			{}	
			// Nächste Teilstrecke berechnen					
			n++;	
		}
		// Zielpunkt hinzufügen
		p1 = this.getTPat(this.trackpoints.length-1);
		p1.trackIndex = this.trackpoints.length -1;
		p1.dis = this.distance;
		tempProfile[w-1] = p1;
		
		// Profil glätten
		tempProfile = this.profilGlatten(tempProfile);
		tempProfile = this.profilGlatten(tempProfile);
		
			
		// Profil ausgeben	
		
		if(!onlyView)
			this.profile = tempProfile;			
		else
			return tempProfile;
		
	}
	
	return this.profile;	
}

AbsGpsTrack.prototype.updateDistance = function()
{
	var length = 0;
	
	for(var n = 0; n<this.trackpoints.length-1;n++)
	{
		var p1 = this.trackpoints[n];
		var p2 = this.trackpoints[n+1];
		
		var dis = getDistance(p1,p2);
		length = length+dis;				
	}
	
	distance = length;
}

AbsGpsTrack.prototype.getTPat = function(n)
{
	if(n>=this.trackpoints.length)
		n = this.trackpoints.length-1
	if(n<0)
		n=0
	var wp = this.trackpoints[n];
	return wp;
}

AbsGpsTrack.prototype.profilGlatten = function(profile)
{
	var g = 7;
	var sum;
	var p;
	var n, i;

	for(var b=0;b<4;b++)
	for(n = 1; n<= profile.length-2; n++)
	{
		if(n<=3)
			g = 2*n+1;
		else if(n>profile.length-4)
			g = (profile.length-n-1)*2+1;
		else
			g=7;
		
		sum = 0;		
		for(i = n-(g-1)/2; i<= n+(g-1)/2;i++)
		{	
			sum = sum + profile[i].ele;
		}				
		p = profile[n];
		p.ele = sum / g;
		profile[n] = p;			
	}	
		
	return profile;		
}


function AbsGpsTrackpoint(lat, lon, ele, ug, dis)
{
	this.lat = lat;
	this.lon = lon;
	this.ele = ele;
	this.ug = ug;
	this.dis = dis;
	this.head;
	this.anst;
	
}

AbsGpsTrackpoint.prototype.clone = function()
{
	return new AbsGpsTrackpoint(this.lat, this.lon, this.ele, this.ug, this.dis);	
}

function getDistance(lat1, lon1, lat2, lon2)
{
	lat = (lat1 + lat2)/2 * 0.01745;
	dx  = 111.3 * Math.cos(lat)*(lon2-lon1);
	dy  = 111.3 * (lat2 - lat1);
	
	return Math.sqrt(dx*dx + dy*dy);
}

function getAngle(lat1, lon1, lat2, lon2)
{
	lat = (lat1 + lat2)/2 * 0.01745;
	dx  = 111.3 * Math.cos(lat)*(lon2-lon1);
	dy  = 111.3 * (lat2 - lat1);
	
	angle = 180/Math.PI*Math.atan2(dx,dy);
	
	return angle;
}

function getAnstieg(lat1, lon1, ele1, lat2, lon2, ele2)
{
	lat = (lat1 + lat2)/2 * 0.01745;
	dx  = 111.3 * Math.cos(lat)*(lon2-lon1);
	dy  = 111.3 * (lat2 - lat1);
	
	dis = Math.sqrt(dx*dx + dy*dy);
	eledif = ele2-ele1;
	
	angle = Math.atan(eledif/dis);
	
	return angle;
}
