String.prototype.trim = function () {   /* JS doesn't have trim() method of String object */
  return this.replace(/^\s*(\S*(\s+\S+)*)\s*$/, "$1");
};

function MMWCommon() {
    self.loadEvents = new Array();
    this.onPageLoad = function() {
        
        if(MMWLoad){
            if(MMWLoad.genericParams)
                MMWLoad.genericParams();
            if(MMWLoad.setCDNParameters)
                MMWLoad.setCDNParameters();
            if(MMWLoad.mapViewerParams)
                MMWLoad.mapViewerParams();
            if(MMWLoad.mapViewerPostParams)
                MMWLoad.mapViewerPostParams();
            if(MMWLoad.locationSearchParams)
                MMWLoad.locationSearchParams();
            if(MMWLoad.pageLoad)
                MMWLoad.pageLoad();
            if(MMWLoad.directionsPageLoad)
                MMWLoad.directionsPageLoad();
            if(MMWLoad.listingsPageLoad)
                MMWLoad.listingsPageLoad();
            if(MMWLoad.metroMapLoad)
                MMWLoad.metroMapLoad(); 
        }
        
        this.page_id = document.getElementsByTagName('body')[0].id;
        var inputFields = document.getElementsByTagName('input');
        if (!document.getElementById || !document.getElementsByTagName) {
            return;
        }
        MMWCore.Cookies.init(); // 100
        MMWCore.DOMTemplates.init(); // 100
        MMWCommon.Basic.init(); // 99
        MMWCore.UI.Markers.Icons.init(); // null (99)
        MMWCore.UI.Markers.markerCollection = new MMWCore.CollectionBase(); // null (99)
        MMWCore.MyMMLinks.init(); // null (99)
        MMWCore.Log.init(); // null (99)
        MMWCommon.PromoLink.init(); // 90
        MMWCore.UI.Mapviewer.init(); // 85
        MMWCommon.MinWidthForIE.init(); // 80
        MMWCommon.searchBoxHelp.init(); // 80
        MMWCore.UI.Spinner.init(); // 80
        MMWCore.Implementation.Palettes.init(); // 75
        MMWCore.UI.Mapviewer.EventManager.init(); // 20
        MMWCore.UI.MapHeader.init(); // 15
        MMWCore.LocationSearch.init(); // 10
        MMWCore.MSCollections.init(); // 10
        MMWCore.UI.Markers.InfoBox.init(); // 10
        MMWCore.Tabs.init(); // 10
        MMWCore.AdManager.init(); // 9
        MMWCore.UI.MapLocaleInfo.init(); // 8
        MMWCore.Implementation.MapFunctionButtons.init(); // 6
        MMWCore.UI.Mapviewer.WhereAmI.init(); // 5
//        MMWCore.URLManager.handleStaticKeys(); // 1
        MMWCore.PageLoad(); // 1
        MMWCore.Bundles.init(); // 0
        MMWCore.URLManager.init(); // 0
        MMWCore.URLProxy.init(); // 0
        MMWCore.Business.init(); // -100
        MMWCore.Directions.init(); // -100
        MMWCore.DisamMap.init(); // -100
        MMWCore.DefaultCountry.init();
        
        if(window.location.search.indexOf('bing_exit_survey') >= 0) {
             MMWCore.Implementation.Dialogues.open('bingsurvey');
        } 

        // Check that the init event has been called otherwise
        // the mapviewer won't have been created
        if ( !MMWCommon.searchBoxHelp.isHomeOrBundlePage() ) {
            // If we haven't called a goToPosition on the mapviewer yet
            // and we're not waiting for any calls from the bundle interactions...
            if ( !MMWCore.UI.Mapviewer.position_called && !MMWCore.URLManager._waiting ) {
                // Make sure we're not in the listView tab otherwise we'll end
                // up carrying this map across bundles instead of the mini map
                if ( MMWCore.Tabs && MMWCore.Tabs.current == 'listView' )
                    return false;

                // Zoom factor 3 map of the world
                var default_position = new MMLocation(
                    new MMLatLon( 21.40027, -6.18286 ), 3
                );

                // If the we have a country selected in the drop down and
                // its not 'Rest of World' then centre the map on the country
                var country_field = MMWCore.LocationSearch.country_field;
                if ( country_field && country_field.value.trim() != '' ) {
                    default_position = new MMAddress( {
                        'qs' : '',
                        'country_code' : country_field.value
                    } );
                }

                MMWCore.UI.Mapviewer.map.goToPosition( default_position );
            }
        }
        MMWCommon.addToEvent(window, "resize", function() { MMWCore.UI.Mapviewer.resizeMap(); }, 1 );
        MMWCommon.addToEvent(window, "resize", function() { MMWCore.Implementation.Dialogues.TubeMap.setSize(); }, 1 );







        /*
         * This is the old loop for looping through inits from addToEvent. These are no hard-coded.
         */    
        /*self.loadEvents.sort( function(a,b) {
            return a[1] < b[1] ? 1 : ( a[1] == b[1] ? 0 : -1 );
        } );
        for (var i = 0, j = self.loadEvents.length; i<j; i++) {
            self.loadEvents[i][0]();
        }*/
        MMWCommon.Input.init();
    };
    
    // Use our new DOM Ready function.
    //MMWCommon.ready( this.onPageLoad );
    
    //window.onload = this.onPageLoad;
}

