function DineGmapListeners(map,args) {
    this.m = args.m;
    this.who = args.who;
    this.map = map;
    this.url = '/p/dine/search_restaurants.cgi?xml=1&action=search&site='+args.site+'&rating='+args.rating+'&foodtype='+args.foodtype+'&tracking='+args.tracking+'&pid='+args.pid+'&lang='+args.lang+'&keywords='+args.keywords+'&cobrand='+args.cobrand;
    this.baseIcon = args.baseIcon;
    this.nomove = 0;
    this.firstmove = 1;

    this.search = function(args) {
        var me = this;

        var sendUrl = this.url;
        if (args) {
            sendUrl = sendUrl + args;
        }
        this.sendRequest(sendUrl+'&search=1');
    };

    this.redirect = function() {
        var bounds = this.map.getBounds();
        var bounds_max = bounds.getNorthEast();
        var bounds_min = bounds.getSouthWest();
        var sendUrl = this.url + '&minlat='+bounds_min.lat() + '&maxlat='+bounds_max.lat() + '&minlng='+bounds_min.lng()+'&maxlng='+bounds_max.lng();
        sendUrl = sendUrl.replace(/xml=1/,'xml=0');
        window.location.href = sendUrl;
    };

    this.onMoveEnd = function() {
        var bounds = this.map.getBounds();
        var bounds_max = bounds.getNorthEast();
        var bounds_min = bounds.getSouthWest();
        var sendUrl = this.url + '&minlat='+bounds_min.lat() + '&maxlat='+bounds_max.lat() + '&minlng='+bounds_min.lng()+'&maxlng='+bounds_max.lng();

        this.sendRequest(sendUrl+'&onMoveEnd=1');
    };

    this.sendRequest = function(sendUrl) {
        try {
            $('mapLoadingDiv').style.display='block';
        }catch(e){}
        var me = this;
        var d = new Date();
        sendUrl = sendUrl + '&ts='+d.getTime();
        GDownloadUrl(sendUrl,function(data,code) {
            me.nomove = 1;
            var xml = GXml.parse(data);
            try {
                var markers = xml.documentElement.getElementsByTagName('marker');
            } catch(e) {
                var markers = xml.getElementsByTagName('marker');
            }
            try {
                me.setPages(xml.documentElement.getElementsByTagName('currentPage')[0].firstChild.nodeValue,xml.documentElement.getElementsByTagName('pageCount')[0].firstChild.nodeValue);
            } catch(e) {
                try {
                    me.setPages(xml.getElementsByTagName('currentPage')[0].firstChild.nodeValue,xml.getElementsByTagName('pageCount')[0].firstChild.nodeValue);
                } catch(f) { }
            }


            if (markers && markers.length > 0) {
                try{
                    me.map.clearOverlays();
                }catch(e){}
                me.printMarkers(markers);
                /* me.printFeatured(markers[0]); -- NOT NEEDED FOR RIGHT NOW --- */  

                for (var i=0;i<markers.length;i++) {
                    try {
                        var pt = new GLatLng(parseFloat(markers[i].getAttribute('lat')),parseFloat(markers[i].getAttribute('lng')));
                        me.map.addOverlay(me.createMarker(pt,i,markers[i]));
                    }catch(e){ }
                }
            } 
            if (!markers || markers.length == 0 || (markers && markers.length && markers[0].getAttribute('nolist') == 1)) {
                try{
                    me.map.clearOverlays();
                }catch(e){}
                try{
                    $('side_results').innerHTML = $('searchErrorMessage').innerHTML
                }catch(e){}
                try {
                    document.getElementsByClassName('paginationDiv').each(function(e){e.style.display='none'});
                }catch(e){}
            }


            try {

                var minCoord;
                var maxCoord;
                try {
                    minCoord = {
                        lat: xml.documentElement.getElementsByTagName('minlat')[0].firstChild.nodeValue,
                        lng: xml.documentElement.getElementsByTagName('minlng')[0].firstChild.nodeValue
                    };
                    maxCoord = {
                        lat: xml.documentElement.getElementsByTagName('maxlat')[0].firstChild.nodeValue,
                        lng: xml.documentElement.getElementsByTagName('maxlng')[0].firstChild.nodeValue
                    };
                } catch(e) {
                    try {
                        minCoord = {
                            lat: xml.getElementsByTagName('minlat')[0].firstChild.nodeValue,
                            lng: xml.getElementsByTagName('minlng')[0].firstChild.nodeValue
                        };
                        maxCoord = {
                            lat: xml.getElementsByTagName('maxlat')[0].firstChild.nodeValue,
                            lng: xml.getElementsByTagName('maxlng')[0].firstChild.nodeValue
                        };
                    } catch(f) {}
                }
                var bounds = me.map.getBounds();
                var bounds_max = bounds.getNorthEast();
                var bounds_min = bounds.getSouthWest();
                if (me.firstmove || (minCoord.lat < bounds_min.lat() || maxCoord.lat > bounds_max.lat() || minCoord.lng < bounds_min.lng() || maxCoord.lng > bounds_max.lng()) && me.map.getZoom() > 3) {
                    me.firstmove=0;

                    // set center to midpoint of minCoord and maxCoord.
        //alert('min '+minCoord.lat+', '+minCoord.lng+'\nmax: '+maxCoord.lat+', '+maxCoord.lng);
                    var mid = {
                        'lat': (minCoord.lat - -maxCoord.lat) / 2 ,
                        'lng': (minCoord.lng - -maxCoord.lng) / 2 
                    };
        //alert('center: '+mid.lat+', '+mid.lng);
                    me.map.setCenter(new GLatLng(mid.lat,mid.lng));
                
                    GEvent.removeListener(me.zoomhandler);

                        me.map.setZoom(13);
                    var bounds = me.map.getBounds();
                    var bounds_max = bounds.getNorthEast();
                    var bounds_min = bounds.getSouthWest();
                    while ((minCoord.lat < bounds_min.lat() || maxCoord.lat > bounds_max.lat() || minCoord.lng < bounds_min.lng() || maxCoord.lng > bounds_max.lng()) && me.map.getZoom() > 3) {
                        //alert(minCoord.lat +'<'+ bounds_min.lat() +'||'+ maxCoord.lat +'>'+ bounds_max.lat() +'||'+ minCoord.lng +'<'+ bounds_min.lng() +'||'+ maxCoord.lng +'>'+ bounds_max.lng());
                        me.map.zoomOut();
                        bounds = me.map.getBounds();
                        bounds_max = bounds.getNorthEast();
                        bounds_min = bounds.getSouthWest();
                    }
                    me.zoomhandler = GEvent.bind(me.map, "zoomend", me, me.onMoveEnd);
                }
            } catch(e) {
                // alert('center/zoom error: '+e.message);
            }


            try {
                $('mapLoadingDiv').style.display='none';
            }catch(e){}
            $('side_results').scrollTop = 0;

            me.nomove = 0;
        });
    }


    this.createMarker = function(point, index, markers) {
        if (markers.getAttribute('nolist')) { return; }
        // Create a lettered icon for this point using our icon class
        var letter = String.fromCharCode("A".charCodeAt(0) + index);
        var icon = new GIcon(this.baseIcon);
        icon.image = "http://www.google.com/mapfiles/marker" + letter + ".png";
        var marker = new GMarker(point, icon);

        var address = markers.getAttribute('address');
        var name = markers.getAttribute('name');
        var phone;
        (markers.getAttribute('phone') == 'Unknown') ? phone = '' : phone = markers.getAttribute('phone');

        var rid = markers.getAttribute('rid');
        var city = markers.getAttribute('city');
        var state = markers.getAttribute('state');
        var rating = markers.getAttribute('rating');
        //var link = '<a href="'+  markers.getAttribute('link') + '" target=_top>' + name + '</a>';
        var link = '<a href="/p/dine/info.cgi?who='+this.who+'&m='+this.m+'&rid='+rid+'"&nbsp;target=_top>'+name+'</a>'; 

        var infoWindow ="<div id='infoWindow'><div style='float:left;height:100px;margin-right:6px;z-index: 3;'>";
        var sidebar = $('side_results');
        GEvent.addListener(marker, "click", function() {
            var html = infoWindow + letter + ".</div><div><b>" + link + "</b></div><div>" + rating + "/5</div><div>" + address + "</div><div>" + city + ", " + state +  "</div><div>" + phone + "</div>";
            html += '<div style="margin-top:4px;"><a target="_new" href="http://maps.google.com/maps?f=d&hl=en&saddr=&daddr='+ address +' '+ city + ", " + state +'&layer=&ie=UTF8&z=10&om=1">Get directions</a></div>';
            html += "</div>";
            marker.openInfoWindowHtml(html);
            var pos = Position.positionedOffset($('marker'+letter));
            var ppos = Position.positionedOffset($('marker'+letter).parentNode);

            sidebar.scrollTop = (parseInt(pos[1]) - parseInt(ppos[1]));
        });
        return marker;
    }


    this.printMarkers = function(xml) {
        var markers = xml;
        if (!markers || !markers.length) return;

        var buff = "";
        for (var i=0; i<markers.length; i++) {
            var letter = String.fromCharCode("A".charCodeAt(0) + i);

            var url = '/p/dine/info.cgi?who='+this.who+'&m='+this.m+'&rid='+markers[i].getAttribute('rid');

            buff += '<div id="marker'+letter+'"><span style="margin-right:6px;"><a href="'+ url + '" style="color:#FC5801;font-weight:bold;">' + String.fromCharCode("A".charCodeAt(0) + i) + '.&nbsp;&nbsp;' + markers[i].getAttribute("name") + '&nbsp;&raquo;</a></span></div>';
            buff += '<div style="font-size:10px;">';
            buff += (markers[i].getAttribute("address") != null) ? markers[i].getAttribute("address") + '<br>' : '';
            buff += markers[i].getAttribute("city") + ', ' + markers[i].getAttribute("state") + '<br>';
            if ( markers[i].getAttribute("phone") != 'Unknown' ) {
                buff += (markers[i].getAttribute("areacode") != null) ? '('+ markers[i].getAttribute("areacode") +') ' : '';
            }
            buff += (markers[i].getAttribute("phone") != 'Unknown') ? markers[i].getAttribute("phone") : '' ;
            buff += '</div><div style="margin-bottom:6px;font-size:10px;">';
            buff += (markers[i].getAttribute("numreviews") != null) ?  '<a href="'+url+'#reviewSection">'+markers[i].getAttribute("numreviews") + ' reviews</a>' : '0 reviews';
	    buff += ' (' + markers[i].getAttribute("rating") + '/5)</div>';
        }
        $("side_results").innerHTML = buff;
    }
    this.printFeatured = function (xml) {
        try {
            var marker = xml;
            var buff = "";
            var rating = Math.floor(marker.getAttribute("rating"));

            buff += '<div><span style="margin-right:6px; font-size: 16px;"><a href="'+ marker.getAttribute("link") + '" style="color:#FC5801;font-weight:bold;">' +  marker.getAttribute("name") + '</a></span></div>';
            buff += '<div><img src="[var GLOBAL->GRAPHICS_URL]/stars/new/'+rating+'_stars.gif" width="80" height="16" border="0" style="float:left;margin-right:6px;">';
            buff += '<span style="margin-right:6px;"><a href="">' +  ((marker.getAttribute("numreviews") != null) ?  marker.getAttribute("numreviews") : '0') + ' reviews</a></span></div>'; 
            buff += '<div style="clear: left;"><span style="margin-right:6px;">' + marker.firstChild.nodeValue + '</span></div>';
            buff += '<div><span style="margin-right:6px;color:#FC5801;">' +  marker.getAttribute("address") + '<br>' + marker.getAttribute("city") + ', ' + marker.getAttribute("state") + ' ' + marker.getAttribute("zipcode") + '<br>';
            if ( marker.getAttribute("phone") != 'Unknown' ) {
                buff += (marker.getAttribute("areacode") != null) ? '('+ marker.getAttribute("areacode") +') ' : '';
            }
            buff += (marker.getAttribute("phone") != 'Unknown') ? marker.getAttribute("phone") + '<br>' : '';
            buff += 'Category: ' + marker.getAttribute("foodtype") + '</span></div>';
            $("featured_restaurant").innerHTML = buff;
        } catch(e) {}
    }


    this.movehandler = GEvent.bind(this.map, "dragend", this, this.onMoveEnd);
    this.zoomhandler = GEvent.bind(this.map, "zoomend", this, this.onMoveEnd);
    
}


