/*!
 * @author Wills
 */
//jQuery.noConflict(); // prevent conflict
(function($) {
    $(function() {
        // data
        window.searchBox = window.searchBox || {};
        searchBox.baseURL = searchBox.baseURL || "/SearchBox/";
        if (searchBox.baseURL.lastIndexOf("/") + 1 < searchBox.baseURL.length) {
            searchBox.baseURL += "/";
        }
        searchBox.baseURL += "searchBox";
        searchBox.language = searchBox.language || "zh";
        searchBox.containerId = searchBox.containerId || "searchBox";
        searchBox.tooltips = !!searchBox.tooltips;
        searchBox.tooltipsButton = searchBox.tooltipsButton || null;
        searchBox.whenNoMatches = searchBox.whenNoMatches || null;
        searchBox.submitButton = searchBox.submitButton || null;
        searchBox.waitMillis = searchBox.waitMillis || 200;
        searchBox.defaultValue = searchBox.defaultValue || "";
        searchBox.autoFocus = !searchBox.defaultValue; // true is default
        if (searchBox.tooltips) {
            $.getJSON(searchBox.baseURL + "?action=tooltips&fileName=tooltips_" + searchBox.language + ".html&callback=?", function(tooltips) {
                plugins.tooltips.append(tooltips || "");
            });
        }

        // constants
        var TYPES_URLS = {
            i: null,
            p: null,
            f: null,
            c: null,
            n: null
        };

        // handle error
        // $().ajaxError(function(event, XMLHttpRequest, ajaxOptions, thrownError) {
        // });

        // init options
        $.getJSON(searchBox.baseURL + "?action=options&callback=?", function(options) {
            options = options || {};
            TYPES_URLS.i = options.internalCityURL;
            TYPES_URLS.p = options.provinceURL;
            TYPES_URLS.f = options.foreignCityURL;
            TYPES_URLS.c = options.countryURL;
            TYPES_URLS.n = options.noMatchURL;
        });

        // variables
        var textId = searchBox.containerId + "_text";
        var text = $("<input id='" + textId + "' type='text' value='" + searchBox.defaultValue + "' />");
        if (searchBox.defaultValue) {
            text.addClass("description");
        }
        var form = $("<form></form>");
        $("#" + searchBox.containerId).append(form.append(text));

        // function s
        var fill = function(items, suggestions, type) {
            if (!items || !suggestions || !suggestions.length) {
                return;
            }
            if (items.length) {
                items.push(null); // the separator
            }
            [].push.apply(items, suggestions);
        };

        // init searchBox
        var tooltipsId = "tooltips";
        var plugins = {
            tooltips: searchBox.tooltips ? $("<div id='" + tooltipsId + "'></div>") : null,
            selectedItem: null,
            isSearching: false
        };
        var updateList = function() {};
        $.suggest(textId, function(keyword, callback) {
            updateList = callback;
            if (keyword) {
                if (plugins.tooltips) {
                    plugins.tooltips.hide();
                }
                // use post but not get or getJSON, encoding ....
                $.getJSON(searchBox.baseURL + "?callback=?", {language: searchBox.language, keyword: keyword}, function(json) {
                    json = json || {};
                    var items = [];
                    // never touch the order - i p f c n
                    fill(items, json.i, "i");
                    fill(items, json.p, "p");
                    fill(items, json.f, "f");
                    fill(items, json.c, "c");
                    callback(keyword, items);
                });
            }
            else {
                callback();
                if (plugins.tooltips && plugins.tooltips.is(":not(:empty)")) {
                    plugins.tooltips.show();
                }
            }
        }, {
            waitMillis: searchBox.waitMillis,
            plugins: plugins, // the additional plugins
            // whenNoKeyword: searchBox.tooltips,
            whenNoMatches: searchBox.whenNoMatches
        });
        if (searchBox.submitButton) {
            text.after(searchBox.submitButton);
        }

        // bind event s
        var interval = 0;
        form.submit(function(event, tooltips) {
            if (tooltips) {
                return true;
            }
            else if (plugins.isSearching) {
                if (interval) {
                    clearInterval(interval);
                }
                interval = setInterval(function() {
                    if (!plugins.isSearching) {
                        clearInterval(interval);
                        interval = 0;
                        form.submit();
                    }
                }, 100);
                return false;
            }
            else {
                var textVal = text.val();
                plugins.selectedItem = (textVal && plugins.selectedItem) || {t: "n", n: textVal};
                var url = plugins.selectedItem.u || TYPES_URLS[plugins.selectedItem.t];
                if (url) {
                    url = url.replace(/\$\{LA}/g, searchBox.language || "");
                    if (plugins.selectedItem.t !== "n") {
                        form.attr("action", url.replace(/\$\{I\D\}/g, plugins.selectedItem.i));
                    }
                    else {
                        form.attr("action", url.replace(/\$\{KW\}/g, plugins.selectedItem.n));
                    }
                    return true;
                }
                else {
                    updateList(textVal, null);
                }
            }
            return false;
        });
        if (searchBox.defaultValue) {
            text.focus(function(event) {
                if ($.trim(text.val()) === searchBox.defaultValue) {
                    text.val("").removeClass("description");
                }
            }).blur(function(event) {
                if (plugins.tooltips && plugins.tooltips.is(":visible")) {
                    // nothing to do
                }
                else {
                    if (!$.trim(text.val())) {
                        text.val(searchBox.defaultValue).addClass("description");
                    }
                }
            });
        }
        if (plugins.tooltips) {
            if (searchBox.tooltipsButton) {
                var backup = searchBox.tooltipsButton;
                searchBox.tooltipsButton = $(searchBox.tooltipsButton);
                if (!searchBox.tooltipsButton.length) {
                    searchBox.tooltipsButton = $("<span></span>").append(backup);
                }
                text.after(searchBox.tooltipsButton);
                searchBox.tooltipsButton.click(function(event) {
                    if (plugins.tooltips.is(":hidden") && plugins.tooltips.is(":not(:empty)")) {
                        plugins.tooltips.show();
                        return false;
                    }
                });
            }
            text.mousedown(function(event) {
                var textVal = text.val();
                if (!textVal || textVal === searchBox.defaultValue) {
                    if (plugins.tooltips.is(":hidden") && plugins.tooltips.is(":not(:empty)")) {
                        plugins.tooltips.show();
                    }
                    else {
                        plugins.tooltips.hide();
                    }
                }
            });
            $().click(function(event) {
                var source = $(event.target);
                if (plugins.tooltips.is(":visible") && !source.is("#" + textId) && !source.closest("#" + tooltipsId).length) {
                    plugins.tooltips.hide();
                    text.blur();
                }
            });
            $("#" + tooltipsId + " .tab:not(.active)").live("click", function(event) {
                var newTab = $(event.target);
                var curTab = plugins.tooltips.find(".tab.active");
                var curTabId = curTab.attr("id") || "";
                var newTabId = newTab.attr("id") || "";
                curTab.removeClass("active");
                plugins.tooltips.find("#" + curTabId.substring(4)).hide();
                newTab.addClass("active");
                plugins.tooltips.find("#" + newTabId.substring(4)).show();
            });
            $("#" + tooltipsId + " ul li span").live("click", function() {
                var self = $(this);
                var li = self.closest("li");
                var ul = self.closest("ul");
                var url = li.attr("_url") || ul.attr("_url") || TYPES_URLS[ul.attr("_type")];
                if (url) {
                    form.attr("action", url.replace(/\$\{LA}/g, searchBox.language || "").replace(/\$\{I\D\}/g, li.attr("_id"))).trigger("submit", true);
                }
            }).live("mouseover", function(event) {
                $(this).addClass("highlight");
            }).live("mouseout", function(event) {
                $(this).removeClass("highlight");
            });
        }

        // make sure the focus can work in ie8
        if (searchBox.autoFocus) {
            setTimeout(function() {
                text.focus();
            }, 0);
        }
    });
})(jQuery);