MMWCommon.prototype = {    
    className: "self.MMWCommon",
    ready: function( func ){
        var callback = function() {
            if ( typeof func != 'undefined' ) {
                setTimeout( func, Math.random() );
                func = undefined;
            }
        }

        // Mozilla, Opera (see further below for it) and webkit nightlies currently support this event
        // RK disabled for now for Safari as callback is being called twice and causing a crash
        if ( document.addEventListener && navigator.userAgent.indexOf('Safari') == -1 && !window.opera )
            // Use the handy event callback
            document.addEventListener( "DOMContentLoaded", callback, false );

        // If IE is used and is not in a frame
        // Continually check to see if the document is ready
        if ( navigator.userAgent.indexOf('MSIE') != -1 && window == top ) (function(){
            try {
                // If IE is used, use the trick by Diego Perini
                // http://javascript.nwbox.com/IEContentLoaded/
                document.documentElement.doScroll("left");
            } catch( error ) {
                setTimeout( arguments.callee, 50 );
                return;
            }
            // and execute any waiting functions
            callback();
        })();

        if ( window.opera )
            document.addEventListener( "DOMContentLoaded", function () {
                for (var i = 0; i < document.styleSheets.length; i++)
                    if (document.styleSheets[i].disabled) {
                        setTimeout( arguments.callee, 0 );
                        return;
                    }
                // and execute any waiting functions
                callback();
            }, false);

        if ( navigator.userAgent.indexOf('Safari') != -1 ) {
            var numStyles;
            (function(){
                if ( document.readyState != "loaded" && document.readyState != "complete" ) {
                    setTimeout( arguments.callee, 0 );
                    return;
                }
                /*if ( numStyles === undefined )
                    numStyles = jQuery("style, link[rel=stylesheet]").length;
                if ( document.styleSheets.length != numStyles ) {
                    setTimeout( arguments.callee, 0 );
                    return;
                }*/
                // and execute any waiting functions
                callback();
            })();
        }

        // A fallback to window.onload, that will always work
        window.onload = callback;
    },
    
    addToEvent: function(element, ev_type, fn, sortIndex) {
        if (element == window && ev_type == "load") {
            if (arguments.length < 4) {
                sortIndex = 99;
            }
            self.loadEvents.push( new Array(fn, sortIndex) );
            return true;
        }
        if (element.addEventListener) {
            element.addEventListener(ev_type, fn, false);
            return true;
        } else if (element.attachEvent) {
            var r = element.attachEvent('on' + ev_type, fn);
            return r;
        } else {
            element['on' + ev_type] = fn;
        }
    },
    getClientDimensions: function() {
        var x,y;
        if (self.innerHeight) {
                x = self.innerWidth;
                y = self.innerHeight;
        }
        else if (document.documentElement && document.documentElement.clientHeight) {
                x = document.documentElement.clientWidth;
                y = document.documentElement.clientHeight;
        }
        else if (document.body) {
                x = document.body.clientWidth;
                y = document.body.clientHeight;
        }
        return { "x":x, "y":y };
    },
    getVerticalScrollPosition: function() {
        var de = document.documentElement;
        return self.pageYOffset || (de && de.scrollTop) || document.body.scrollTop;
    },
    /*
        If you change hasCssClass, make sure you change other
        inline versions of the function which are there for 
        performance reasons. Have a good reason for
        changing this as well, as it's very fast.
    */
    hasCssClass: function(o, c) {
        return (" " + o.className + " ").indexOf( c ) >= 0;
    },
    addCssClass: function(o, c) {
        if ((" " + o.className + " ").indexOf( c ) >= 0) {
            return false;
        }
        o.className = o.className.trim() + " " + c.trim();
        return true;
    },
    removeCssClass: function(o, c) {
        if ((" " + o.className + " ").indexOf( c ) == -1) {
            return false;
        }
        o.className = o.className.replace(c.trim(), "").trim();
        return true;
    },
    setCssClass: function(o, css_class) {
        o.className = css_class;
        return true;
    },
    getEventTarget: function(e) {
        var e = e || window.event;
        var targ = e.target || e.srcElement;
        if (targ.nodeType == 3) {// defeat Safari bug
		targ = targ.parentNode;
        }
        return targ;
    },
    isKeyboardClick: function(e) {
        var e = e || window.event;
        for (x in e) {
            alert(x + ' = ' + e[x]);
        }
        return (e.clientX == 0 && e.clientY == 0) ? true : false;
    },
    getComputedStyle: function(o, property) {
        var property_value = null;
        if (o.currentStyle) {
            property_value = o.currentStyle[property];
        } else if (window.getComputedStyle) {
            property_value = document.defaultView.getComputedStyle(o,null).getPropertyValue(property);
        }
        return property_value;
    },
    getAbsolutePosition: function(o, stop_at_element) {
        var position = new Object();
        position["left"] = parseInt(o.offsetLeft);
        position["top"] = parseInt(o.offsetTop);
        while (o = o.offsetParent) {
            if (o == stop_at_element) {
                break;
            }
            position["left"] += parseInt(o.offsetLeft);
            position["top"] += parseInt(o.offsetTop);
        }
        return position;
    },
    getParentNodeByTagName: function(o, parent_tag) {
        while (o = o.parentNode) {
            if (o.nodeType != 1) {
                continue;
            }
            if (o.tagName.toLowerCase() == parent_tag.toLowerCase()) {
                return o;
            }
        }
        return null;
    },
    getParentNodeByClassName: function(o, className) {
        while (o) {
            if (o.nodeType != 1) {
                o = o.parentNode;
                continue;
            }
            if (o.className.match(new RegExp( '\\b'+className+'\\b' ))) {
                return o;
            }
            o = o.parentNode;
        }
        return null;
    },
    getElementsByTagNames: function(o, list) {
        var tag_names = list.split(",");
        var results = new Array();
        for (var i=0; i<tag_names.length; i++) {
            var elements = o.getElementsByTagName(tag_names[i]);
            for (var j=0, k=elements.length; j<k; j++) {
                results.push(elements[j]);
            }
        }
        return results;
    },
    getElementsByTagNameClass: function(o, n, c) {
    	if (!o){
    		return;
    	}
        var r = [];
        var e = o.getElementsByTagName(n);
        for (var i = 0, j = e.length; i<j; ++i) {
            if ((" " + e[i].className + " ").indexOf( c ) >= 0) {
                r.push(e[i]);
            }
        }
        return r;
    },
    getParentByStyleProperty: function(o, property, value) {
        while (o = o.parentNode) {
            if (this.getComputedStyle(o, property) == value) {
                return o;
            }
        }
        return null;
    },
    removeAllChildren: function(o) {
        while (o.hasChildNodes()) {
            o.removeChild(o.firstChild);
        }
    },
    stringToBounds: function( str ) {
        var bounds = new MMBounds();
        var parts = str.split( ';' );
        var ll = parts[0].split( ',' );
        bounds.extend( new MMLatLon( Number( ll[0] ), Number( ll[1] ) ) );
        ll = parts[1].split( ',' );
        bounds.extend( new MMLatLon( Number( ll[0] ), Number( ll[1] ) ) );
        return bounds;
    },
    newWindow: function(url) {
        window.open(url);
        return false;
    },

    decodeBase64: function(s) {
        var base64chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'.split("");
        var base64inv = {}; for (var i = 0; i < base64chars.length; i++) { base64inv[base64chars[i]] = i; }

        var p = (s.charAt(s.length-1) == '=' ? (s.charAt(s.length-2) == '=' ? 'AA' : 'A') : "");
        var r = "";

        s = s.substr(0, s.length - p.length) + p;
 
        s = s.replace(new RegExp('[^'+base64chars.join("")+']', 'g'), "");
 
        for (var c = 0; c < s.length; c += 4) {
            var n = (base64inv[s.charAt(c)] << 18) + base64inv[s.charAt(c+3)] + (base64inv[s.charAt(c+1)] << 12) + (base64inv[s.charAt(c+2)] << 6);

            r += String.fromCharCode((n >>> 16) & 255, (n >>> 8) & 255, n & 255);
        }

        return r.substring(0, r.length - p.length);
    }
};