function DineFullGmapListeners(map,args) { 
    this.temp = DineGmapListeners;
    this.temp(map,args);
    delete this.temp;

    this.url = '/p/dine/search_restaurants.cgi?xml=1&action=search&site='+args.site+'&tracking='+args.tracking+'&pid='+args.pid+'&lang='+args.lang+'&cobrand='+args.cobrand;


    this.defaultsearch = '&searchname='+encodeURIComponent(args.searchname)+'&name='+encodeURIComponent(args.name)+'&foodtype='+encodeURIComponent(args.foodtype)+'&rating='+encodeURIComponent(args.rating)+'&keywords='+encodeURIComponent(args.keywords)+'&city='+encodeURIComponent(args.city)+'&state='+encodeURIComponent(args.state)+'&zip='+encodeURIComponent(args.zip)+'&ziptype='+(args.ziptype?encodeURIComponent(args.ziptype):5)+'&minlat='+args.minlat+'&minlng='+args.minlng+'&maxlat='+args.maxlat+'&maxlng='+args.maxlng;

    this.setTitle = function(args) {
        var neartitle = args.city && args.state && args.zip 
            ? args.city+', '+args.state+' '+args.zip
            : args.zip ? args.zip
            : args.city && args.state ? args.city+', '+args.state
            : args.city ? args.city
            : args.state;
        if (neartitle.length) neartitle = 'near '+neartitle;
        //$('search-title').innerHTML = 'Top '+(args.foodtype ? args.foodtype : args.searchname ? args.searchname : '')+' Restaurants '+neartitle;
        $('search-title').innerHTML = 'Top Restaurants '+(args.foodtype ? 'matching '+args.foodtype : args.searchname ? 'matching '+args.searchname : '')+' '+neartitle;
    };
    this.setTitle(args);

    this.initsearch = function() {
        var bounds = this.map.getBounds();
        var bounds_max = bounds.getNorthEast();
        var bounds_min = bounds.getSouthWest();
        var sendUrl = this.url + this.defaultsearch+'&initsearch=1';
        this.sendRequest(sendUrl);
    };
    this.initsearch();

    this.printMarkers = function(xml) {
        var markers = xml;
        if (!markers || !markers.length) return;

        var buff = "";
        var image = "";
        var areaPhone = "";

        var minCoord;
        var maxCoord;
        for (var i=0; i < markers.length; i++) {
            var address = markers[i].getAttribute('address');
            var rating = markers[i].getAttribute('rating');
            var areaPhone = "";

            if (markers[i].getAttribute('nolist')) { continue; }

            if (address != '') {
                address += '</br>';
            } else {
                address = markers[i].getAttribute('city') + ' ' + markers.getAttribute('state');
            }

            if (!rating) rating = 0;
            eval("image = '<img src=\"http://dine.com/images/dine/stars/new/"+parseInt(rating)+"_stars.gif\" width=\"80\" height=\"16\" border=\"0\" style=\"float:left;margin-right:6px;\">';");

            if(markers[i].getAttribute('areacode') != '') {
                areaPhone = "(" + markers[i].getAttribute('areacode') + ")" + "&nbsp;";
            }
            areaPhone += markers[i].getAttribute('phone');

            var url = '/p/dine/info.cgi?who='+this.who+'&m='+this.m+'&rid='+markers[i].getAttribute('rid');

            buff += '<div style="margin-right:6px;height:100px;width:10px;float:left;">' + String.fromCharCode("A".charCodeAt(0) + i) + '</div>';
            buff += '<div style="text-align:left;">';
            buff += '<span><a href="'+url+'" style="text-decoration:none;white-space:wrap;font:bold 16px arial,sans-serif,helvetica;">' + markers[i].getAttribute('name') + '</a></span>';
            buff += '<div style="margin-bottom:6px;">' + image + " (based on <a href='"+url+"#reviewSection'>" + markers[i].getAttribute('numreviews') + "&nbsp;reviews</a>)"  + '</div>';
            buff += '<div style="margin-bottom:8px;">' + address + '</div>';
            buff += '<div style="margin-bottom:4px;">' + markers[i].getAttribute('city') + ", " + markers[i].getAttribute('state') + "</div>";
            buff += '<div style="margin-bottom:4px;">' + areaPhone + '</div>';
            buff += '</div><div style="clear:both;border-bottom:1px dotted #CCC;margin:4px 0 6px 0;"></div>';

        }



        $("side_results").innerHTML = buff;
    }

    this.formSearch = function(form) {
        var args = this.buildargs(0);
        this.search('&'+args.join('&'));
    };

    this.page = function(e) {
        if (!e) e = window.event;
        var ele = e.target ? e.target : e.srcElement;
        var page = ele.id.split('_');
        var pagenum = page[page.length-1];

        var pages = document.getElementsByClassName('pages');
        for (var j=0;j<pages.length;j++) {
            var pagespan = pages[j];
            for (var i=1;i<=this.pageCount;i++) {
                var page = 'pages_'+j+'_'+i;
                if (i == pagenum) {
                    $(page).innerHTML = '<b>'+i+'</b>';
                    $(page).style.textDecoration='none';
                    $(page).style.color='black';
                } else {
                    $(page).innerHTML = i;
                    $(page).style.textDecoration='underline';
                    $(page).style.color='blue';
                }
            }
        }
        var args = this.buildargs();
        args.push('page='+pagenum);
        var sendUrl = '&';
        if (!($F('searchcity') || $('searchstate').selectedIndex > 0 || $F('searchzip'))) {
            var bounds = this.map.getBounds();
            var bounds_max = bounds.getNorthEast();
            var bounds_min = bounds.getSouthWest();
            sendUrl = '&minlat='+bounds_min.lat() + '&maxlat='+bounds_max.lat() + '&minlng='+bounds_min.lng()+'&maxlng='+bounds_max.lng()+'&';
        }
        sendUrl += args.join('&');
        this.search(sendUrl);
        try {
            Element.Extend(document.body);
            document.body.scrollTo(0);
        }catch(e){}
    };

    this.setPages = function(current,count) {
        this.pageCount = count;
        var pages = document.getElementsByClassName('pages');
        var pageDivs = document.getElementsByClassName('paginationDiv');
        if (!pages || pages.length < 1) {
            pageDivs.each(function(e){e.style.display='none'});
            return false;
        }

        var obj = this;
        for (var j=0;j<pages.length;j++) {
            var pagespan = pages[j];
            pagespan.innerHTML = '';
            for (var i=1;i<=count;i++) {
                var a = document.createElement('a');
                a.id = 'pages_'+j+'_'+i;
                a.style.textDecoration='underline';
                a.style.color='blue';
                a.style.cursor='pointer';
                a.style.padding='3px';
                a.onclick = function(e){ obj.page(e); return false; };
                if (i == current) {
                    a.innerHTML = '<b>'+i+'</b>';
                    a.style.textDecoration='none';
                    a.style.color='black';
                } else {
                    a.innerHTML = i;
                    a.style.textDecoration='underline';
                    a.style.color='blue';
                }
                pagespan.appendChild(a);
            }
        }
        pageDivs.each(function(e){e.style.display='block'});
    };

    this.buildargs = function(no_location) {
        var args = new Array();
        if (!no_location) {
            if ($('searchzip') && $F('searchzip').length) {
                args.push('zip='+$F('searchzip'));
            }
            if ($('searchziptype') && $('searchziptype').selectedIndex > 0) {
                args.push('ziptype='+$('searchziptype').options[$('searchziptype').selectedIndex].value);
            }
            if ($('searchstate').selectedIndex > 0) {
                args.push('state='+$('searchstate').options[$('searchstate').selectedIndex].value);
            }
            if ($F('searchcity') && $F('searchcity').length) {
                args.push('city='+$F('searchcity'));
            } 
        } else {
            $('searchcity').value = '';
            $('searchstate').selectedIndex = 0;
            $('searchzip').value = '';
        }
        if ($('searchlimit').selectedIndex > 0) {
            args.push('limit='+$('searchlimit').options[$('searchlimit').selectedIndex].value);
        }
        if ($('searchfoodtype').selectedIndex > 0) {
            args.push('foodtype='+$('searchfoodtype').options[$('searchfoodtype').selectedIndex].value);
        }
        if ($F('searchkeywords') && $F('searchkeywords').length) {
            args.push('keywords='+$F('searchkeywords'));    
        }
        if ($('searchrating').selectedIndex > 0) {
            args.push('rating='+$('searchrating').options[$('searchrating').selectedIndex].value);
        }
        if ($F('searchformname') && $F('searchformname').length) {
            args.push('name='+$F('searchformname'));
        }

        this.setTitle({
            foodtype: $('searchfoodtype').options[$('searchfoodtype').selectedIndex].value,
            city: $F('searchcity'),
            state: $('searchstate').options[$('searchstate').selectedIndex].value,
            zip: $F('searchzip')
        });

        return args;
    };

    this.onMoveEnd = function() {
        if (this.nomove) return false;
        var bounds = this.map.getBounds();
        var bounds_max = bounds.getNorthEast();
        var bounds_min = bounds.getSouthWest();
        var args = this.buildargs(1);
        var sendUrl = this.url + '&minlat='+bounds_min.lat() + '&maxlat='+bounds_max.lat() + '&minlng='+bounds_min.lng()+'&maxlng='+bounds_max.lng()+'&'+args.join('&');

        this.sendRequest(sendUrl+'&onMoveEnd=2');
    };
    this.onZoomEnd = function() {
        if (this.nomove) return false;
        var bounds = this.map.getBounds();
        var bounds_max = bounds.getNorthEast();
        var bounds_min = bounds.getSouthWest();
        var args = this.buildargs(1);
        var sendUrl = this.url + '&minlat='+bounds_min.lat() + '&maxlat='+bounds_max.lat() + '&minlng='+bounds_min.lng()+'&maxlng='+bounds_max.lng()+'&'+args.join('&');

        this.sendRequest(sendUrl+'&onZoomEnd=2');
    };

    // remove the old prototype's handlers
    GEvent.removeListener(this.movehandler);
    GEvent.removeListener(this.zoomhandler);
    // and add our own
    this.movehandler = GEvent.bind(this.map, "dragend", this, this.onMoveEnd);
    this.zoomhandler = GEvent.bind(this.map, "zoomend", this, this.onZoomEnd);
}
