﻿general.namespace('SW.Controls');

(function () {

        var MapHistoryControl = SW.Controls.MapHistoryControl = function (regionIdFromUrl, homeRegion) {
			var me = this;
            
            this.HISTORY_MODULE = 'place';

			if (regionIdFromUrl) {
                this.START_REGION_STATE = '0_179.5_1_' + regionIdFromUrl + '_height_none_Sat_-1'; // if the inital region is not 1092 (the world region), the coord (0, 179.5) and zoom of 1 are not correct, but this is not a problem because of how restoreState() works
            }
            var initialRegion = homeRegion || 1092; // 1092 is the world region
            this.DEFAULT_STATE = '0_179.5_1_'+ initialRegion + '_height_none_Sat_-1';
                        
            this.addingState = false;
            this.restoringState = false;
            
            YAHOO.util.History.onReady(function () {
                mapSetup.createMap();
            });
            
	        YAHOO.util.History.register(this.HISTORY_MODULE, this.DEFAULT_STATE, function (state) {
	            // addingState: this handler gets triggered any time the "module" changes, including when 
	            // just adding a url to history, so we need a flag to skip this when just adding a url to history
	            if (state && !me.addingState) {
                    state = me.parseState(state);
                    me.goToState(state);
                }
                me.addingState = false;
	        });
        
            try { 
	            YAHOO.util.History.initialize("yui-history-field", "yui-history-iframe"); 
	        } catch (e) {
	            // The only exception that gets thrown here is when the browser is 
	            // not supported (Opera, or not A-grade) Degrade gracefully.
	        }
        }; 
        MapHistoryControl.prototype.constructor = MapHistoryControl;
        
        
        /**/
        MapHistoryControl.prototype.parseState = function (state) {
            state = state.split('_');

            return {
                center: new GLatLng(parseFloat(state[0]), parseFloat(state[1])),
                zoom: parseInt(state[2]),
                region: SWMap.world.regionsById[parseInt(state[3])],
                animType: state[4],
                markerType: state[5],
                mapTileType: mapGeneral.getMapTypeByShortName(state[6]),
                perspectiveId: parseInt(state[7])
            };
        };
        
        
        /**/
        MapHistoryControl.prototype.encodeState = function (centerLat, centerLng, zoom, regionId, animType, markerType, mapTileType, perspectiveId) {
            return [
                centerLat,
                centerLng,
                zoom,
                regionId,
                animType,
                markerType,
                mapTileType,
                perspectiveId
            ].join('_');
        };
        
        
        /* */
        MapHistoryControl.prototype.goToState = function (state, restore) {
            var map = SWMap.map;
            var currentZoom = SWMap.map.getZoom();
            this.restoringState = (typeof restore === 'undefined') ? true : restore;
            
            /*
            if (state.zoom === currentZoom) {
                SWMap.markerSelectionControl.selectMarkerType(state.markerType);
            } 
            else {
                // instead of just calling setMarkerType in all instances, cut out a few unnecessary requests by using the 'deferUpdate' flag
                SWMap.markerSelectionControl.selectMarkerType(state.markerType, true);
            }
            */
            
            var deferUpdate = state.zoom !== currentZoom;
            SWMap.markerSelectionControl.selectMarkerType(state.markerType, deferUpdate);  // instead of just calling setMarkerType in all instances, cut out a few unnecessary requests by using the 'deferUpdate' flag
 
            handlers.setMapTypeChangedHandler('DUMMY');
            if (state.perspectiveId !== -1) {
                SWMap.map.setCenter(state.center, state.zoom, state.mapTileType);
                SWMap.perspectiveView.display(state.perspectiveId, state.animType);
            }
            else {
                SWMap.perspectiveView.close();
            
                if (state.animType === 'off') {
                    SWMap.animationControl.setType('off');
                    
                    if (state.zoom === currentZoom) {
                        handlers.setMoveEndHandler('ON_PAN_AFTER_SETTING_ANIMATION');
                        SWMap.map.panTo(state.center);
                        map.setMapType(state.mapTileType);
                    }
                    else {
                        SWMap.map.setCenter(state.center, state.zoom, state.mapTileType);
                    }
                }
                else {
                    mapGeneral.centerAndZoomOnRegionAnimation(state.region, state.animType);
                    map.setMapType(state.mapTileType);
                }
            }
        };
        
        /**/
        MapHistoryControl.prototype.setLastViewedState = function (state) {
            YAHOO.util.Cookie.set("previousViewedState", state);
        };
        
        /**/
        MapHistoryControl.prototype.getLastViewedState = function () {
            return YAHOO.util.Cookie.get("previousViewedState");
        };
        
        /*
         */
        MapHistoryControl.prototype.addState = function () {
            var state = this.getState();
            if (!this.restoringState) {
                this.addingState = true;
                YAHOO.util.History.navigate(this.HISTORY_MODULE, state);
            }
            this.restoringState = false;
            this.setLastViewedState(state);
        };      
        
        /*
         */
        MapHistoryControl.prototype.getState = function () {
            var map = SWMap.map;
            var center = SWMap.map.getCenter();
            
            return this.encodeState(
                center.lat(),
                center.lng(),
                map.getZoom(),
                center.getTightestContainingRegion().regionId,
                (SWMap.animationControl.animation.isPerspective) ? SWMap.perspectiveView.currentType : SWMap.animationControl.currentType,
                SWMap.markerGrid.currentMarkerType,
                map.getCurrentMapType().getName(true),
                (SWMap.animationControl.animation.isPerspective) ? SWMap.animationControl.animation.perspectiveId : '-1'
            );
        };
        
        /* */
        MapHistoryControl.prototype.areStatesEqual = function (state1, state2, margin) {
            state1 = (typeof state1 === 'string') ? this.parseState(state1) : state1;
            state2 = (typeof state2 === 'string') ? this.parseState(state2) : state2;
            margin = margin || 300;
            
            if ( state1.zoom === state2.zoom
                && state1.region === state2.region
                && state1.animType === state2.animType
                && state1.markerType === state2.markerType
                && state1.mapTileType === state2.mapTileType
                && state1.perspectiveId === state2.perspectiveId
                && (state1.center.distanceFrom(state2.center) <= margin) ) { 
                return true;
            }
            else {
                return false;
            }
        };
        
        /*
         */
        MapHistoryControl.prototype.goToStartingState = function () {
            var state = YAHOO.util.History.getBookmarkedState(this.HISTORY_MODULE)
                || this.START_REGION_STATE
                || this.getLastViewedState()
                || this.DEFAULT_STATE;
            state = this.parseState(state);
            this.goToState(state);
        };
})();