window.onload = function() {
    MMWCore.Print.init();
};

MMWCore.Print = {
    // location: null,
    // position: null,
    // pois: null,
    routeMarkers: [],
    maps: {},
    page: {},
    map_converted: false,
	red_circle: false,
	refinements: '',
    staticMapsURL: '',

    init: function() {
        if(this.mapType == 64) {
            this.mapType = 8;
        } else if (this.mapType == 256) {
            this.mapType = 32;
        }
        this.initialiseMaps();
        this.initialisePrint();

        if(this.pois) {
            this.plotPOIs();
        }
    },
    
    initialiseMaps: function() {

        var overview_map = document.getElementById( 'mapviewer' );

        // Create maps
        if(overview_map) {
            this.maps.overview = MMFactory.createViewer(overview_map, this.mapType);
            this.maps.overview.setOption('autoswitchapi', false);
        }


        var dp = this.dataPreferences.slice();
        if ( dp ) {
            var data_prefs = MMDataResolver.getDataPreferences( this.mapType );
            for ( var i = 0; i < data_prefs.length; i++ ) {
                if ( ( ' ' + dp.join( ' ' ) + ' ' ).indexOf( ' ' + data_prefs[i] + ' ' ) == -1 ) {
                    dp[dp.length] = data_prefs[i];
                }
            }
            MMDataResolver.setDataPreferences( this.mapType, dp );
        }

        switch(this.bundle) {
            case 'Directions':
                var routeRequester = MMFactory.createRouteRequester( this.mapRouteRequestCallback );
                routeRequester._GeneralJSONCallback( 1, this.route, true );

                if(overview_map) {
                    this.addRouteOverlays( this.maps.overview );
                    this.maps.overview.goToPosition( this.maps.overview.getAutoScaleLocation( this.routeMarkers ));
                } else {
                    this.maps.points = [];
                    for (var i=0, j=this.maps_count; i < j; ++i) {
                        if(this.maps_count > 1) {
                            // Point A
                            if (i == 0) {
                                this.maps.points[i] = MMFactory.createViewer(document.getElementById( 'mapviewerA' ), this.mapType);
                                this.maps.points[i].goToPosition( new MMLocation (new MMLatLon (this.route.start.start_point.lat, this.route.start.start_point.lon), 16));
                            // Vias
                            } else if (i != this.maps_count - 1) {
                                var via_index = i - 1;
                                this.maps.points[i] = MMFactory.createViewer(document.getElementById( 'mapviewerVia' + i ), this.mapType);
                                this.maps.points[i].goToPosition( new MMLocation (new MMLatLon (this.route.points.via[via_index].lat, this.route.points.via[via_index].lon), 16));
                            // Point B
                            }
                            if (i == this.maps_count - 1) {
                                this.maps.points[i] = MMFactory.createViewer(document.getElementById( 'mapviewerB'), this.mapType);
                                this.maps.points[i].goToPosition( new MMLocation (new MMLatLon (this.route.end.end_point.lat, this.route.end.end_point.lon), 16));
                            }
                        }
                        this.maps.points[i].setOption('autoswitchapi', false);
                        this.addRouteOverlays( this.maps.points[i] );
                    };
                }
                break;

            default:
                if(!this.position && this.location) {
                    this.position = this.location;
                }
                if(this.position && this.maps.overview) {
                    this.maps.overview.goToPosition(this.position);
                }
                if(this.location && this.maps.overview) {
                    this.addRedCircle(this.location);
                }
                break;
        }
		
		if (this.maps.overview) {
			this.maps.overview.addEventHandler('changeZoom', this.refreshHotels);
			this.maps.overview.addEventHandler('endPan', this.refreshHotels);
			this.refreshHotels();
		}
    },
	
	refreshHotels: function(eventType){
		
		eventType = eventType || null;

		var zf = MMWCore.Print.maps.overview.getZoomFactor();

		MMWCore.Print.maps.overview.removeAllOverlays();
		
		if (MMWCore.Print.red_circle)
			MMWCore.Print.addRedCircle(MMWCore.Print.location);

		if (MMWCore.Print.route)
			MMWCore.Print.addRouteOverlays(MMWCore.Print.maps.overview);

		if ((zf >= 13) && MMWCore.Print.ha) {
			
			var hotelsArr = MMWCore.Print.ha.split(",");
			for (var i = 0, j = hotelsArr.length; i < j; ++i) {
				MMWCore.Print.plotHotels(hotelsArr[i],MMWCore.Print.hotel_refines);
			}
		}
	},

    addRedCircle: function( location ) {
        // FIXME: don't forget to add current position which will be different from location (red circle)
        var icon = new MMIcon( MMWCore.CDN.getCDNPath('/mmw/i/markers/circle.png') );
        icon.printImage = MMWCore.CDN.getCDNPath('/mmw/i/markers/circle.gif');
        icon.iconSize = new MMDimensions( 34, 34 );
        icon.iconAnchor = new MMPoint( 17, 17 );
        icon.cssClass = 'MMMarkerRedCircle';
        var red_circle = this.maps.overview.createMarker( location, { 'icon' : icon, 'inert' : true } );
		this.red_circle = true;
        return true;
    },

    createMarker: function( location, name ) {
        var icon = new MMIcon(MMWCore.CDN.getCDNPath('/API_RES/1.2/i/marker.png'));
        icon.printImage = MMWCore.CDN.getCDNPath('/API_RES/1.2/i/poi/markers/' + name + '.gif');
        icon.iconSize = new MMDimensions( 23, 26 );
        icon.iconAnchor = new MMPoint( 12, 23 );

        for (var i=0, j=MMWCore.Print.page.dynamic_maps.length; i < j; ++i) {
            var marker = this.page.dynamic_maps[i].createMarker( location, { 'icon' : icon } );
        };
    },

    plotPOIs: function() {
        for (var poi_name in this.pois.record_sets) {
            var pois = this.pois.record_sets[poi_name].records;
            for (var i=0, j=pois.length; i<j; ++i) {
                this.createMarker( new MMLatLon(pois[i].point.lat, pois[i].point.lon), poi_name );
            };
        }
    },
    
    mapRouteRequestCallback: function ( route ) {
        MMWCore.Print.mapRoute = route;
    },

    addRouteOverlays: function ( viewer ) {
        var route = MMWCore.Print.route;
        for( var i = 0, l = MMWCore.Print.mapRoute.polyLine.length; i < l; ++i ) {
            viewer.addOverlay( MMWCore.Print.mapRoute.polyLine[i].copy() );
        }

        var pointIcon = MM_DEFAULT_ICON.copy();
        pointIcon.cssClass = 'MMMarker routePoint';
        
        var viaIcon = new MMIcon( MMWCore.CDN.getCDNPath("/mmw/i/markers/marker.png") );
        viaIcon.iconSize = new MMDimensions( 23, 26 );
        viaIcon.iconAnchor = new MMPoint( 12, 26 );
        viaIcon.infoBoxAnchor = new MMPoint( 9, 0 );
        viaIcon.printImage = MMWCore.CDN.getCDNPath("/mmw/i/markers/marker-via.gif");
		viaIcon.cssClass = 'MMMarker routeViaPoint';
	    

        // *** Do we need markers on route? ***
        // for( var i = 0, l = route.stages.length; i < l; ++i ) {
        //     for( var j = 0, k = route.stages[i].steps.length; j < k; ++j ) {
        //         var marker = viewer.createMarker( 
        //             new MMLatLon( route.stages[i].steps[j].start_point.lat, route.stages[i].steps[j].start_point.lon ) , { 'text' : j }
        //         );
        //         this.routeMarkers = this.routeMarkers.concat(marker);
        //     }
        // }

        this.routeMarkers.push(viewer.createMarker( new MMLatLon( this.route.points.start.lat, this.route.points.start.lon ), {'text' : 'A', 'icon' : pointIcon}));
        // viewer.createMarker( new MMLatLon( this.route.start.start_point.lat, this.route.start.start_point.lon ), {'text' : 'A', 'icon' : pointIcon});
        this.routeMarkers.push(viewer.createMarker( new MMLatLon( this.route.points.end.lat, this.route.points.end.lon ),  {'text' : 'B', 'icon' : pointIcon}));
        // viewer.createMarker( new MMLatLon( this.route.end.end_point.lat, this.route.end.end_point.lon ),  {'text' : 'B', 'icon' : pointIcon});
        for (var i=0, j=this.route.points.via.length; i < j; ++i) {
            this.routeMarkers.push(viewer.createMarker( new MMLatLon( this.route.points.via[i].lat, this.route.points.via[i].lon ),  {'text' : '', 'icon' : viaIcon}));
            
        };
    },
    
    initialisePrint: function() {
        var me = this;
        this.page.containers = [];
        this.page.contents = [];
        this.page.dynamic_maps = [];
        var loaded_img_counter = 0;
        var button = document.getElementById('printButton');
        button.style.display = 'inline';

        // Identify all maps on the page
        for (map in this.maps) {
            if(map == 'points') {
                for (var i=0, j=this.maps[map].length; i < j; ++i) {
                    addMapToCollection(this.maps.points[i]);
                };
            } else {
                addMapToCollection(this.maps[map]);
            }
        }

        function addMapToCollection(map) {
            me.page.dynamic_maps.push(map);
            me.page.containers.push(map.getContainer().parentNode);
            me.page.contents.push(map.getContainer());
        }

        button.onclick = function() {
            if(me.mapType > 4) {
                me.map_converted = true;
            }
            if(MMWCore.Print.bundle == 'Listings' && !me.maps.overview) {
                me.map_converted = true;
            }
            if(me.map_converted) {
                window.print();
                return;
            } else {
                var static_map = {};

                for (var i=0, j=me.page.containers.length; i < j; ++i) {
                    me.page.contents[i].style.display = 'none';
                    static_map.img = document.createElement('img');
                    static_map.img.src = me.convertToStatic(me.page.dynamic_maps[i], static_map.img, MMWCore.Print.bundle);
                    me.page.containers[i].appendChild(static_map.img);

                    static_map.img.onload = function() {
                        loaded_img_counter++;
                        callPrint();
                    };
                }
            }
        };

        function callPrint() {
            // window.print() seems to be crashing Firefox 3 after a few seconds
            if(loaded_img_counter == me.page.containers.length) {
                me.map_converted = true;
                window.print();
            }
        }
    },

    convertToStatic: function(input, output, bundle) {
        output.width = 638;
        output.height = 450;
        var dataPreferences = (typeof this.dataPreferences != 'undefined') ? this.dataPreferences : '';
        var bounds = input.getMapBounds();
        var url = this.staticMapsURL;
        var amp = '&amp;';
        var mapviewer_id = input.getContainer().parentNode.id;
        var via_id = parseInt(mapviewer_id.substr(mapviewer_id.indexOf('Via') + 3));

        // TODO: Get static map API to work with either type of map type: strings or integers.
        var mapType;
        if (this.mapType == 4) { mapType = 'map'; }
        else if (this.mapType == 8) { mapType = 'aerial'; }
        else if (this.mapType == 16 || this.mapType == 32) { mapType = 'hybrid'; }

        // common URL parameters
        var params = {
            width                       : output.width, 
            height                      : output.height, 
            mapType                     : mapType, 
            dataPreferences             : dataPreferences.join(','), 
            zoomFactor                  : input.getZoomFactor(), 
            bb                          : bounds.getSouthWest().lon + ',' + bounds.getSouthWest().lat + ';' + bounds.getNorthEast().lon + ',' + bounds.getNorthEast().lat
        };
        
        if(via_id > 0) {
            var via_index = via_id - 1;
            params.marker               = 'point_via.png';
            params.lat                  = this.route.points.via[via_index].lat;
            params.lon                  = this.route.points.via[via_index].lon;
        }
        // directions only parameters
        if (bundle == 'Directions') {
            params.routeKey             = (this.route ? this.route.key : '');
            params.routeStartMarker     = 'point_a.png';
            params.routeEndMarker       = 'point_b.png'; 
            if(this.advanced) {
                for (var i=0, j=this.route.points.via.length; i < j; ++i) {
                    var count = i + 1;
                    var marker = 'marker_' + count;
                    var lat = 'lat_' + count;
                    var lon = 'lon_' + count;
                    params[marker] = 'point_via.png';
                    params[lat] = this.route.points.via[i].lat;
                    params[lon] = this.route.points.via[i].lon;
                }
            }
        // all apart from directions
        } else {
            params.lat                  = this.location.coords.lat;
            params.lon                  = this.location.coords.lon;
            params.marker               = 'circle.png';
            params.label                = '%20';
        }
        // POIs specific
        if (this.pois) {
            var poiDS = '';
            for (poi in MMWCore.Print.pois.record_sets) {
                poiDS += poi + ',';
            }
            params.overlayDataSource    = poiDS.replace( /,$/, '' );
            params.overlayCount         = 100;
        }
		// Hotel information
		if(this.ha) {
			
			if(params.overlayDataSource)
				params.overlayDataSource += "," + this.ha;
			else
				params.overlayDataSource = this.ha;
		}
        for (param in params) {
            url += param + '=' + params[param] + amp;
        }
        url = url.replace(/\&amp;$/,'');
		url += amp + this.refinements;
        return url;
    },
	
	plotHotels: function(dataSource,refinement) {
		
		// MMWCore.Print.callPoi("thirdparty.activehotels");
		var bb = this.maps.overview.getMapBounds().toAPIQueryString();
		
		// Create URL
		var url = "/API/search/1.2/";
			url += "public_api?output=json&dataSource="+dataSource+"&count=100"+bb+"&returnInfobox=true";
		
		var rf;
				
		if (refinement[dataSource.replace(/[.]/g,"_")]){ // looks for refinement
			rf = refinement[dataSource.replace(/[.]/g,"_")].replace(/[|]/g,"&");
			url += "&" + rf;
			this.refinements += rf;
		}
			
		
		// Create Ajax Call
		var request = new Object();
		if (request.ajax) {
	        request.ajax.onreadystatechange = function() {};
	        request.ajax.abort();
		}
		request.data = dataSource;
		request.ajax = this.getXMLHTTPRequest();
		
		// Send Ajax Call
        request.ajax.open("GET", url, true);
        request.ajax.onreadystatechange = function() { MMWCore.Print.plotHotels_callback(request); }
        request.ajax.send(null);
	},
	
    plotHotels_callback: function(req) {
        
        if (req.ajax.readyState == 4) {
            if (req.ajax.status == 200) {
                
				var json = eval('(' + req.ajax.responseText + ')');
				this.hotels = json;
		
				var records = json.record_sets[req.data].records;
				
				if (records) {
					
					var location;
					
					var icon = new MMIcon(MMWCore.CDN.getCDNPath('/API_RES/1.2/i/marker.png'));
					icon.iconSize = new MMDimensions(23, 26);
					icon.iconAnchor = new MMPoint(12, 23);
					icon.infoBoxAnchor = new MMPoint(9, 0);
					
					if (req.data == "mm.clients.toptable_mmw") 
						infoBoxClass = "MMInfoBox toptable";
					else 
						infoBoxClass = "MMInfoBox";
					
					
					for (i = 0, j = records.length; i < j; i++) {
					
						location = new MMLatLon(records[i].point.lat, records[i].point.lon);
						icon.printImage = MMWCore.CDN.getCDNPath('/API_RES/1.2/i/poi/markers/' + req.data + '.gif');
						
						
						marker = this.maps.overview.createMarker(location, {
							'label': records[i].name,
							'icon': icon,
							'inert' : true
						});
					}
				}
            }
        }
    },

    getXMLHTTPRequest: function() {
        var xmlhttp;
        if( ! xmlhttp && typeof XMLHttpRequest != 'undefined' ) {
            try {
                xmlhttp = new XMLHttpRequest();
            } catch (e) {
                xmlhttp = undefined;
            }
        }
        if( ! xmlhttp && window.ActiveXObject ) {
            try {
                xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
            } catch(e) {
               try {
                   xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
               } catch(e) {
                   xmlhttp = undefined;
               }
            }
        }
        return xmlhttp;
    }
};
