/*
 * Tracers: users making traces and being traced
 * $Id: tracer.js,v 1.19 2005/10/21 21:59:17 just Exp $
 */
// Tracer static functions

var TRC = {
  // Array of N available colors, each in triples: N+0 (avail) N+1 (name) N+2 (colorcode)
  colors: [0, 'yellow', '#FFFF00', 0, 'green','#00EE00', 0, 'orange', '#FF9933', 0,'red','#CC0000',0, 'blue','#0066FF', 0,'purple','#FF66FF'],
  tracers: [],
  map: null,

  init: function(map) {
 	// Init server.js
    SRV.init();
    TRC.map = map;
  },

  // Create new Tracer object and put in tracers array
  createTracer: function(name, lon, lat, color) {
    // Find color
    // Always try username to find color first
    var colorIndex = 0;
    var lastFreeIndex = -1;
    while(true) {
        if (TRC.colors[colorIndex] == 0) {
          // remember last free index
          lastFreeIndex = colorIndex;

          // Check if name matches
          if (TRC.colors[colorIndex+1] == color) {
            // OK found, reserve color slot
     //       TRC.colors[colorIndex] = 1;
            break;
          }
        }

        // next triple
        colorIndex += 3;
        if (colorIndex >= TRC.colors.length) {
          // not found name
          colorIndex = -1;
          break;
        }
    }

    // If still not found use last free or default
    if (colorIndex == -1) {
       if (lastFreeIndex != -1) {
         colorIndex = lastFreeIndex;
        } else {
         colorIndex = 0; // take any
       }

       // reserve color slot
  //     TRC.colors[colorIndex] = 1;
    }

    var point;
    if (lon && lat) {
      point = new GPoint(lon, lat);
    }

    var iconURL = 'img/' + TRC.colors[colorIndex+1] + 'ball.gif';
    var box = DH.getObject(TRC.colors[colorIndex+1]);
    var tracer = new Tracer(name, box, TRC.colors[colorIndex+2], iconURL, point);
    TRC.tracers[name] = tracer;
    return tracer;
  },

   // Get tracer by name
  getTracer: function(name) {
    return TRC.tracers[name];
  },

  // Get tracers array
  getTracers: function() {
    return TRC.tracers;
  }
}

