/* ------------------------------------------------------------------------
	map by segment
	
	developed By: dean huntley
	Version: 1.0
	
	modified by: matt feury
	may 09 for UMCOM
	
	Copyright: Feel free to redistribute the script/modify it, as
			   long as you leave my infos at the top.
------------------------------------------------------------------------- */

(function($) {

    $.fn.mapBySeg = function(vars) {
        callerid = $(this);
        var self = this;
        addresses = [];
        addressLink = [];
        addressMarker = [];
        numGeocoded = 0;

        //get map params
        ctrlat = (vars.ctrlat != undefined) ? vars.ctrlat : 41.26; 	//default Omaha, NE
        ctrlong = (vars.ctrlong != undefined) ? vars.ctrlong : -95.94; //default Omaha, NE
        zoomlevel = (vars.zoomlevel != undefined) ? vars.zoomlevel : 4;
        var serverpath = (vars.serverpath != undefined) ? vars.serverpath : "http://master.umc.org/spheremaps/";
        maxzoomlevel = (vars.maxzoomlevel != undefined) ? vars.maxzoomlevel : 11;
        var filtering = (vars.filter != undefined) ? vars.filter : false;
        var debugMode = (vars.debugMode != undefined) ? vars.debugMode : false;
        var waitToBubble = (vars.waitToBubble != undefined) ? (vars.waitToBubble * 1000) : 15000;
        segment = vars.segment;
        lastname = ($('#lastname').val() != '') ? $('#lastname').val() : vars.lastname;
        firstname = ($('#firstname').val() != '') ? $('#firstname').val() : vars.firstname;
        searchcity = ($('#city').val() != '') ? $('#city').val() : vars.city;
        searchstate = ($('#state').val() != '') ? $('#state').val() : vars.state;
        var refresh = (vars.refresh == "1") ? vars.refresh : "";
        runnow = (vars.runnow != undefined) ? vars.runnow : false;
        showrightcol = (vars.showrightcol != undefined) ? vars.showrightcol : true;
        usetemplate = (vars.usetemplate != undefined) ? vars.usetemplate : false;
        userctemplate = (vars.userightcoltemplate != undefined) ? vars.userightcoltemplate : false;
        templatedata = '';
        var badLinks = false;
        //        var popupTimer;
        //store template in datastring
        if (vars.templatedata) {
            for (var key in vars.templatedata) {
                templatedata += vars.templatedata[key]; //store template in 1 long string
            }
        }
        if (usetemplate && templatedata == '') {
            alert('Error: params usetemplate set to true but no template data specified!\nusetemplate set to false');
            usetemplate = false;
        }
        rctemplatedata = '';
        //store template in datastring
        if (vars.rightcoltemplatedata) {
            for (var key in vars.rightcoltemplatedata) {
                rctemplatedata += vars.rightcoltemplatedata[key]; //store template in 1 long string
            }
        }
        if (userctemplate && rctemplatedata == '') {
            alert('Error: params userightcoltemplate set to true but no template data specified!\nuserightcoltemplate set to false');
            userctemplate = false;
        }
        autobubblepopup = (vars.autobubblepopup != undefined) ? vars.autobubblepopup : false;
        autobubblepopupinterval = (vars.autobubblepopupinterval != undefined) ? (vars.autobubblepopupinterval * 1000) : 10000;
        if (vars.bubbleheight != undefined) templateheight = "<style>#mapPopupInfo {height:" + vars.bubbleheight + "px !important}</style>";
        if (vars.bubblewidth != undefined) templatewidth = "<style>#mapPopupInfo {width:" + vars.bubblewidth + "px !important}</style>";

        if (filtering) {
            $('#loading, #loadingstatus').show();
            $('#loadingstatus')[0].innerHTML = "<div>Filtering ...</div><div><img src='http://master.umc.org/spheremaps/images/ajax-loader.gif' /></div>";
        }

        var buildMap = function() {
            googlemap = new GMap2($("#map")[0]);
            //this.googlemap.addMapType(G_SATELLITE_3D_MAP);
            //this.googlemap.setMapType(G_SATELLITE_3D_MAP);
            googlemap.setMapType(G_NORMAL_MAP);
            //centered on Omaha, NE
            googlemap.setCenter(new GLatLng(ctrlat, ctrlong), zoomlevel);
            googlemap.addControl(new GLargeMapControl());
            googlemap.addControl(new GMapTypeControl());

            geocoder = new GClientGeocoder();
            geocoder.setCache(null);
            var mt = googlemap.getMapTypes();
            // Overwrite the getMinimumResolution() and getMaximumResolution() methods
            for (var i = 0; i < mt.length; i++) {
                mt[i].getMinimumResolution = function() { return zoomlevel; }
                mt[i].getMaximumResolution = function() { return maxzoomlevel; }
            }
            //GEvent.addListener(googlemap, 'zoomend', function(oldZoomLevel, newZoomLevel) { 
            //  console.log(oldZoomLevel + ' ' + newZoomLevel);
            //  if(newZoomLevel < maxzoomlevel) { 
            //	 googlemap.zoomTo(Math.max(oldZoomLevel, maxzoomlevel)); 
            //  } 
            //});			
        }

        // If the map position is out of range, move it back
        checkBounds = function() {
            // Perform the check and return if OK
            if (allowedBounds.contains(googlemap.getCenter())) {
                return;
            }
            // It`s not OK, so find the nearest allowed point and move there
            var C = googlemap.getCenter();
            var X = C.lng();
            var Y = C.lat();

            var AmaxX = allowedBounds.getNorthEast().lng();
            var AmaxY = allowedBounds.getNorthEast().lat();
            var AminX = allowedBounds.getSouthWest().lng();
            var AminY = allowedBounds.getSouthWest().lat();

            if (X < AminX) { X = AminX; }
            if (X > AmaxX) { X = AmaxX; }
            if (Y < AminY) { Y = AminY; }
            if (Y > AmaxY) { Y = AmaxY; }
            //alert ("Restricting "+Y+" "+X);
            googlemap.setCenter(new GLatLng(Y, X));
        }

        getData = function() {
            if (showrightcol) {
                divrightcol = $('#results')[0];
                divrightcol.innerHTML = '';
                var span = document.createElement('span');
                span.innerHTML = "<div id=\"resultHeader\"><h3><span class='mapstatus'>Contacts Displayed</span></h3></div>";
                $('#results').before(span);
            }
            $('#loadingstatus')[0].innerHTML = "<div>Loading Map Data ...</div><div><img src='http://master.umc.org/spheremaps/images/ajax-loader.gif' /></div>";
            setTimeout(function() { if ($('#loadingstatus')[0].innerHTML.match("Loading Map Data")) $('#loadingstatus')[0].innerHTML = "<div>Still working, please be patient ...</div><div><img src='http://master.umc.org/spheremaps/images/ajax-loader.gif' /></div>"; }, 26000);
            contactCount = 0;
            numGeocoded = 0;
            googlemap.clearOverlays();
            geocoder.setCache(null);
            addresses = [];
            allMarkersArray = new Array();
            setTimeout(function() { getAddressData() }, 50);
        }

        /* This function is c/o Lokkju and is distributed
        freely from the google/apis/maps/ discussion group. */
        GMap2.prototype.addOverlays = function(a) {
            var b = this;
            for (i = 0; i < a.length; i++) {
                try {
                    this.overlays.push(a[i]);
                    a[i].initialize(this);
                    a[i].redraw(true);
                } catch (ex) {
                    //alert('err: ' + i + ', ' + ex.toString());
                }
            }
            this.reOrderOverlays();
        };

        var resolveAddress = function() {

            if (numGeocoded < addresses.length) {

                //add em to the map
                if (addresses[numGeocoded]['lat'] == '' || addresses[numGeocoded]['lat'] == '0') {
                    geocoder.getLocations(addresses[numGeocoded]['mappoint'], addressResolved);
                } else {
                    addPoint();
                }
            } else {
                //clear loading
                //googlemap.addOverlays(allMarkersArray);
                //zebra stripe
                $('div:visible > .contactlist').parent(":odd").addClass("zebra");

                $('#loading, #loadingstatus').hide();
                $('.mapstatus')[0].innerHTML = contactCount + " Contacts Displayed";
                if (filtering) {
                    $(".mapstatus").append(" (FILTERED)");

                }
                if (autobubblepopup) {
                    bubblepopup();
                    popupTimer = setInterval(function() { bubblepopup() }, autobubblepopupinterval);
                }
                if (badLinks) {
                    badLinkNotifier();
                }

            }
        }

        var bubblepopup = function() {
            var rndm = (pickRandom(contactCount - 1) + 1);
            //if not marker found then get next random number
            if (addressMarker[rndm] == undefined) setTimeout(function() { bubblepopup(); }, 600);
            else {
                var marker = addressMarker[rndm].marker;
                marker.openInfoWindowHtml(addressMarker[rndm].html);
                //popupTimer = setTimeout(function() { bubblepopup() }, autobubblepopupinterval);
            }
        }

        var badLinkNotifier = function() {
            if (debugMode) {
                $("#container").prepend("<div id=\"badLinks\"><h3>Attention</h3><div class=\"error\"><img src=\"http://master.umc.org/spheremaps/images/cross.gif\" /></div><div class=\"errorMessage\">Unmappable entries were found. They have been highlighted.<br><span class=\"options\"><a href=\"#\" class=\"toggle\">Toggle unmappables</a> | <a href=\"#\" class=\"closeNotif\">Close this notification</a></span></div></div>");
                $("#results").css("height", "350px");
            }
        }

        var clearAllIntervals = function() {
            clearInterval(popupTimer);
            clearTimeout(popupInterval);
        }

        var pauseBubble = function() {
            //alert("cleared");
            clearAllIntervals();
            //alert(popupInterval + " __ " + popupTimer);
            popupInterval = setTimeout(function() {
                bubblepopup();
                popupTimer = setInterval(function() { bubblepopup() }, autobubblepopupinterval);
            }, 15000);
        }

        var addressResolved = function(response) {
            var delay = 0;
            if (response.Status.code == 620) {
                // Too fast, try again, with a small pause
                delay = 50;
            } else {
                if (response.Status.code == 200) {
                    // Success; do something with the address.
                    var place = response.Placemark[0];
                    var point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);
                    var marker = new GMarker(point);
                    allMarkersArray.push(marker);
                    googlemap.addOverlay(marker);
                    var html = addresses[numGeocoded]['mapdata'];
                    var count = numGeocoded;
                    //map point
                    var geoclick = GEvent.addListener(marker, "click", function() {
                        marker.openInfoWindowHtml(html);
                        pauseBubble();
                    });
                    //right col links
                    addressMarker[numGeocoded] = {};
                    addressMarker[numGeocoded].marker = marker;
                    addressMarker[numGeocoded].html = html;
                    addressLink[numGeocoded].onclick = function() {
                        marker.openInfoWindowHtml(html);
                        pauseBubble();
                    }
                    contactCount++;
                } else {
                    //bad response code
                    //INVALID ADDRESS
                    if (addressLink[numGeocoded] != '') {
                        badLinks = true;
                        $(addressLink[numGeocoded]).hide();
                        if (debugMode) {
                            $(addressLink[numGeocoded]).prepend("<div class=\"error\"><img src=\"http://master.umc.org/spheremaps/images/cross.gif\" /></div>");
                            $(addressLink[numGeocoded]).addClass("bad");
                            $(addressLink[numGeocoded]).show();
                        }
                    }
                }
                // Move onto the next address; this skips bad addresses, too.
                numGeocoded++;
            }

            setTimeout(function() { resolveAddress() }, delay);

        }

        var addPoint = function() {

            addresses[numGeocoded]['']
            var point = new GLatLng(addresses[numGeocoded]['lat'], addresses[numGeocoded]['long']);
            var marker = new GMarker(point);
            googlemap.addOverlay(marker);
            allMarkersArray.push(marker);
            var html = addresses[numGeocoded]['mapdata'];
            var count = numGeocoded;
            //map point
            var geoclick = GEvent.addListener(marker, "click", function() {
                marker.openInfoWindowHtml(html);
                pauseBubble();
            });
            //right col links
            addressMarker[numGeocoded] = {};
            addressMarker[numGeocoded].marker = marker;
            addressMarker[numGeocoded].html = html;
            addressLink[numGeocoded].onclick = function() {
                marker.openInfoWindowHtml(html);
                //                alert("clear " + popupTimer);
                pauseBubble();
                //                alert("done " + popupTimer);
            }
            contactCount++;
            numGeocoded++;
            resolveAddress();
        }

        var passParameters = function(item) {

            var itPassed = true;
            if (item['LastName'] != null)
            { if (item['LastName'].toLowerCase().match(lastname.toLowerCase()) == null) itPassed = false; }
            if (item['FirstName'] != null)
            { if (item['FirstName'].toLowerCase().match(firstname.toLowerCase()) == null) itPassed = false; }
            if (item['PrimaryAddressCity'] != null)
            { if (item['PrimaryAddressCity'].toLowerCase().match(searchcity.toLowerCase()) == null) itPassed = false; }
            if (item['primaryStateString'] != null)
            { if (item['primaryStateString'].toLowerCase().match(searchstate.toLowerCase()) == null) itPassed = false; }

            return itPassed;
        }

        var showReminder = function(contents) {
            var cacheDiv = "<div class=\"clear\"></div>";
            cacheDiv += "<div class=\"bottomReminder\">" + contents + "<img src=\"http://master.umc.org/spheremaps/images/delete.gif\" class=\"closeReminder\" /></div>";
            $("#output").after(cacheDiv);
            $(".bottomReminder").slideDown("slow");
        }

        var removeCustomTags = function(html) {
            //removes [any] tags from html
            var replaceWith = "";
            var findAll = new RegExp('(\\[.*?\\])');
            html = html.replace(findAll, replaceWith);

            //remove double line breaks
            replaceWith = "<br />";
            findAll = "<br /><br />";
            html = html.replace(findAll, replaceWith);

            //remove double breaks caused by block level headers
            replaceWith = "</h3>";
            findAll = "</h3><br />";
            html = html.replace(findAll, replaceWith);

            return html;
        }

        var getAddressData = function() {
            clearAllIntervals();
            var inputParms = 'segment=' + segment;

            inputParms += '&lastname=' + lastname;
            inputParms += '&firstname=' + firstname;
            inputParms += '&city=' + searchcity;
            inputParms += '&state=' + searchstate;
            inputParms += '&refreshdata=' + refresh;
            if (location.href.indexOf("refreshdata") > 0) inputParms += "&refreshdata";
            //inputParms += '&country='+$('#country')[0].value;
            //				$.getJSON(connectpath+'/getContactRecords_byseg_gbcs.php?'+inputParms+'&callback=?', function(data){
            //              $.getJSON('Default.aspx?'+inputParms+'&callback=?', function(data){
            $.jsonp({
                url: serverpath + 'Default.aspx?' + inputParms + '&callback=?',
                error: function(d, msg) {
                    $('#loadingstatus, #loading').hide();
                    //alert(d + msg);
                    var err = "<b> Error while attempting to read segment. </b>";
                    //if (x.status.toString() == '500')
                    //err += "Is this a valid segment ID?";
                    showReminder(err);
                },
                success: function(data) {
                    //alert("got it");
                    var empty;
                    var problem;
                    if (typeof (data.contacts[0]) != "object") {
                        empty = true;
                        problem = "none";
                    }
                    var z = 0;
                    var contactsFound = true;
                    //alert("found em");
                    $.each(data.contacts, function(index, item) {
                        //alert("each" + data.contacts);
                        if (empty != true) {
                            //alert("if");
                            if (item['jsonID'] == "CACHED" && !filtering) {
                                var conts = "This a cached copy of the specified segment. Each cache is regenerated daily. Force a refresh <a href=\"#\" onclick=\"makeMap(false,'1')\">by clicking here</a>.";
                                showReminder(conts);
                            }
                            $("#currentName").html(item['segName']);
                            $("#currentSegment").html(item['segID']);
                            if (item['FirstName'] != undefined && passParameters(item)) {
                                var html = "<span id='mapPopupInfo'>";
                                if (usetemplate) {
                                    html += templateheight;
                                    html += templatewidth;
                                    html += templatedata;
                                    for (key in item) {
                                        if (item[key] != null && key != "customfields") {
                                            //replace elements in template data
                                            var strcheck = new RegExp("\\[" + key + "\\]", "g");
                                            var repstr = (item[key] != 'Unknown' && item[key] != null) ? item[key] : '';
                                            html = html.replace(strcheck, repstr);
                                        }
                                    }
                                    //customfields
                                    if (item['customfields'] != null) {
                                        $.each(item['customfields'], function(cindex, citem) {
                                            //alert("custom fields " + item['customfields']);
                                            if (citem['Value'] != undefined) {

                                                var strcheck = new RegExp("\\[" + citem['FieldID'] + "\\]", "g");
                                                var repstr = (citem['Value'] != 'Unknown') ? citem['Value'].toString() : '';
                                                html = html.replace(strcheck, repstr);
                                            }
                                        });
                                    }
                                } else {
                                    html += "<div id='contactDetails'><h3>" + item['FirstName'] + ' ' + item['LastName'] + "</h3>";
                                    if (item['PrimaryAddressState'] != "Unknown")
                                        html += item['PrimaryAddressLine1'] + "<br />" + item['PrimaryAddressCity'] + ", " + item['primaryStateString'] + " " + item['PrimaryAddressZip'] + "</div>";
                                    else
                                        html += item['PrimaryAddressLine1'] + "<br />" + item['PrimaryAddressCity'] + ", " + item['primaryCountryString'] + " " + item['PrimaryAddressZip'] + "</div>";
                                }
                                html += "</span>";
                                html = removeCustomTags(html);
                                if (showrightcol) {
                                    if (userctemplate) {
                                        var divid = document.createElement('div');
                                        var rchtml = rctemplatedata;
                                        for (key in item) {
                                            if (item[key] != null && key != "customfields") {
                                                //replace elements in template data
                                                var strcheck = new RegExp("\\[" + key + "\\]", "g");
                                                var repstr = (item[key].toString() != 'Unknown') ? item[key].toString() : '';
                                                rchtml = rchtml.replace(strcheck, repstr);
                                            }
                                        }
                                        if (item['customfields'] != null) {
                                            $.each(item['customfields'], function(cindex, citem) {
                                                if (citem['Value'] != undefined) {
                                                    var strcheck = new RegExp("\\[" + citem['FieldID'] + "\\]", "g");
                                                    var repstr = (citem['Value'].toString() != 'Unknown') ? citem['Value'].toString() : '';
                                                    rchtml = rchtml.replace(strcheck, repstr);
                                                }
                                            });
                                        }
                                        rchtml = removeCustomTags(rchtml);
                                        //only show ones with proper addresses
                                        if (rchtml.indexOf("PrimaryAddressLine1") < 0) {
                                            divid.innerHTML = rchtml;
                                            divrightcol.appendChild(divid);
                                            $(divid).attr("style", "cursor:pointer");
                                            addressLink[z] = divid;
                                        } else {
                                            addressLink[z] = '';
                                        }

                                    } else {
                                        var divid = document.createElement('div');
                                        divid.className = "contactlist";
                                        var href = document.createElement('a');
                                        href.innerHTML = item['FirstName'] + ' ' + item['LastName'];
                                        href.href = 'javascript:void(0);';
                                        divid.appendChild(href);
                                        addressLink[z] = divid;
                                        var divid2 = document.createElement('div');
                                        divid2.className = "contactAddress";
                                        if (item['primaryStateString'] != "Unknown")
                                            divid2.innerHTML = item['PrimaryAddressLine1'] + "<br/>" + item['PrimaryAddressCity'] + ", " + item['primaryStateString'] + " " + item['PrimaryAddressZip'] + "<br />";
                                        else
                                            divid2.innerHTML = item['PrimaryAddressLine1'] + "<br/>" + item['PrimaryAddressCity'] + ", " + item['primaryCountryString'] + " " + item['PrimaryAddressZip'] + "<br />";
                                        divid.appendChild(divid2);
                                        $(divid).attr("style", "cursor:pointer");
                                        divrightcol.appendChild(divid);
                                    }
                                } else {
                                    addressLink[z] = '';
                                }
                                if (item['PrimaryAddressLine1'] != undefined) {

                                    if (item['primaryStateString'] == "DistrictofColumbia") {
                                        var primaryStateString = "DC";
                                    } else {
                                        var primaryStateString = item['primaryStateString'];
                                    }

                                    addresses[z] = [];
                                    if (primaryStateString != "Unknown" && primaryStateString != "")
                                        addresses[z]['mappoint'] = item['PrimaryAddressLine1'] + ", " + item['PrimaryAddressCity'] + ", " + primaryStateString + " " + item['PrimaryAddressZip'];
                                    else if (item['primaryCountryString'] != "UnitedStates" && item['primaryCountryString'] != "Unknown")
                                        addresses[z]['mappoint'] = item['PrimaryAddressLine1'] + " " + item['PrimaryAddressLine2'] + " " + item['PrimaryAddressCity'] + ", " + item['primaryCountryString'] + " " + item['PrimaryAddressZip'];
                                    else if (item['PrimaryAddressLine2'] != "" && item['PrimaryAddressLine2'] != null)
                                        addresses[z]['mappoint'] = item['PrimaryAddressLine1'] + " " + item['PrimaryAddressLine2'] + ", " + item['PrimaryAddressCity'] + ", " + item['primaryCountryString'] + " " + item['PrimaryAddressZip'];
                                    else
                                        addresses[z]['mappoint'] = item['PrimaryAddressLine1'] + ", " + item['PrimaryAddressCity'] + " " + item['PrimaryAddressZip'];

                                    addresses[z]['mapdata'] = html;

                                    var temp = [];
                                    temp[0] = "0";
                                    temp[1] = "0";



                                    if (item['TaxIDNumber'] != undefined) {
                                        temp = item['TaxIDNumber'].split(',');
                                    }
                                    addresses[z]['lat'] = (item['lat'] != undefined) ? item['lat'] : temp[0];
                                    addresses[z]['long'] = (item['lon'] != undefined) ? item['lon'] : temp[1];
                                    //alert(addresses[z]['lat']+", "+addresses[z]['long']);
                                    z++;


                                }
                            }
                        } else {
                            contactsFound = false;
                        }
                    });
                    if (contactsFound) {
                        resolveAddress();
                        $('#loadingstatus')[0].innerHTML = "<div>Adding Map Points ...</div><div><img src='http://master.umc.org/spheremaps/images/ajax-loader.gif' /></div>";
                    } else {
                        $('#loadingstatus, #loading').hide();

                        if (problem == "none") {
                            var err = "No Contacts Found";
                        } else {
                            var err = "There was an error processing the map data.<br /><br />Please alert us if this is error consistently occurs";
                        }

                        $('#results').append(err);
                    }
                }
            });
        }

        var pickRandom = function(range) {
            if (Math.random)
                return Math.round(Math.random() * (range - 1));
            else {
                var now = new Date();
                return (now.getTime() / 1000) % range;
            }
        }

        //build Map
        buildMap();
        if (runnow) getData();


    };

})(jQuery);  

