var suggest = {
    
    url          : "http://suggestqueries.google.com/complete/search?hl=ja&client=suggest&hjson=t&",
    
    on_suggest   : false,

    complete     : true,

    keywords     : new Array(),

    target_boxes : new Array(),

    target       : "",

    check_time   : null,

    check_text   : "",

    first_click : true,

    keyposition  : 0,

    init : function()
    {
        var suggest_tbl  = document.createElement("table");
        suggest_tbl.setAttribute("id", "suggest_tbl");
        suggest_tbl.style.zIndex = '100';
        var nodes_number = document.body.childNodes.length - 1;
        var last_nodes = document.body.childNodes[nodes_number];
        while (last_nodes.tagName == "script") {
            nodes_number--;
            last_nodes = document.body.childNodes[nodes_number];
        }
        document.body.insertBefore(suggest_tbl, last_nodes.nextSibling);
        this.setEventListener();
    },

    setEventListener : function ()
    {
        var suggest_tbl  = document.getElementById("suggest_tbl");
        var scripts      = document.getElementsByTagName("script");
        var text_boxes   = document.getElementsByTagName("input");
        var target_regex = new RegExp();

        var bind = function(i,e)
        {
            if (e.addEventListener) {
                e.addEventListener("focus", function(event) { suggest._focus(event, suggest.target_boxes[i]) }, false);
                e.addEventListener("keyup", function(event) { suggest.setKeyup(event, suggest.target_boxes[i]) }, false);
                e.addEventListener("keydown", function(event) { suggest.setKeydown(event, suggest.target_boxes[i]) }, false);
                e.addEventListener("blur", function(){ suggest._blur() }, false);
            } else if (e.attachEvent) {
                e.attachEvent("onkeyup", function(event) { suggest.setKeyup(event, suggest.target_boxes[i]) });
                e.attachEvent("onkeydown", function(event) { suggest.setKeydown(event, suggest.target_boxes[i]) });
                e.attachEvent("onblur", function(){ if(!suggest.on_suggest) suggest_tbl.style.visibility = "hidden" }, false);
            }
 
        }

        for (var i = 0; i < scripts.length; i++) {
            if (scripts[i].getAttribute("src") && scripts[i].getAttribute("src").match(/suggest.js/)) {
                scripts[i].getAttribute("src").match(/\?target=(.*?)$/);
                target_regex = new RegExp(RegExp.$1.replace(',','|'));
                break;
            }
        }
        for (var i = 0; i < text_boxes.length; i++) {
            if (text_boxes[i].getAttribute("id") && text_boxes[i].getAttribute("id").match(target_regex)) {
                this.target_boxes.push(text_boxes[i]);
            }
        }

        for (var i = 0; i < this.target_boxes.length; i++) {
            bind(i, this.target_boxes[i]);
        }

    },

    _focus : function(event, text_box)
    {
        var suggest_tbl = document.getElementById("suggest_tbl");
        if (this.first_click) {
            this.check_text = text_box.value;
            this.first_click = false;
        }
        if ((suggest_tbl.style.visibility == "visible" || this.check_text != text_box.value) && this.keyposition == 0) {
            var query = encodeURIComponent(text_box.value);
            var count = text_box.value.length;
            this.setScript(query, count);
        }
        this.check_text = text_box.value;
        this.check_time = window.setTimeout(function(){ suggest._focus(event, text_box) }, 100);
    },

    _blur : function()
    {
         var suggest_tbl       = document.getElementById("suggest_tbl");
         if(!suggest.on_suggest) suggest_tbl.style.visibility = "hidden";
         this.first_click = true;
         clearTimeout(this.check_time);
    },

    setKeydown : function(event, text_box)
    {
        var tbl       = document.getElementById("suggest_tbl");
        var text      = text_box.value;
        var query     = encodeURIComponent(text);
        var count     = text.length;
        this.target   = text_box.getAttribute("id");

        if (event.keyCode == 229) {
            this._focus(event, text_box);
            return false;
        }

        if (text == "" || event.keyCode == 27) {
            tbl.style.visibility = "hidden";
        } else {
            //keypositionの変化 ループ
            switch (event.keyCode) {
            case(46):   //delete
                if (text == this.keywords[0]) return true;
                break;
            case(37):   //left
                return false;
                break;
            case(39):   //right
                if (suggest.keyposition == 0) return true;
                break;
            case(38):   //up
                if (!this.keywords[0]) {
                    this.complete = false;
                    this.setScript(query, count);
                }
                this.keyPositionUp(text_box);
                tbl.style.visibility = "visible";
                text = this.keywords[this.keyposition];
                return false;
                break;
            case(40):   //down
                if (!this.keywords[0]) {
                    this.complete = false;
                    this.setScript(query, count);
                }   
                this.keyPositionDown(text_box);
                tbl.style.visibility = "visible";
                text  = this.keywords[suggest.keyposition];
                return false;
                break;
            case(13): //enter
                if (this.keyposition != 0) {
                    tbl.style.visibility = "hidden";
                    return false;
                }
                break;
            case(8):
            case(32):
                break;
            case(144):
            case(145):
                return false;
                break;
            default:
                break;
            }
            this.setScript(query, count);
        }
      
    },

    setKeyup : function(event, text_box)
    {
        var tbl       = document.getElementById("suggest_tbl");
        var text      = text_box.value;
        var query     = encodeURIComponent(text);
        var count     = text.length;
        this.target   = text_box.getAttribute("id");
       
        if (text == "" || event.keyCode == 27) {
            tbl.style.visibility = "hidden";
        } else {
            //keypositionの変化 ループ
            switch (event.keyCode) {
            case(46):   //delete
                if (text == this.keywords[0]) return true;
                break;
            case(37):   //left
            case(38):   //up
            case(40):   //down
                return false;
                break;
            case(13): //esc
                if (this.keyposition != 0) {
                    tbl.style.visibility = "hidden";
                    return false;
                }
                break;
            case(8):
            case(32):
                break;
            case(144):
            case(145):
                return false;
                break;
            default:
                break;
            }
            this.setScript(query, count);
        }
       
    },

    setScript : function(query, count)
    {
        suggest.keyposition = 0;
        if (document.getElementById("g_suggest")) {
            document.getElementById("g_suggest").parentNode.removeChild(document.getElementById("g_suggest"));
        }
        var e = document.createElement('script');
        e.setAttribute("id", "g_suggest");
        e.setAttribute("type", "text/javascript");
        e.setAttribute("src", this.url + "jsonp=suggest.view&q=" + query + "&cp=" + count);
        document.getElementsByTagName("head").item(0).appendChild(e);
    },
 
    keyPositionUp : function(text_box)
    {
        if (!this.complete) {
            window.setTimeout(function(){suggest.keyPositionUp(text_box)}, 10);
            return false;
        }
        var tbody = document.getElementById("suggest_tbl").childNodes.item(0);
        for (var i = 0; i < tbody.childNodes.length; i++) {
            tbody.childNodes.item(i).childNodes.item(0).className = "suggest_list_a";
        }
        if (suggest.keyposition == 0) {
            suggest.keyposition = this.keywords.length - 1;
            text_box.value = this.keywords[this.keywords.length - 1];
            tbody.childNodes.item(suggest.keyposition - 1).childNodes.item(0).className = "suggest_list_b"; 
        } else if (suggest.keyposition == 1) {
            suggest.keyposition = suggest.keyposition - 1; 
            text_box.value = this.keywords[suggest.keyposition];
        } else {
            suggest.keyposition = suggest.keyposition - 1;
            text_box.value = this.keywords[suggest.keyposition];
            tbody.childNodes.item(suggest.keyposition - 1).childNodes.item(0).className = "suggest_list_b"; 
        }
    },

    keyPositionDown : function(text_box)
    {
        if (!this.complete) {
            window.setTimeout("suggest.keyPositionDown", 10, text_box);
            return false;
        } 
        var tbody = document.getElementById("suggest_tbl").childNodes.item(0);
        for (var i = 0; i < tbody.childNodes.length; i++) {
            tbody.childNodes.item(i).childNodes.item(0).className = "suggest_list_a";
        }
        if (suggest.keyposition == this.keywords.length - 1) {
            suggest.keyposition = 0;
            text_box.value = this.keywords[0];
        } else {
            suggest.keyposition = suggest.keyposition + 1;
            text_box.value = this.keywords[suggest.keyposition];
            tbody.childNodes.item(suggest.keyposition - 1).childNodes.item(0).className = "suggest_list_b";
        }
        
    },

    view : function(data)
    {
        var tbl      = document.getElementById("suggest_tbl");
        var text_box = document.getElementById(this.target);
        var position = this.getElementPosition(text_box);
        tbl.style.top         = (position["top"] + 27) + "px";
        tbl.style.left        = (position["left"] + 1) + "px";
        this.keywords.shift();
        this.setList(data);
        this.keywords.unshift(data[0]);
        tbl.style.width      = text_box.offsetWidth;
        tbl.style.visibility = "visible";
        this.complete = true; 
    },

    setList : function(data)
    {
        var tbl      = document.getElementById("suggest_tbl");
        var tbody    = document.createElement("tbody");
        var text_box = document.getElementById(this.target);
        
        var clickListEvent = function(i)
        {
            text_box.value = suggest.keywords[i];
            var parent_form = text_box.parentNode;
            while (parent_form.tagName != "FORM") {
                if (parent_form.tagName == "BODY")  {
                    return false;    
                }
                parent_form = parent_form.parentNode;
            }
            var target_file = parent_form.getAttribute("action");
            var inputs      = parent_form.getElementsByTagName("input");
            var param       = '?';
            for (var i = 0; i < inputs.length; i++) {
                if (inputs[i].getAttribute('name') || inputs[i].value) {
                    if (i > 0) param = param + '&';
                    param = param + inputs[i].getAttribute('name') + '=' + inputs[i].value;
                }
            }
            document.getElementById("suggest_tbl").style.visibility = "hidden";
            location.href = target_file + param;
        };
        
        var suggestOver = function(e, position)
        {
            var tbody = document.getElementById("suggest_tbl").childNodes.item(0);
            for (var i = 0; i < tbody.childNodes.length; i++) {
                tbody.childNodes.item(i).childNodes.item(0).className = "suggest_list_a";
            }
            e.className = "suggest_list_b";
            suggest.keyposition = position;
        };
        
        var bind = function(i,e)
        {
            if (e.addEventListener) {
                e.addEventListener("click", function(){ clickListEvent(i + 1); }, false);
                e.addEventListener("mouseover", function(){ suggest.on_suggest = true; suggestOver(e, i + 1); }, false);
                e.addEventListener("mouseout", function(){ suggest.on_suggest = false; }, false);
            } else {
                e.attachEvent("onclick", function(){ clickListEvent(i + 1); });
                e.attachEvent("onmouseover", function(){ suggest.on_suggest = true; suggestOver(e, i + 1); }, false);
                e.attachEvent("onmouseout", function(){ suggest.on_suggest = false; }, false);
            }
        };
        tbl.appendChild(tbody);
        this.keywords = new Array();
         for (var i = 0; i < data[1].length; i++) {
            var tr = document.createElement("tr");
            var td = document.createElement("td");
            td.className = "suggest_list_a";
            td.innerHTML = data[1][i][0];
            tr.appendChild(td);
            tbody.appendChild(tr);
            this.keywords[i] = data[1][i][0];
            bind(i,td);
        }
        tbl.removeChild(tbl.childNodes.item(0));
        tbl.appendChild(tbody);
    },

    getElementPosition : function(element) {
        var offsetTrail = (typeof element == 'string') ? document.getElementById(element) : element;
        var offsetLeft = 0;
        var offsetTop = 0;

        while (offsetTrail) {
            offsetLeft += offsetTrail.offsetLeft;
            offsetTop += offsetTrail.offsetTop;
            offsetTrail = offsetTrail.offsetParent;
        }

        if (navigator.userAgent.indexOf('Mac') != -1 && typeof document.body.leftMargin != "undefined") {
            offsetLeft += document.body.leftMargin;
            offsetTop += document.body.topMargin;
        }

        if (/*@cc_on!@*/false) {
            offsetLeft -= 1;    
            offsetTop  -= 1;    
        }

        return ({left: offsetLeft, top: offsetTop});
    },

    otherClick : function()
    {
        if (!suggest.on_suggest) {
            document.getElementById("suggest_tbl").style.visibility = "hidden";
        }
    }
};

if (window.addEventListener) {
    window.addEventListener("load", function(){ suggest.init(); }, false);
} else if(window.attachEvent) {
    window.attachEvent("onload", function(){ suggest.init(); });
}