// Class representing GeoTracing user on Map.
function Tracer(name, box, color, iconURL, point) {
        this.name = name;
        this.color = color;
        this.box = box;
        this.activeTrack = null;
        this.point = point;
        this.iconURL = iconURL;
        this.tlabel = null;
		this.hidden = false;
		this.live = false;
		this.interv = null;
		if (this.point) {
		  this.setLocation(point);
        }
 }

  // Add a medium
  Tracer.prototype.addMedium = function (medium) {
    if (this.activeTrack != null) {
      this.activeTrack.addMedium(medium);
    }
  }

 // Add a POI
 /* Tracer.prototype.addPOI = function (poi) {
    if (this.activeTrack != null) {
      this.activeTrack.addPOI(poi);
    }
  }
*/
  // Delete a Track for id and name
  Tracer.prototype.deleteTrack = function (id, name) {
   if (this.activeTrack != null) {
     this.activeTrack.remove();
    }
	if (this.tlabel != null) {
		 GT.map.removeTLabel(this.tlabel);
    }
    this.activeTrack = null;
  }

  // Delete a Track for id and name
  Tracer.prototype.newTrack = function (id, name) {
  //   this.deleteTrack(id, name);
//  	alert(name);
     this.activeTrack =  new Track(id, name, this.color);
  }

  // Draw a Track by getting GPX file by (record) id
  Tracer.prototype.drawTrack = function (id) {
       // Need this for JS local scope in callback
	   var tracer = this;

	   // Define callback for async response
	   this.onGetTrackRsp = function (gtx) {
         // Get info
	     var infoElm = gtx.documentElement.getElementsByTagName('info')[0];
         var name = infoElm.getAttribute('name');
		 
         if (!name || name == null) {
           name = 'unnamed';
         }

         // Get points
		 /////MODDING FOR SEGMENTS...
		 var segments = gtx.documentElement.getElementsByTagName('seg');
	   //  var ptElements = segments[i].getElementsByTagName('pt');
		
	     // Go through all Track points, building up array of Points
		// var ptArr = [];
	     var nextPt;
		 var nextSeg;
	//	 alert(segments.length);
		 var segArray = new Array();
	     for (i = 0; i < segments.length; i++) {
			segArray[i] = new Array();
	    	nextSeg = segments[i]; // .getElementsByTagName('time')[0].childNodes[0].nodeValue;
	   		var ptElements = segments[i].getElementsByTagName('pt');
	     	for (var j = 0; j < ptElements.length; j++) {
	       		nextPt = ptElements[j]; // .getElementsByTagName('time')[0].childNodes[0].nodeValue;
					if(nextPt.getAttribute('speed') < 20 && nextPt.getAttribute('speed') > 0.1) {
	       				segArray[i].push(new GPoint(nextPt.getAttribute('lon'), nextPt.getAttribute('lat')));
					} 
	     		}
			 }		 
         // Get medium locations
	     var mediumElements = gtx.documentElement.getElementsByTagName('medium');
	     var media = [];
         if (mediumElements) {
           var nextMedium;
	       for (i = 0; i < mediumElements.length; i++) {
	         nextMedium = mediumElements[i];

	         // Create and draw location-based medium
	         medium = new Medium(nextMedium.getAttribute('id'),
	              nextMedium.getAttribute('name'),
	              nextMedium.getAttribute('kind'),
	              nextMedium.getAttribute('mime'),
	              nextMedium.getAttribute('time'),
	              tracer,
	              nextMedium.getAttribute('lon'),
	              nextMedium.getAttribute('lat'));
             media.push(medium);
	       }
         }
	     var pois = [];

         // Get POI locations
	 /*    var poiElements = gtx.documentElement.getElementsByTagName('poi');
         if (poiElements) {
           var nextPOI;
	       for (i = 0; i < poiElements.length; i++) {
	         nextPOI = poiElements[i];

	         // Create and draw location-based medium
	         poi = new POI(nextPOI.getAttribute('id'),
	              nextPOI.getAttribute('name'),
	              nextPOI.getAttribute('type'),
	              nextPOI.getAttribute('time'),
	              tracer,
	              nextPOI.getAttribute('lon'),
	              nextPOI.getAttribute('lat'));
                  pois.push(poi);
	       }
         }
*/
	     tracer.activeTrack = new Track(id, name, tracer.color, segArray, media, pois);
         tracer.activeTrack.draw();
	     // Show Tracer at last point of Track
		 /////NOG VERANDEREN VOOR SEGMENTEN !!!!!!!!!!!!!!!!!!!!!!!
		 var ptArray = segArray[segArray.length-1];
		 if (segArray.length > 0) { tracer.tlabel.setPosition(ptArray[ptArray.length-1]);}
	   }

	   // Get GTX document by id from server
	   SRV.get('get-track', this.onGetTrackRsp, 'id', id, 'format', 'gtx', 'attrs', 'lon,lat,t,speed');
	}

	// Set Tracer at lon/lat location
	Tracer.prototype.setLocation = function(point) {
		// Always last location
		this.point = point;

        if (this.tlabel == null) {

		  this.iconId = 'icon' + this.name;

		  var html = '<span class="tracer"><img id="' + this.iconId + '" src="' + this.iconURL + '" border="0" />&nbsp;<span class="tracername">' + this.name + '</span></span>';

		  // Setup TLabel object
		  tl = new TLabel();
          tl.id = 'tlab' + this.name;
          tl.anchorLatLng = this.point;
          tl.anchorPoint = 'topLeft';
          tl.content = html;

          // To shift icon on exact lat/lon location (half size of icon)
          tl.markerOffset = new GSize(5, 5);

          // Add Tlabel to map
          TRC.map.addTLabel(tl);
          this.tlabel = tl;
        } else {
	      // Only Move TLabel
 		  this.tlabel.setPosition(this.point);
        }
	}

	// Move Tracer to lon/lat location
	Tracer.prototype.move = function(lon, lat) {

	    // replace point
		var point = new GPoint(lon, lat);
		// Move TLabel
 		this.setLocation(point);
 		if (this.activeTrack != null) {
 		  this.activeTrack.addPoint(point);
 		}
	}

	// Setting the visibility to visible
	Tracer.prototype.show = function() {
		DH.show(this.tlabel.id);
	}

	// Setting the visibility to hidden
	Tracer.prototype.hide = function() {
		DH.hide(this.tlabel.id);
	}

    // Is Tracer live
	Tracer.prototype.isLive = function() {
		return this.live;
	}

	// Set Tracer live
    Tracer.prototype.setLive = function() {
		if (this.live == true) {
			return;
		}
		this.live = true;
    	this.interv = setInterval(this.blink,300,this);
	}

	// The continuous blinking
	Tracer.prototype.blink = function(t) {
		if(t) { DH.toggleVisibility(t.iconId);}
	}

