// 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(_scoreGMap.minYear);
        
        yrContainer.appendChild(_scoreGMap.yearLabel);
        
        {
            var startBtn = document.createElement('input');
            styleButton(startBtn, 'First');
            container.appendChild(startBtn);
            GEvent.addDomListener(startBtn, 'click', function() {        
                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() {
                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, scores, canPlayByYear, minYear, maxYear, aggregateFactor, getInfoWindowHtmlFn){
	var _smallMapWidthThreshold = 500;
	var _initialized = false;
	var _scores = scores;
	var _markersByYear;
	var _canPlayByYear = canPlayByYear;
	var _activeYearKey;
	var _aggregateFactor = aggregateFactor;
	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 fitScores = function(){
	    with(this){
		    var bounds;
		    if(_scores.length > 0){
			    bounds = new GLatLngBounds();
			    for (var i=0; i < scores.length; i++){
				    bounds.extend(new GLatLng(_scores[i].La, _scores[i].Lo));
			    }
		    }else{
			    var sw = new GLatLng(45, -122);
			    var ne = new GLatLng(48, -121);
			    bounds = new GLatLngBounds(sw, ne);
		    }
		    _gmap.setZoom(_gmap.getBoundsZoomLevel(bounds));
		    _gmap.setCenter(bounds.getCenter());
		}
	};

	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;
		}
	};

	var getYearKey = function(year){
		return 'Year' + ('' + year).match(/\d{4}/);
	};

	///////////////////// PUBLICS ////////////////////////////

	this.minYear = minYear; // show this first
	this.maxYear = maxYear;
	this.htmlForInfoWindows = [];
	this.getInfoWindowHtml = getInfoWindowHtmlFn;
    this.yearLabel = null;
    this.isPlaying = false;
    this.playPauseButton = null;
       
	this.getGIcon = function(rank, flags, size){
		var icon = new GIcon();
		icon.image = rank.getIconRef(flags);    
		icon.iconSize = new GSize(size, size);
		icon.iconAnchor = new GPoint(1, 1);
		icon.infoWindowAnchor = new GPoint(5, 1);
		return icon;
	};

	this.getIconSize = function(){
		with(this){
			var sz = +_zoomLevel;
			if(+_aggregateFactor>0){
				sz += (_aggregateFactor/5);
			}else{
				sz *= 1.6;
			}
			return sz;
		}
	};

	this.getGMarker = function(score, hide){
		with(this){
			var rank = new Rank(score.Rk); 
			var marker = new GMarker(new GLatLng(score.La, score.Lo), 
				{   icon: getGIcon(rank, score.F, getIconSize()),
					hide: hide   
				});

			GEvent.addListener(marker, 'click', 
				function(){
					marker.openInfoWindowHtml(getInfoWindowHtml(score));
				}
			);
			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());
				if(_canPlayByYear && _scores.length > 0){
				    _gmap.addControl(new VCRControl(this));
				}
			}
			fitScores();
			setTimeout(function(){ plotScores(); }, 1);
		}
	};

    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{
                setText(playPauseButton, 'Play');
                playPauseButton.title = 'Scroll through years';
            }
        }
    };
                   
    this.playNext = function(){
        with(this){
            var year = parseInt(getText(yearLabel));
            while(true){
                year++;
                var yearMarkers = _markersByYear[getYearKey(year)];
                if(year <= maxYear && yearMarkers){
                    break;
                }else if(year > maxYear){
                    setPlayMode('Stop');
                    return;
                }
            }
            if(isPlaying){
                setTimeout(function(){ plotScores( year, isPlaying); }, 1000);
            }
        }
    };
    
    this.plotScores = function(year, checkPlaying){
		with(this){
			if(!_initialized){
				_markersByYear = [];
				_activeYearKey = getYearKey(minYear);

				var defaultKey;
				if(!_canPlayByYear){
					defaultKey = _activeYearKey;
				}
				for(var i=0; i < _scores.length; i++){
					var score = _scores[i];
					var yrKey = defaultKey || getYearKey(score.DT);
					var mkrsForYear = _markersByYear[yrKey];
					if(!mkrsForYear){
						mkrsForYear = [];
						_markersByYear[yrKey] = mkrsForYear;
					}
					var mkr = getGMarker(score, yrKey != _activeYearKey);
					_gmap.addOverlay(mkr);
					mkrsForYear.push(mkr);
				}
				_initialized = true;
			} else {
			    if(checkPlaying == undefined || checkPlaying == isPlaying){
			        var seqKeys = [_activeYearKey, getYearKey(year)];
				    for(var i = 0; i < seqKeys.length; i++){
					    var yearMarkers = _markersByYear[seqKeys[i]];
                        if (yearMarkers){
						    for(var j = 0; j < yearMarkers.length; j++){
							    if(i == 0){
								    yearMarkers[j].hide();
							    }else{
								    yearMarkers[j].show();
							    }
						    }
					    }
				    }
				    _activeYearKey = seqKeys[1];
				    if(yearLabel){
				        setText(yearLabel, year);
				    }
				    if(checkPlaying){
				        playNext();
				    }
				}
			}
		}
	};

	this.preserve = function(){
		with(this){
			if(_initialized){
				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;
			}
		}
	};
}