var MMW_BUSINESS_TEXT = 'e.g. coffee or Starbucks';

MMWCommon.prototype.searchBoxHelp = {
    init: function() {
        var locations = new Array( 'location', 'dir_from', 'dir_to', 'via_string', 'dir_to3', 'query' );
        var countries = new Array( 'country', 'country_from', 'country_to', 'country_via', 'country_to' );

        var locationBox, country, me = this, results = this.setupResults();

        for ( var i = 0; i < locations.length; i++ ) {
            locationBox = document.getElementById( locations[i] );
            country = document.getElementById( countries[i] );

            if ( locationBox && !country ) {
                if ( locationBox.id == 'query' ) {
                    locationBox.helperText = MMW_BUSINESS_TEXT;
                    function onEvent( event_type ) {
                        if ( event_type == 'focus' && locationBox.value == MMW_BUSINESS_TEXT ) {
                            locationBox.value = '';
                            return locationBox.style.color = '';
                        } else if ( event_type == 'blur' && locationBox.value == '' ) {
                            locationBox.value = MMW_BUSINESS_TEXT;
                            return locationBox.style.color = '#666';
                        }
                    }
                    MMWCommon.addToEvent( locationBox, 'focus', function() {
                        onEvent( 'focus' );
                    } );
                    MMWCommon.addToEvent( locationBox, 'blur', function() {
                        onEvent( 'blur' );
                    } );
                    MMWCommon.addToEvent( locationBox.form, 'submit', function() {
                        // Fake a focus event so that we clear the value
                        // of the input if it's got the helper text
                        onEvent( 'focus' );
                    } );
                    onEvent( 'blur' );
                }
                continue;
            }

            if ( !locationBox || !country )
                continue;

            locationBox.country = country;
            country.locationBox = locationBox;

            locationBox.validate = function() {
                for ( var item in results ) {
                    if ( this.value == results[item] )
                        return true;
                }
                return false;
            }
            locationBox.setFontColor = function( helper ) {
		    this.style.color = ( helper ) ? '#666666' : '';
            }

            me.searchBoxSetEvent( locationBox, country );

            MMWCommon.addToEvent( locationBox, 'focus', function( e ) {
                var targ = MMWCommon.getEventTarget( e );
                me.searchBoxFocusEvent( targ );
            });
            MMWCommon.addToEvent( locationBox, 'blur', function( e ) {
                var targ = MMWCommon.getEventTarget( e );
                me.searchBoxSetEvent( targ, targ.country );
            });
            MMWCommon.addToEvent( country, 'change', function( e ) {
                var targ = MMWCommon.getEventTarget( e );
                me.searchBoxSetEvent( targ.locationBox, targ );
            });
        }
        this.init = function() {
            return false;
        }
    },
    isHomeOrBundlePage: function() {
        var homeOrBundlePage = ( document.getElementById( 'mapviewer' ) == null && window.location.href.indexOf( 'print' ) == -1 );
        this.isHomeOrBundlePage = function() {
            return homeOrBundlePage;
        }
        return homeOrBundlePage;
    },
    searchBoxSetEvent: function(searchBox, countrySelect) {
        var result = MMWCommon.searchBoxHelp.setupResults();
        var code = countrySelect.options[countrySelect.selectedIndex].value.toLowerCase();
        if ( searchBox.value != '' ) {
            if ( !searchBox.validate() ) {
                return false;
            }
        }
        if ( !result[code] ) code = 'rw';
        searchBox.value = result[code];
        searchBox.setFontColor( true);
    },
    searchBoxFocusEvent: function( me ) {
        if ( me.validate() ) {
            me.value = '';
        } else {
            me.select();
        }
        me.setFontColor( false );
    },
    validate: function(value) {
        var results = MMWCommon.searchBoxHelp.setupResults();
        for (var item in results) {
            if (value == results[item]) {
                return true;
            }
        }
    },
    setupResults: function() {
        var template = MMWCore.DOMTemplates.getTemplate( 'PaletteHelpText' ), result = {};
        if ( template ) {
            result.gb = template.gb.innerHTML || document.createTextNode( '' );
            result.us = template.us.innerHTML || document.createTextNode( '' );
            result.au = template.au.innerHTML || document.createTextNode( '' );
            result.rw = template.rw.innerHTML || document.createTextNode( '' );
        }
        this.setupResults = function() {
            return result;
        }
        return this.setupResults();
    }
}