// Track
function Track(id, name, color, points, media, pois) {
  this.id = id;
  this.name = name;
  this.color = color;
  this.points = [];
  this.media = [];
  this.pois = [];
  this.livePoints = [];

  if (points) {
    this.points = points;
  }

  if (media) {
    this.media = media;
  }

  if (pois) {
    this.pois = pois;
  }

  this.polyLines = [];
}
// Add medium to this tracer
Track.prototype.addPoint = function (aPoint) {
  var ptArr = [];
  ptArr[0] = null;

  // Prev point is either a live point or from track
  if (this.livePoints.length > 0) {
    ptArr[0] = this.livePoints[this.livePoints.length-1];
  } else if (this.points.length > 0) {
	var pointArray =  this.points[this.points.length-1];
    ptArr[0] = pointArray[pointArray.length -1];
  }

  // Only draw line if we have a previous point
  if (ptArr[0] != null) {
     ptArr[1] = aPoint;
	 var pl = new GPolyline(ptArr, this.color, 1, 0.80);
	 TRC.map.addOverlay(pl);
	 this.polyLines.push(pl);
  }

  // Remember
  this.livePoints.push(aPoint);
}

// Add medium to this tracer
Track.prototype.addMedium = function (medium) {
  this.media[medium.id] = medium;
  medium.show();
}

// Add medium to this tracer
Track.prototype.addPOI = function (poi) {
  this.pois[poi.id] = poi;
  poi.show();
}

// Drawin view
Track.prototype.draw = function () {
  // Draw the entire Track on map
  for(var i = 0; i< this.points.length; i++) {
  		var pointArray = this.points[i];	  
  		var pl= new GPolyline(pointArray, this.color, 1, 0.80);
  		TRC.map.addOverlay(pl);
  		this.polyLines.push(pl);
  	}
    for (var i=0; i < this.media.length; i++) {
    this.media[i].show();
  }

  for (var i=0; i < this.pois.length; i++) {
    this.pois[i].show();
  	}
}

// remove from view
Track.prototype.remove = function () {
  for (var i=0; i < this.polyLines.length; i++) {
    TRC.map.removeOverlay(this.polyLines[i]);
  }

  for (var i=0; i < this.media.length; i++) {
    if (this.media[i]) {
      this.media[i].remove();
    }
  }

  for (var i=0; i < this.pois.length; i++) {
    if (this.pois[i]) {
      this.pois[i].remove();
    }
  }

  this.polyLines = [];
  this.points = [];
  this.livePoints = [];
  this.media = [];
  this.pois = [];
}

// Location-based medium
function Medium(id, name, kind, mime, time, tracer, lon, lat) {
  this.id = id;
  this.name = name;
  this.kind = kind;
  this.mime = mime;
  this.time = new Number(time); // somehow needed
  this.lon = lon;
  this.lat = lat;
  this.tracer = tracer;
  this.url = '/gt/media.srv?id=' + this.id;
  this.tlabel = null;
}

Medium.prototype.show = function() {
    var mediumId = this.id;
    this.display();
    if (!this.lon && !this.lat) {
      return;
    }

    var tl = new TLabel();
    tl.id = 'med' + mediumId;
    var pt = new GPoint(this.lon, this.lat);
    tl.anchorLatLng = pt;
    tl.anchorPoint = 'center';
    var divId = 'medicon' + mediumId;

    tl.content = '<div class="medicon" id="' + divId + '" style="background-color:' + this.tracer.color + ';" >&nbsp;&nbsp;&nbsp;&nbsp;</div>';

    // Add Tlabel to map
    TRC.map.addTLabel(tl);

    this.tlabel = tl;

    // Add extra attributes so callback can figure out the medium and tracer
    var obj = DH.getObject(divId);

    var medium = this;

	// Define callback for mouse over medium icon
	this.onMouseOverIcon = function (e) {
       medium.display();
       DH.cancelEvent(e);
    }

    DH.addEvent(obj, 'mouseover', this.onMouseOverIcon, false);
}

