// 2 object in this file: VCRControl GControl to scroll thru years & the ScoreGMap to wrap GMap
function VCRControl(scoreGMap) {
	this._scoreGMap = scoreGMap;
}
VCRControl.prototype = new GControl();
VCRControl.prototype._scoreGMap = null;
VCRControl.prototype.plotYear = function(year){
	with(this){
		_scoreGMap.plotScores(year);
		setText(_scoreGMap.yearLabel, year);
	}
}
VCRControl.prototype.initialize = function(map) {
	with (this){
		var container = document.createElement('div');
		container.style.backgroundColor = 'white';
		container.style.border = 'solid 1px black';
		container.style.padding = '3px';
		container.appendChild(document.createTextNode('Year '));

		var yrContainer = document.createElement('span');
		yrContainer.style.fontWeight = 'bold';
		yrContainer.style.margin = '3px';
		container.appendChild(yrContainer);
		_scoreGMap.yearLabel = document.createTextNode(' ');
		yrContainer.appendChild(_scoreGMap.yearLabel);
		{
			var startBtn = document.createElement('input');
			styleButton(startBtn, 'First');
			container.appendChild(startBtn);
			GEvent.addDomListener(startBtn, 'click', function() {
				_scoreGMap.setPlayMode('Stop');
				plotYear(_scoreGMap.minYear);
			});
		}{
			var playPauseBtn = document.createElement('input');
			styleButton(playPauseBtn, '_PLAY_');
			playPauseBtn.style.width = '4em';
			_scoreGMap.playPauseButton = playPauseBtn;
			_scoreGMap.setPlayMode('Stop');
			container.appendChild(playPauseBtn);

			GEvent.addDomListener(playPauseBtn, 'click', function() {
				_scoreGMap.setPlayMode(getText(playPauseBtn));
			});
		}{
			var endBtn = document.createElement('input');
			styleButton(endBtn, 'Last');
			container.appendChild(endBtn);
			GEvent.addDomListener(endBtn, 'click', function() {
				_scoreGMap.setPlayMode('Stop');
				plotYear(_scoreGMap.maxYear);
			});
		}
		map.getContainer().appendChild(container);
		return container;
	}
}
VCRControl.prototype.getDefaultPosition = function() {
	return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(150, 7));
}
VCRControl.prototype.styleButton = function(btn, text) {
	btn.style.margin = '2px';
	btn.type = 'button';
	btn.className = 'smallButton';
	btn.value = text;
}

//=== The GMap Wrapper ==========================

