var geograffiti = geograffiti ||
{};
geograffiti.SearcherEvent = {
    GoingToSearch: "geograffiti:goingToSearch",
    SearchStarted: "geograffiti:searchStarted",
    SearchCompleted: "geograffiti:searchCompleted",
    SearchCompletedWithFailure: "geograffiti:searchCompletedWithFailure"
};
geograffiti.Searcher = function(){
    var SearchType = {
        Content: 0,
        Filter: 1,
        UserVoiceMarks: 2,
        Tag: 3,
        AllWithTag: 4,
        None: 5
    };
    var lastSearchType = SearchType.None;
    var searcherElement = null;
    var form;
    var searchWhat = null;
    var searchWhere = null;
    var sideBar = null;
    var map = null;
    var searchResults = null;
    var SearchQuery = {
        botLeftLat: null,
        botLeftLon: null,
        topRightLat: null,
        topRightLon: null,
        zoom: null,
        searchWhat: null,
        searchWhere: null,
        offset: 0,
        centerLat: null,
        centerLon: null,
        type: null,
        filter: null,
        vid: null,
        userid: null,
        uid: null,
        isAnonymous: null,
        userNameToSearch: null,
        gid: null
    };
    var page2Offset = function(page){
        return page.offset
    };
    var updateSearchQuery = function(parameters){
        if (parameters) {
            var page = parameters.page;
            if (page) {
                SearchQuery.offset = page2Offset(page)
            }
        }
        else {
            var southWest = gg.map.getBounds().southWest;
            var northEast = gg.map.getBounds().northEast;
            SearchQuery.botLeftLat = southWest.latitude;
            SearchQuery.botLeftLon = southWest.longitude;
            SearchQuery.topRightLat = northEast.latitude;
            SearchQuery.topRightLon = northEast.longitude;
            SearchQuery.zoom = gg.map.getZoom();
            SearchQuery.searchWhat = $F(searchWhat).strip().stripTags().stripScripts();
            SearchQuery.searchWhere = $F(searchWhere).strip().stripTags().stripScripts()
        }
        var center = gg.map.getCenter();
        SearchQuery.centerLat = center.latitude;
        SearchQuery.centerLon = center.longitude
    };
    var performSearch = function(parameters){
        updateSearchQuery(parameters);
        searcherElement.fire(gg.SearcherEvent.GoingToSearch, {
            query: SearchQuery
        });
        new Ajax.Request(gg.ApiUrl.ContentSearch, {
            parameters: $H(SearchQuery),
            onSuccess: function(response){
                try {
                    lastSearchType = SearchType.Content;
                    searchResults = response.responseText.evalJSON(true);
                    if (gg.debug) {
                        gg.log("searchResults are %o", searchResults)
                    }
                    if (searchResults === null) {
                        searcherElement.fire(gg.SearcherEvent.SearchCompletedWithFailure, {
                            query: SearchQuery,
                            error: {
                                status: response.status,
                                statusText: response.statusText,
                                responseText: response.responseText
                            }
                        });
                        if (gg.debug) {
                            gg.log("AJAX call failed!!!")
                        }
                    }
                    else {
                        searcherElement.fire(gg.SearcherEvent.SearchCompleted, {
                            query: SearchQuery
                        });
                        gg.SideBar.displaySearchResults(searchResults, {
                            query: SearchQuery
                        });
                        gg.map.displayResults(searchResults)
                    }
                } 
                catch (e) {
                    searcherElement.fire(gg.SearcherEvent.SearchCompletedWithFailure, {
                        query: SearchQuery,
                        error: {
                            status: response.status,
                            statusText: response.statusText,
                            responseText: response.responseText
                        }
                    });
                    if (gg.debug) {
                        gg.log("AJAX call failed!!!")
                    }
                }
            },
            onFailure: function(response){
                searcherElement.fire(gg.SearcherEvent.SearchCompletedWithFailure, {
                    query: SearchQuery,
                    error: {
                        status: response.status,
                        statusText: response.statusText,
                        responseText: response.responseText
                    }
                });
                if (gg.debug) {
                    gg.log("AJAX call failed!!!")
                }
            }
        });
        searcherElement.fire(gg.SearcherEvent.SearchStarted, {
            query: SearchQuery
        })
    };
    var searchRequested = function(e){
        if (gg.debug) {
            gg.log("SSSSEEEEAARRRRCHHH????? --->>>>> %o", e)
        }
        e.stop();
        var memo = e.memo;
        SearchQuery.offset = 0;
        performSearch(memo);
		
		
    };
    var filterSearchRequested = function(e){
        if (gg.debug) {
            gg.log("!!!! filterSearchRequested with %o", e)
        }
        e.stop();
        var memo = e.memo;
        var page = memo.page;
        if (page) {
            SearchQuery.offset = page.offset
        }
        performSearchByFilter(memo)
    };
    var userVoiceMarksSearchRequested = function(e){
        gg.log("user vms %o", e.memo);
        e.stop();
        var memo = e.memo;
        if (typeof memo.page === "undefined") {
            var isAnonymous = e.memo.isAnonymous;
            SearchQuery.uid = isAnonymous ? null : e.memo.id;
            SearchQuery.vid = isAnonymous ? e.memo.id : null;
            SearchQuery.isAnonymous = isAnonymous;
            SearchQuery.offset = 0;
            SearchQuery.userNameToSearch = e.memo.userName
        }
        else {
            SearchQuery.offset = memo.page.offset
        }
        performSearchByUser()
    };
    var groupVoiceMarksSearchRequested = function(e){
        e.stop();
        var memo = e.memo;
        if (typeof memo.page === "undefined") {
            SearchQuery.offset = 0;
            SearchQuery.gid = e.memo.id
        }
        else {
            SearchQuery.offset = memo.page.offset
        }
        performSearchByGroup()
    };
    var performSearchByGroup = function(){
        searcherElement.fire(gg.SearcherEvent.GoingToSearch, {
            query: SearchQuery
        });
        new Ajax.Request(gg.ApiUrl.GetGroupVoiceMarks, {
            parameters: $H(SearchQuery),
            onSuccess: function(transport){
                lastSearchType = SearchType.GroupVoiceMarks;
                searcherElement.fire(gg.SearcherEvent.SearchCompleted, {
                    query: SearchQuery
                });
                var apiResponse = transport.responseText.evalJSON(true);
                gg.log("The response is %o", apiResponse);
                gg.map.displayGroupVoiceMarksResults(apiResponse);
                gg.SideBar.displayGroupVoiceMarksResults(apiResponse, {
                    query: SearchQuery
                })
            },
            onFailure: function(transport){
                searcherElement.fire(gg.SearcherEvent.SearchCompletedWithFailure, {
                    query: SearchQuery,
                    error: {
                        status: response.status,
                        statusText: response.statusText,
                        responseText: response.responseText
                    }
                });
                gg.error("ERROOORRRR %o", transport)
            }
        });
        searcherElement.fire(gg.SearcherEvent.SearchStarted, {
            query: SearchQuery
        })
    };
    var performSearchByUser = function(){
        searcherElement.fire(gg.SearcherEvent.GoingToSearch, {
            query: SearchQuery
        });
        new Ajax.Request(gg.ApiUrl.GetUserVoiceMarks, {
            parameters: $H(SearchQuery),
            onSuccess: function(transport){
                lastSearchType = SearchType.UserVoiceMarks;
                searcherElement.fire(gg.SearcherEvent.SearchCompleted, {
                    query: SearchQuery
                });
                var apiResponse = transport.responseText.evalJSON(true);
                gg.log("The response is %o", apiResponse);
                gg.map.displayUserVoiceMarksResults(apiResponse);
                gg.SideBar.displayUserVoiceMarksResults(apiResponse, {
                    query: SearchQuery
                })
            },
            onFailure: function(transport){
                searcherElement.fire(gg.SearcherEvent.SearchCompletedWithFailure, {
                    query: SearchQuery,
                    error: {
                        status: response.status,
                        statusText: response.statusText,
                        responseText: response.responseText
                    }
                });
                gg.error("ERROOORRRR %o", transport)
            }
        });
        searcherElement.fire(gg.SearcherEvent.SearchStarted, {
            query: SearchQuery
        })
    };
    var performSearchByFilter = function(memo){
        SearchQuery.type = "filter";
        searcherElement.fire(gg.SearcherEvent.GoingToSearch, {
            query: SearchQuery
        });
        new Ajax.Request(gg.ApiUrl.FilterSearch, {
            parameters: $H(SearchQuery),
            onSuccess: function(response){
                searcherElement.fire(gg.SearcherEvent.SearchCompleted, {
                    query: SearchQuery
                });
                lastSearchType = SearchType.Filter;
                if (gg.debug) {
                    gg.log("The response is %o", response)
                }
                var apiResponse = response.responseText.evalJSON(true);
                if (gg.debug) {
                    gg.log("The filter all result is %o", apiResponse)
                }
                gg.SideBar.displayFilterResults(apiResponse, {
                    query: SearchQuery
                });
                if (gg.debug) {
                    gg.log("about to call the map to filter")
                }
                gg.map.displayFilterResults(apiResponse);
                if (gg.debug) {
                    gg.log("done calling map to filte")
                }
            },
            onFailure: function(response){
                searcherElement.fire(gg.SearcherEvent.SearchCompletedWithFailure, {
                    query: SearchQuery,
                    error: {
                        status: response.status,
                        statusText: response.statusText,
                        responseText: response.responseText
                    }
                });
                if (gg.debug) {
                    gg.error("AJAX call for filter search failed with response %o", response)
                }
            }
        });
        searcherElement.fire(gg.SearcherEvent.SearchStarted, {
            query: SearchQuery
        })
    };
    var filterSelected = function(e){
        e.stop();
        var memo = e.memo;
		if (memo.filter === 0) {
			// overriding ALL to default to most recent search
			memo.filter = 4;
		}
        SearchQuery.filter = memo.filter;
		
        SearchQuery.userid = memo.userid;
        SearchQuery.vid = memo.vid;
        SearchQuery.botLeftLat = memo.botLeftLat;
        SearchQuery.botLeftLon = memo.botLeftLon;
        SearchQuery.topRightLat = memo.topRightLat;
        SearchQuery.topRightLon = memo.topRightLon;
        SearchQuery.offset = 0;
        performSearchByFilter(memo)
    };
    var performSearchByTag = function(){
        SearchQuery.type = "tag";
        searcherElement.fire(gg.SearcherEvent.GoingToSearch, {
            query: SearchQuery
        });
        new Ajax.Request(gg.ApiUrl.TagSearch, {
            parameters: $H(SearchQuery),
            onSuccess: function(response){
                lastSearchType = SearchType.Tag;
                if (gg.debug) {
                    gg.log("The response is %o", response)
                }
                var apiResponse = response.responseText.evalJSON(true);
                if (!apiResponse) {
                    searcherElement.fire(gg.SearcherEvent.SearchCompletedWithFailure, {
                        query: SearchQuery,
                        error: {
                            status: response.status,
                            statusText: response.statusText,
                            responseText: response.responseText
                        }
                    })
                }
                else {
                    searcherElement.fire(gg.SearcherEvent.SearchCompleted, {
                        query: SearchQuery
                    })
                }
                gg.SideBar.displaySearchResults(apiResponse, {
                    query: SearchQuery
                });
                if (gg.debug) {
                    gg.log("about to call the map to filter")
                }
                gg.map.displayResults(apiResponse);
                if (gg.debug) {
                    gg.log("done calling map to filter")
                }
            },
            onFailure: function(response){
                if (gg.debug) {
                    gg.error("AJAX call for filter search failed with response %o", response)
                }
                searcherElement.fire(gg.SearcherEvent.SearchCompletedWithFailure, {
                    query: SearchQuery,
                    error: {
                        status: response.status,
                        statusText: response.statusText,
                        responseText: response.responseText
                    }
                })
            }
        });
        searcherElement.fire(gg.SearcherEvent.SearchStarted, {
            query: SearchQuery
        })
    };
    var tagLinkClicked = function(e){
        e.stop();
        var memo = e.memo;
        SearchQuery.tag = memo.tag;
        SearchQuery.botLeftLat = memo.botLeftLat;
        SearchQuery.botLeftLon = memo.botLeftLon;
        SearchQuery.topRightLat = memo.topRightLat;
        SearchQuery.topRightLon = memo.topRightLon;
        SearchQuery.centerLat = memo.centerLat;
        SearchQuery.centerLon = memo.centerLon;
        SearchQuery.offset = 0;
        performSearchByTag()
    };
    var performSearchAllWithTag = function(){
        SearchQuery.type = "allwithtag";
        searcherElement.fire(gg.SearcherEvent.GoingToSearch, {
            query: SearchQuery
        });
        new Ajax.Request(gg.ApiUrl.TagSearch, {
            parameters: $H(SearchQuery),
            onSuccess: function(response){
                lastSearchType = SearchType.Tag;
                if (gg.debug) {
                    gg.log("The response is %o", response)
                }
                var apiResponse = response.responseText.evalJSON(true);
                if (!apiResponse) {
                    searcherElement.fire(gg.SearcherEvent.SearchCompletedWithFailure, {
                        query: SearchQuery,
                        error: {
                            status: response.status,
                            statusText: response.statusText,
                            responseText: response.responseText
                        }
                    })
                }
                else {
                    searcherElement.fire(gg.SearcherEvent.SearchCompleted, {
                        query: SearchQuery
                    })
                }
                gg.SideBar.displaySearchResults(apiResponse, {
                    query: SearchQuery
                });
                if (gg.debug) {
                    gg.log("about to call the map to filter")
                }
                gg.map.displayResults(apiResponse);
                if (gg.debug) {
                    gg.log("done calling map to filter")
                }
            },
            onFailure: function(response){
                if (gg.debug) {
                    gg.error("AJAX call for filter search failed with response %o", response)
                }
                searcherElement.fire(gg.SearcherEvent.SearchCompletedWithFailure, {
                    query: SearchQuery,
                    error: {
                        status: response.status,
                        statusText: response.statusText,
                        responseText: response.responseText
                    }
                })
            }
        });
        searcherElement.fire(gg.SearcherEvent.SearchStarted, {
            query: SearchQuery
        })
    };
    searchAllWithTagRequested = function(e){
        e.stop();
        var memo = e.memo;
        SearchQuery.tag = memo.tag;
        SearchQuery.botLeftLat = memo.botLeftLat;
        SearchQuery.botLeftLon = memo.botLeftLon;
        SearchQuery.topRightLat = memo.topRightLat;
        SearchQuery.topRightLon = memo.topRightLon;
        SearchQuery.centerLat = memo.centerLat;
        SearchQuery.centerLon = memo.centerLon;
        SearchQuery.offset = 0;
        performSearchAllWithTag()
    };
    var repeatLastSearchRequested = function(e){
        e.stop();
        var memo = e.memo;
        var searchQueryHash = $H(SearchQuery);
        searchQueryHash.update(e.memo);
        SearchQuery = searchQueryHash.toObject();
        switch (lastSearchType) {
            case SearchType.Content:
                performSearch({});
                break;
            case SearchType.Filter:
                performSearchByFilter();
                break;
            case SearchType.Tag:
                performSearchByTag();
                break;
            case SearchType.UserVoiceMarks:
                performSearchByUser();
                break;
            default:
                gg.warn("lastSearchType invalid!-->%d", lastSearchType);
                break
        }
    };
    var load = function(){
        searcherElement = $("searcher");
        form = $("searchform");
        searchWhat = form["searchbox-what"];
        searchWhere = form["searchbox-where"];
        sideBar = $("sidebar");
        map = $("voicemarkmap")
    };
    var initialize = function(){
        form.observe("submit", searchRequested.bindAsEventListener(this));
        sideBar.observe(gg.SideBarEvent.SearchRequested, searchRequested.bindAsEventListener(this));
        sideBar.observe(gg.SideBarEvent.FilterSearchRequested, filterSearchRequested.bindAsEventListener(this));
        sideBar.observe(gg.SideBarEvent.ListenLinkClicked, userVoiceMarksSearchRequested.bindAsEventListener(this));
        sideBar.observe(gg.SideBarEvent.UserVoiceMarksSearchRequested, userVoiceMarksSearchRequested.bindAsEventListener(this));
        sideBar.observe(gg.SideBarEvent.GroupVoiceMarksSearchRequested, groupVoiceMarksSearchRequested.bindAsEventListener(this));
        sideBar.observe(gg.SideBarEvent.ViewGroupVoiceMarksLinkClicked, groupVoiceMarksSearchRequested.bindAsEventListener(this));
        map.observe(gg.MapEvent.FilterSelected, filterSelected.bindAsEventListener(this));
        map.observe(gg.MapEvent.RepeatLastSearch, repeatLastSearchRequested.bindAsEventListener(this));
        map.observe(gg.MapEvent.TagLinkClicked, tagLinkClicked.bindAsEventListener(this));
        map.observe(gg.MapEvent.SearchAllWithTagRequested, searchAllWithTagRequested.bindAsEventListener(this));
        map.observe(gg.MapEvent.UserVoiceMarksSearchRequested, userVoiceMarksSearchRequested.bindAsEventListener(this));
    };
    load();
    initialize();
}();