Medium.prototype.getTitle = function() {
	var date = new Date(this.time);
	return this.name + ' [' + this.kind + '/' + this.id + '] - ' + date.format("DDD D MMMM YYYY HH:mm:ss");
}

Medium.prototype.display = function() {
	var currentTile = document.getElementById('tile6');
	var handlers = currentTile.getElementsByTagName('div');
	for(var i =0; i< handlers.length; i++) {
		if(handlers[i].className == 'handler') { var handler = handlers[i];}	
	}
	var colors = new Array (0, 'yellow', '#FFFF00', 0, 'green','#00EE00', 0, 'orange', '#FF9933', 0,'red','#CC0000',0, 'blue','#0066FF', 0,'purple','#FF66FF');
	for(var j = 0; j < colors.length; j++) {
		if(this.tracer.color == colors[j]) { var c = colors[j-1]; } 
	}
	//handler.innerHTML = '<img src=img/handler_'+c+'.gif />';
    var src;
	var vid;
	openTile('tile6', 196,200, false);
	handler.style.backgroundImage = 'url("img/handler_'+c+'.gif")';
    if (this.kind == 'video') { ///IF VIDEO
		(navigator.userAgent.toLowerCase().indexOf('mac') != -1) ? vid = '<OBJECT CLASSID="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" WIDTH="176" HEIGHT="154" CODEBASE="http://www.apple.com/qtactivex/qtplugin.cab" align="left"><PARAM name="SRC" VALUE="' + this.url + '"><PARAM name="AUTOPLAY" VALUE="true"><PARAM NAME="type" VALUE="video/quicktime"><PARAM name="CONTROLLER" VALUE="true"><EMBED SRC="' + this.url + '" WIDTH="176" HEIGHT="154" AUTOPLAY="true" CONTROLLER="false" LOOP="true" type="video/quicktime" PLUGINSPAGE="http://www.apple.com/quicktime/download/"></EMBED></OBJECT>' : vid = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" align="left"><param name="movie" value="'+this.url+'&format=swf"><param name="quality" value="high"><param name="bgcolor" value="#ffffff"><param name="loop" value="true"><embed src="'+this.url+'&format=swf" quality="high" bgcolor="#ffffff" loop="true" type="application/x-shockwave-flash"pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?p1_prod_version=shockwaveflash"></embed></object>';
		document.getElementById('media').innerHTML = vid;
    } else { /// IF IMAGE
	////OPEN TILE FOR MEDIA DISPLAY
//    var img = '<img title="' + this.getTitle() + '" src="' + src + '" border="0" width="160" height="120">';
//    this.tracer.box.innerHTML = img
	var src = this.url + '&resize=176';
	var img = '<img title="' + this.getTitle() + '" src="' + src + '" border="0" width="176" align="left">';
	document.getElementById('media').innerHTML = img;
	}
}

Medium.prototype.remove = function() {
  if (this.tlabel == null) {
    return;
  }
  // remove Tlabel from map
  TRC.map.removeTLabel(this.tlabel);
  	this.tlabel = null;
}

// Location-based Point Of Interest (e.g. bomb)
/*function POI(id, name, type, time, tracer, lon, lat) {
  this.id = id;
  this.name = name;
  this.type = type;
  this.time = new Number(time); // somehow needed
  this.lon = lon;
  this.lat = lat;
  this.tracer = tracer;
  this.tlabel = null;
}

POI.prototype.show = function() {
    var id = this.id;
    var tl = new TLabel();
    tl.id = 'poi' + id;
    var pt = new GPoint(this.lon, this.lat);
    tl.anchorLatLng = pt;
    tl.anchorPoint = 'center';
    var divId = 'poiicon' + id;
    var src = 'img/poi' + this.type +'.gif';
    var img = '<img title="' + this.getTitle() + '" src="' + src + '" border="0" width="18" height="18" >';

    tl.content = '<div class="poiicon" id="' + divId + '" style="border: 1px solid ' + this.tracer.color + ';" >' + img + '</div>';

    // Add Tlabel to map
    TRC.map.addTLabel(tl);

    this.tlabel = tl;
}

POI.prototype.getTitle = function() {
	var date = new Date(this.time);
	//date.setMilliseconds(1129546161194);
	//1129544318296
	// alert('t=' + this.time + ' day=' + d.getDay());
	return this.name + ' [' + this.type + '/' + this.id + '] - ' + date.format("DDD D MMMM YYYY HH:mm:ss");
}


POI.prototype.remove = function() {
  if (this.tlabel == null) {
    return;
  }
  // remove Tlabel from map
  TRC.map.removeTLabel(this.tlabel);

  this.tlabel = null;
}


/*
 * DateFormat.js
 * Formats a Date object into a human-readable string
 * See http://www.gazingus.org/html/Date_Formatting_Function.html
 *
 * Copyright (C) 2001 David A. Lindquist (http://www.gazingus.org)
 */