self.MMWCommon = new MMWCommon();

MMWCommon.addToEvent( window, "load", function() { MMWCommon.Basic.init(); }, 99 );

self.MMWCommon.Basic = {
	init: function() {
                try {
         	    if ( MMWCommon.hasCssClass('wrapper', 'basic') ){
	                return;
                    }
		} catch(e) {
                };
		if (document.getElementById("wrapper").className == "basic"){
        	document.getElementById("wrapper").className = "";
        };
        if ( MMWCore.UI.Mapviewer && MMWCore.UI.Mapviewer.map )
            MMWCore.UI.Mapviewer.map.resize();
        return;
	}
}

self.MMWCommon.Input =  {
    init: function() {
        var inputs = document.getElementsByTagName("input");
        for (var i = inputs.length-1; i>=0; i--) {
            if (inputs[i].type.toLowerCase() != "text") {
                continue;
            }
            inputs[i].onfocus = self.MMWCommon.Input.focus;
        }
    },
    focus: function() {
            this.select();
    },
    blur: function() {
        if(this.value == "") {
            this.value = this.default_value;
        }
    }
}


self.MMWCommon.PromoLink = {
	init: function() {
		if (!document.getElementById("promoArea")) {
			return false;
		}
		var links = MMWCommon.getElementsByTagNames(document.getElementById("promoArea"),"a");
		for (var j = links.length-1; j>=0; j--) {
			if (links[j].href) {
				var Promo = MMWCommon.getParentNodeByTagName(links[j],"div");
				MMWCommon.addCssClass(Promo,"clickable");
				Promo.onclick = function() {
				   MMWCommon.addCssClass(this,"clickable");
				   var linkDiv = MMWCommon.getElementsByTagNames(this,"a");
				   window.location = linkDiv[0].href;
				}
			}
        }

	}
}

self.MMWCommon.MinWidthForIE = {
	init: function() {
		MMWCommon.MinWidthForIE.resize();
		MMWCommon.addToEvent( window, "resize", function() { MMWCommon.MinWidthForIE.resize(); }, 80 );
	},
	resize: function() {
		var dim = self.MMWCommon.getClientDimensions();
		var wrapper = document.getElementById("wrapper");
		if (dim.x <= 999) {
			MMWCommon.addCssClass(wrapper,"minwidth");	
		} else {
			MMWCommon.removeCssClass(wrapper,"minwidth");	
		}
	}
}	


//MMWCommon.addToEvent( window, "load", function() { MMWCommon.MinWidthForIE.init(); }, 80 );
//MMWCommon.addToEvent( window, "load", function() { MMWCommon.searchBoxHelp.init(); }, 80 );
//MMWCommon.addToEvent( window, "load", function() { MMWCommon.PromoLink.init(); }, 90 );