function ScoreGMap(gmapToWrap, title, qs, canPlayByYear, bounds){
	var me = this;
	var _bounds = bounds;
	var _smallMapWidthThreshold = 500;
	var _scores;
	var _markersByYears;
	var _canPlayByYear = canPlayByYear;
	var _activeYear;
	var _gmap = gmapToWrap;
	var _zoomLevel      = readCookie('map_zoomLevel')       || 8;
	var _ctrLat         = readCookie('map_ctrLat')          || 47.525;
	var _ctrLng         = readCookie('map_ctrLng')          || -122.15;
	var _mapTypeUrlArg  = readCookie('map_mapTypeUrlArg')   || 'p';
	var _scoresLength = 0;      // for perf. (didn't help much)
	var _qs = '?' + (qs.length == 0 ? '' : qs + '&');

	var fitMap = function(){
		with(this){
			_gmap.setCenter(bounds.getCenter());
			_gmap.setZoom(_gmap.getBoundsZoomLevel(_bounds));
		}
	};

	var getMapTypeFromUrlArg = function(urlArg){
		switch(urlArg){
			case 'm' : return G_NORMAL_MAP;
			case 'k' : return G_SATELLITE_MAP;
			case 'h' : return G_HYBRID_MAP;
			case 'p' : return G_PHYSICAL_MAP;
			default:   return G_PHYSICAL_MAP;
		}
	};

	function getIconSize(score){
		with(this){
			var sz = +_zoomLevel;
			sz += ((score.Ag + 3) / 5);
			return sz;
		}
	};

	var getYearKey = function(year){
		return 'Year' + year;
	};

	// PUBLICS
	this.title = title;
	this.minYear = 0; // must init yrs - show min first in vcr ctl.
	this.maxYear = 0;
	this.htmlForInfoWindows = [];
	this.yearLabel = null;
	this.playPauseButton = null;

	this.getQS = function(){
		return _qs;
	}
	this.getYear = function(score){
		return score.DT.match( /(?:\d{1,2}\/\d{1,2}\/)(\d+)/ )[1];
	}

	this.preserve = function(){
		with(this){
			if(_markersByYears){
				var yrFromNow = new Date();
				yrFromNow.setTime(yrFromNow.getTime() + 31536000000);
				document.cookie = 'map_zoomLevel=' + _zoomLevel + ';expires=' + yrFromNow;
				document.cookie = 'map_ctrLat=' + _ctrLat + ';expires=' + yrFromNow;
				document.cookie = 'map_ctrLng=' + _ctrLng + ';expires=' + yrFromNow;
				document.cookie = 'map_mapTypeUrlArg=' + _mapTypeUrlArg + ';expires=' + yrFromNow;
			}
		}
	};

	this.getGIcon = function(score){
		var rank = new Rank(score.Rk);
		var icon = new GIcon();
		icon.image = rank.getIconRef(score.F);
		var d = getIconSize(score);
		icon.iconSize = new GSize(d,d);
		icon.iconAnchor = new GPoint(1, 1);
		icon.infoWindowAnchor = new GPoint(5, 1);
		return icon;
	};

	this.getGMarker = function(score, hide){
		with(this){
			var marker = new GMarker(
				new GLatLng(score.Lat, score.Lng),
				{   icon: getGIcon(score),
					hide: hide
				}
			);

			GEvent.addListener(marker, 'click',
				function(){
					marker.openInfoWindowHtml(getInfoWindowHtml(score, me));
				}
			);
			return marker;
		}
	};

	this.initializeMap = function(){
		with (this){
			GEvent.addListener(_gmap, 'zoomend', function(){  //Whenever zoomed, the user doesn't want to fit to map.
					_zoomLevel = _gmap.getZoom();
					_ctrLat = _gmap.getCenter().lat();
					_ctrLng = _gmap.getCenter().lng();
					preserve();
				}
			);
			GEvent.addListener(_gmap, 'moveend', function(){
					_ctrLat = _gmap.getCenter().lat();
					_ctrLng = _gmap.getCenter().lng();
				}
			);
			GEvent.addListener(_gmap, 'maptypechanged', function(){
					_mapTypeUrlArg = _gmap.getCurrentMapType().getUrlArg();
					preserve();
				}
			);
			GEvent.addListener(_gmap, 'mouseout', function(){
					_gmap.closeInfoWindow();
				}
			);
			// Order is important!
			_gmap.addMapType(G_PHYSICAL_MAP);
			_gmap.setMapType(getMapTypeFromUrlArg(_mapTypeUrlArg));

			// Need this to display anything.  Set type before. Also, buggy when listeners are added after this
			//_gmap.setCenter(new GLatLng(_ctrLat, _ctrLng), _zoomLevel);

			// If DragZoom control is under GLargeMapControl, setting marginLeft breaks GLargeMapControl
			// but it works with GSmallMapControl. Alternative is to put DragZoom control beside GLargeMapControl.
			if (_gmap.getSize().width >= _smallMapWidthThreshold){
				_gmap.addControl(new GLargeMapControl());
				var dragZoomOpts = {
						buttonStartingStyle: {background: '#FFF', paddingTop: '4px', paddingLeft: '4px', border:'1px solid black'},
						buttonHTML: '<img title="Drag Zoom In" src="Images/zoomin.gif">',
						buttonStyle: {marginTop:'-100px',marginLeft:'65px',width:'25px', height:'23px'},
						buttonZoomingHTML: 'Drag a region on the map (click here to reset)',
						buttonZoomingStyle: {background:'yellow',width:'75px', height:'100%'},
						backButtonHTML: '<img title="Zoom Back Out" src="Images/zoomout.gif">',
						backButtonStyle: {display:'none',marginTop:'-29px',marginLeft:'105px',width:'25px', height:'23px'},
						backButtonEnabled: true,
						overlayRemoveTime: 100
					};
				_gmap.addControl(new DragZoomControl({}, dragZoomOpts, {}));
				_gmap.addControl(new GMapTypeControl());
				_gmap.addControl(new GScaleControl());
			}
			fitMap();
		}
	};

	this.setPlayMode = function(text){
		with(this){
			isPlaying = text == 'Play';
			if(isPlaying){
				var year = parseInt(getText(yearLabel));
				if (year >= maxYear){
					plotScores(minYear);
				}
				setText(playPauseButton, 'Stop');
				playPauseButton.title = 'Stop scrolling through years';
				playNext();
			}else{
				isPlaying = false;
				setText(playPauseButton, 'Play');
				playPauseButton.title = 'Scroll through years';
			}
		}
	};

	this.playNext = function(){
		with(this){
			var year = parseInt(getText(yearLabel));
			while(true){
				year++;
				if(year <= maxYear){
					break;
				}else if(year > maxYear){
					setPlayMode('Stop');
					return;
				}
			}
			if(isPlaying){
				setTimeout(function(){ plotScores( year, true); }, 1000);
			}
		}
	};

	this.plotScores = function(year, checkPlaying){
		with(this){
			if(!_scores){
				return;
			}
			if(checkPlaying == undefined || checkPlaying == isPlaying){
				var showHideYrs;    // index 0 to show, 1 to hide
				if(year == undefined){
					_activeYear = year;
				}
				if(year == _activeYear){
					showHideYrs = [_activeYear];
				}else{
					showHideYrs = [year, _activeYear];
					_activeYear = year;
				}
				for(var i = 0; i < showHideYrs.length; i++){
					var key = getYearKey(showHideYrs[i]);
					var mkrsForYear = _markersByYears[key] || initScoreMarkers(showHideYrs[i]);
					for(var j = 0; j < mkrsForYear.length; j++){
						if(i == 0)  mkrsForYear[j].show();
						else        mkrsForYear[j].hide();
					}
				}
				if(yearLabel)   {   setText(yearLabel, year); }
				if(checkPlaying){   playNext(); }
			}
		}
	};

	this.initScoreMarkers = function(year){
		with(this){
			var mkrsForYear = [];
			var hide = true;
			for(var i = 0; i < _scoresLength; i++){
				var score = _scores[i];
				if(_canPlayByYear){
					var scoreYr = getYear(score);
					if (scoreYr < year){  continue; }
					if (scoreYr > year){  break; }
				}
				var mkr = getGMarker(score, hide);
				_gmap.addOverlay(mkr);
				mkrsForYear.push(mkr);
			}
			_markersByYears[getYearKey(year)] = mkrsForYear;
			return mkrsForYear;
		}
	};

	this.setScoreResult = function(scoreResult){
		with(this){
			_scores = scoreResult.Scores;
			_scoresLength = _scores.length;
			if(_scoresLength > 0){
				maxYear = getYear(_scores[_scoresLength-1]);
				minYear = getYear(_scores[0]);

				_markersByYears = [];
				_activeYear = minYear;
				initScoreMarkers(_activeYear);

				setTimeout(function(){
						if(_canPlayByYear){
							var player = new VCRControl(me);
							_gmap.addControl(player);
							player.plotYear( minYear );
						}else{
							plotScores();
						}
					}, 100);
			}
		}
	}
	
	this.getInfoWindowHtml = function (score){	    
        var scoreGMap = this;  // assignment suppresses error msg in FF.
        var elemId = score.Ag + '_' + (score.SV || (score.LId + '-' + score.DT));
        var s = scoreGMap.htmlForInfoWindows[elemId]; 
        if (s) { return s; }
        s = [];
        var rank = new Rank(score.Rk); 
        s.push('<div class="popupOnGMap">');
        if(score.Ag == 0){    
            var hdr = '<b>' + (score.Sm || 'Stream not specified') + ' &ndash; Site ' + score.LNa + '</b><br/>';
            if(hdr.length > 50){
                hdr = hdr.replace(' &ndash; ', '<br/>');
            }
            s.push('<span class="hdr4">');
            s.push(hdr);
            s.push('</span>');
            s.push(scoreGMap.title + ': <b>' + score.V);
            if(score.Mx > 0){ 
                s.push('/' + score.Mx); 
            }
            s.push('</b>, ' + rank.getText());
            s.push('<br/>Sampled on ' + score.DT + '<br/>');
            s.push('by ' + score.J);
            
            s.push('<br/><a href="Visit-Details.aspx' + scoreGMap.getQS() + 'SV=' + escape(score.SV) + '">View details</a><br/>');
        }else{
            s.push('<span class="hdr3">' + score.LNa + '</span> ');
            s.push(scoreGMap.title + ' <b>' + score.V);
            if(score.Mx > 0){ 
                s.push('/' + score.Mx); 
            }
            s.push('</b>, ' + rank.getText());
            s.push('<span style="display: block; font-weight: bold; margin-top: .3em">View Scores within ' + AreaType.getName(score.Ag) +'</span><table cellpadding="0" cellspacing="0">');
            
            var hrefBase = scoreGMap.getQS() + SRW.ParmArea + '=' + encodeURIComponent(score.LNa);
            if(_canPlayByYear){
                var yr = scoreGMap.getYear(score);
                hrefBase += '&' + SRW.ParmMaxYear + '=' + yr;
                hrefBase += '&' + SRW.ParmMinYear + '=' + yr;
            }

            if(score.Ag == AreaType.WRIA.Value) {
                href = hrefBase + '&' + SRW.ParmAggregateType + '=' + AreaType.Basin.Value;
                s.push('<tr><td class="leftSide">Basins Scores: </td><td class="rightSide"><a href="Biotic-Integrity-Map.aspx' + href + '">On Map</a> or <a href="Biotic-Integrity-Scores.aspx' + href + '">In Table</a></td></tr>');
            }
            if(score.Ag >= AreaType.Basin.Value) {
                href = hrefBase + '&' + SRW.ParmAggregateType + '=' + AreaType.Subbasin.Value;
                s.push('<tr><td class="leftSide">Subbasins Scores: </td><td class="rightSide"><a href="Biotic-Integrity-Map.aspx' + href + '">On Map</a> or <a href="Biotic-Integrity-Scores.aspx' + href + '">In Table</a></td></tr>');
            }
            if(score.Ag >= AreaType.Subbasin.Value) {
                href = hrefBase + '&' + SRW.ParmAggregateType + '=' + AreaType.Stream.Value;
                s.push('<tr><td class="leftSide">Stream Scores: </td><td class="rightSide"><a href="Biotic-Integrity-Map.aspx' + href + '">On Map</a> or <a href="Biotic-Integrity-Scores.aspx' + href + '">In Table</a></td></tr>');
            }

            s.push('<tr><td class="leftSide">All <b>' + score.Vs);
            s.push('</b> Visit Scores: </td><td class="rightSide"><a href="Biotic-Integrity-Map.aspx');
            s.push(hrefBase);
            s.push('">On Map</a> or <a href="Biotic-Integrity-Scores.aspx');
            s.push(hrefBase);
            s.push('">In Table</a></td></tr></table>');
        }
        s.push('</div>');
        s = s.join('');
        scoreGMap.htmlForInfoWindows[elemId] = s;
        return s;
    }
}