Date.MONTHS = [
  'January', 'February', 'March', 'April', 'May', 'June', 'July',
  'August', 'September', 'October', 'November', 'December'
];

Date.DAYS = [
  'Sunday', 'Monday', 'Tuesday', 'Wednesday',
  'Thursday', 'Friday', 'Saturday'
];

Date.SUFFIXES = [
  'st','nd','rd','th','th','th','th','th','th','th',
  'th','th','th','th','th','th','th','th','th','th',
  'st','nd','rd','th','th','th','th','th','th','th',
  'st'
];

Date.prototype.format = function( mask ) {
  var formatted     = ( mask != null ) ? mask : 'DD-MMM-YY';
  var letters       = 'DMYHdhmst'.split( '' );
  var temp          = new Array();
  var count         = 0;
  var regexA;
  var regexB        = /\[(\d+)\]/;

  var day           = this.getDay();
  var date          = this.getDate();
  var month         = this.getMonth();
  var year          = this.getFullYear().toString();
  var hours         = this.getHours();
  var minutes       = this.getMinutes();
  var seconds       = this.getSeconds();
  var formats       = new Object();
  formats[ 'D' ]    = date;
  formats[ 'd' ]    = date + Date.SUFFIXES[ date - 1 ];
  formats[ 'DD' ]   = ( date < 10 ) ? '0' + date : date;
  formats[ 'DDD' ]  = Date.DAYS[ day ].substring( 0, 3 );
  formats[ 'DDDD' ] = Date.DAYS[ day ];
  formats[ 'M' ]    = month + 1;
  formats[ 'MM' ]   = ( month + 1 < 10 ) ? '0' + ( month + 1 ) : month + 1;
  formats[ 'MMM' ]  = Date.MONTHS[ month ].substring( 0, 3 );
  formats[ 'MMMM' ] = Date.MONTHS[ month ];
  formats[ 'Y' ]    = ( year.charAt( 2 ) == '0' ) ? year.charAt( 3 ) : year.substring( 2, 4 );
  formats[ 'YY' ]   = year.substring( 2, 4 );
  formats[ 'YYYY' ] = year;
  formats[ 'H' ]    = hours;
  formats[ 'HH' ]   = ( hours < 10 ) ? '0' + hours : hours;
  formats[ 'h' ]    = ( hours > 12 || hours == 0 ) ? Math.abs( hours - 12 ) : hours;
  formats[ 'hh' ]   = ( formats[ 'h' ] < 10 ) ? '0' + formats[ 'h' ] : formats[ 'h' ];
  formats[ 'm' ]    = minutes;
  formats[ 'mm' ]   = ( minutes < 10 ) ? '0' + minutes : minutes;
  formats[ 's' ]    = seconds;
  formats[ 'ss' ]   = ( seconds < 10 ) ? '0' + seconds : seconds;
  formats[ 't' ]    = ( hours < 12 ) ?  'A' : 'P';
  formats[ 'tt' ]   = ( hours < 12 ) ?  'AM' : 'PM';

  for ( var i = 0; i < letters.length; i++ ) {
    regexA = new RegExp( '(' + letters[ i ] + '+)' );
    while ( regexA.test( formatted ) ) {
      temp[ count ] = RegExp.$1;
      formatted = formatted.replace( RegExp.$1, '[' + count + ']' );
      count++;
    }
  }

  while ( regexB.test( formatted ) ) {
    formatted = formatted.replace( regexB, formats[ temp[ RegExp.$1 ] ] );
  }

  return formatted;
}


