function invertDisplay() {
 	for (var i = 0; i < arguments.length; i++) {
		var obj = $("#"+arguments[i]);
		if(obj.css("display")=="none") {
			obj.css("display", "");
		} else {
			obj.css("display", "none");
		}
	}
	return false;
}

function expandAuthors(el) {
	var obj = $(el).parent();
	obj.find(".intmore").hide();
	obj.find(".intless").show();
}

function collapseAuthors(el) {
	var obj = $(el).parent();
	obj.find(".intless").hide();
	obj.find(".intmore").show();
}

document.onkeyup = function(e) {
	if (e == null)
		e = window.event != null ? window.event : Event;
//    Ctrl+Alt+1
	if (e.altKey && e.ctrlKey && e.keyCode == 49) {
		window.location = setParameter(""+window.location, "debug", !window.debug);
	}
}

function setParameter(href,param,value) {
	var from = href.indexOf('?');
	if (from < 0)
		return href+'?'+param+'='+value;
	var pos = href.indexOf('?'+param+'=',from);
	if (pos < 0)
		pos = href.indexOf('&'+param+'=',from);
	if (pos < 0)
		return href+'&'+param+'='+value;
	pos += param.length+2;
	if (pos >= href.length)
		return href+value;
	var tail = href.indexOf('&',pos);
	if (tail < 0)
		return href.substr(0,pos)+value;
	return href.substr(0,pos)+value+href.substr(tail);
}

function htmlEscape(s) {
	return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;");
}

/**
 * Selection.
 * @constructor
 */
function Selection(url) {
	var _selectors = null;
	var send = function(select, ids) {
		var data = {action: select ? 's':'d'};
		if (ids != null)
			data.id = ids;
		data[window.vcParam] = window.vcId;
        $.ajax({
        	url: url,
        	type: "POST",
        	cache: false,
        	data: data,
        	dataType: "text",
        	success: function(data, textStatus, xhr) {
        		var a = data.split("\n");
        		$("#selection_count").html(a[0]);
        		if (a.length > 1)
        			window.vcId = parseInt(a[1]);
        		if (a.length > 2) {
        			if (window.vcSid == '') { // was no session
        				window.vcSid = a[2];
        			} else if (window.vcSid != a[2]) { // page session != xhr session
        				update();
        				alert("Your session has expired. Previous selections (if any) have been reset.");
        			}
        		}
        		if (a.length > 3) {
        			update();
        			alert(a[3]);
        		}
        	}
        });
	};
	var updateSelector = function(el) {
		$(el).attr("src", el.sel ? el.srcOn : el.srcOff);
	    $(el).attr("title", el.sel ? "Deselect for export" : "Select for export");
	};
	var update = function() {
		var ids = [];
		_selectors.each(function(index) {
			ids.push(this.hitId);
		});
		data = {action: 'i', id: ids};
		data[window.vcParam] = window.vcId;
        $.ajax({
        	url: url,
        	type: "POST",
        	cache: false,
        	data: data,
        	dataType: "text",
        	success: function(data, textStatus, xhr) {
        		var a = data.split("\n");
        		$("#selection_count").html(a[0]);
        		if (a.length > 1)
        			window.vcId = parseInt(a[1]);
        		if (a.length > 2)
        			window.vcSid = a[2];
        		if (a.length > 3) {
        			var flags = a[3];
        			_selectors.each(function(index) {
        				this.sel = flags[index] == '1';
        				updateSelector(this);
        			});
        		}
        	}
        });
	};	
	
	return {
		init: function(selectors) {
			$("div.result-selection img").each(function(index) {
				this.srcNorm = $(this).attr("src");
				var pos = this.srcNorm.lastIndexOf('.');
				var prefix = this.srcNorm.substring(0, pos);
				var suffix = this.srcNorm.substring(pos);
				this.srcHov = prefix+"-hov"+suffix;
			}).hover(function(event) {
		    	$(this).attr("src", this.srcHov);
		    },function(event) {
		    	$(this).attr("src", this.srcNorm);
		    });
			
			_selectors = selectors;
			selectors.each(function(index) {
				var t = $(this);
		        var a = t.attr("title").split(":");
		        t.attr("title", "Select for export");
		        this.hitId = a[0];
		        this.sel = a[1] == "true";
		        this.srcOff = t.attr("src");
		        var prefix = this.srcOff.substring(0, this.srcOff.lastIndexOf('/')+1);
		        this.srcOn = prefix+"check-on.gif";
		        this.srcOnHov = prefix+"check-on-hov.gif";
		        this.srcOffHov = prefix+"check-off-hov.gif";
		        updateSelector(this);
		        t.css("visibility", "visible");
		    }).click(function(event) {
		    	this.sel = !this.sel;
		    	updateSelector(this);
		    	send(this.sel, this.hitId);
		    }).hover(function(event) {
		    	$(this).attr("src", this.sel ? this.srcOnHov : this.srcOffHov);
		    },function(event) {
		    	updateSelector(this);
		    });
			$("div.result-selection").css("visibility", "visible");
		},
		selectAll: function(select) {
			_selectors.each(function(index) {
				this.sel = select;
				updateSelector(this);
			});
			send(select);
		},
		selectPage: function(select) {
			var ids = new Array();
			_selectors.each(function(index) {
				this.sel = select;
				updateSelector(this);
				ids.push(this.hitId);
			});
			send(select, ids);
		},
		updatePage: update
	};
}

/**
 * Popup window for dialog relative to pivot.
 * @constructor
 */
function PopupDialog(dialog, pivot) {
	var t = $(dialog);
	var p = $(pivot);
	var shown = false;
	
	var _hide = function() {
		if (shown) {
			t.removeShadow();
			t.hide();
			shown = false;
		}
	};
	
	var _contains = function(ancestor, child) {
		var parent = child;
		do {
			if (parent == ancestor)
				return true;
			parent = parent.parentNode;
		} while (parent && parent.tagName.toLowerCase() != 'body' && parent.tagName.toLowerCase() != 'html');
		return false;
	};
	
	$(document).click(function(event) {
		if (shown) {
			var src = event.srcElement;
			if (!src)
				src = event.target;
			if (!_contains(dialog, src))
				_hide();
		}
		return true;
	});
	
	return {
		show: function() {
			if (!shown) {
		    	var pos = p.offset();
		    	pos.top += p.height();
				t.css("left", pos.left);
				t.css("top", pos.top);
				t.show();
				t.dropShadow({left:2, top:2});
				shown = true;
			}
		},
		hide: function() {
			_hide();
		}
	};
}

/**
 * Main Search Form related functions.
 * @constructor
 */
function MainSearchForm() {
	var f = $("#searchForm");
	var queryInput = f.find('input[name=query]');
	var authorInput = f.find('input[name=so_a]');
	var journalInput = f.find('input[name=so_j]');
	
	queryInput.focus();
    
	// default input values
    var setDefaultInputValue = function(input) {
        var value = input.attr("value");
        var title = input.attr("title");
        if ($.trim(value) == "") {
            input.attr("value", title);
            input.addClass("empty-input-field");
        }
    };
    var dropDefaultInputValue = function(input) {
        var value = input.attr("value");
        var title = input.attr("title");
        if (value == title) {
            input.attr("value", "");
            input.removeClass("empty-input-field");
        }
    };
    var initDefaultInputValue = function(input) {
        setDefaultInputValue(input);
        input.blur(function(event) {
            setDefaultInputValue($(this));
        }).focus(function(event) {
            dropDefaultInputValue($(this));
        });
    };
    initDefaultInputValue(queryInput);
    initDefaultInputValue(authorInput);
    initDefaultInputValue(journalInput);
    
    var clearField = function(input) {
        input.attr("value", "");
        setDefaultInputValue(input);
    };

    // clear form
    var clearForm = function(event) {
    	clearField(authorInput);
    	clearField(journalInput);
    	clearField(queryInput);
    	queryInput.focus();
    };
    
    f.find("a.clear-search-form").click(clearForm);

    // submit form
    f.submit(function(event) {
        dropDefaultInputValue(queryInput);
        dropDefaultInputValue(authorInput);
        dropDefaultInputValue(journalInput);
        return true;
    });

    
    // track selection for query input
    queryInput.trackSelection();

    // autocompleters
    var autocompleteHighlight = function(value, term) {
        term = term.replace(
                /([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1");
        var terms = term.split(/[^\w]+/);
        var template = "";
        for (var i = 0; i < terms.length; i++) {
            term = terms[i];
            if (term.length > 1) {
                for (var j = 0; j < term.length; j++) {
                    template = template + term.charAt(j);
                    if (j < term.length - 1) {
                        template += "[^\\s\\w]?";
                    }
                }
                template += "|";
                if (term.length == 2) {
                    template += term.charAt(0) + "\\w*[^\\w]+"
                            + term.charAt(1);
                    template += "|";
                }
            } else {
                template += term;
                template += "|";
            }
        }
        template = template.substr(0, template.length - 1);
        var pattern = new RegExp("(^|[^\\w])(" + template + ")", "gi");
        var replacement = "$1<span class='ac_highlight'>$2</span>";
        var info = value[2];
        var result = info == null || info.length == 0 ? ""
                : "<span class='ac_info' style='float:right'>(" + info + ")</span>";
        result += value[0].replace(pattern, replacement);
        return result;
    };

    var authorAutocompleteHighlight = function(value, term) {
    	var s = value[0];
    	var ranges = eval("["+value[1]+"]");
        var info = value[2];
        var result = new Array();
        if (info != null || info.length > 0)
        	result.push("<span class='ac_info' style='float:right'>(", info, ")</span>");
        var p = 0;
        for (var i = 0; i < ranges.length;) {
        	var b = ranges[i++];
        	var e = ranges[i++];
        	if (b > p)
        		result.push(htmlEscape(s.substring(p,b)));
        	result.push("<span class='ac_highlight'>", htmlEscape(s.substring(b,e)), "</span>");
        	p = e;
        }
        if (p < s.length)
        	result.push(htmlEscape(s.substring(p)));
        return result.join("");
    };

    var autocompleteFormatItem = function(row, i, max) {
        return row;
    };

    var autocompleteFormatResult = function(row) {
        var s = row[0].replace(/,/g, " ").replace(/\s\s/g, " ");
        if (s.length > 500) {
        	for (var i = 500; i > 200; i--) {
        		if (" \t.-!\"#$%&'()*+/:;<=>?@[\\]^_`{|}~".indexOf(s.charAt(i)) >= 0)
        			return s.substring(0, i);
        	}
        	return s.substring(0, 500);
        }
        return s;
    };

    authorInput.autocomplete(
            "autocomplete", {
        scroll : false,
        max : 20,
        minChars : 3,
        cacheLength : 0,
        multiple : true,
        matchContains : true,
        selectFirst : false,
        multipleSeparator : ",",
        extraParams : {
            p : "a"
        },
        formatItem : autocompleteFormatItem,
        formatResult: autocompleteFormatResult,
        highlight : authorAutocompleteHighlight
    });

    journalInput.autocomplete(
            "autocomplete", {
        scroll : false,
        max : 20,
        minChars : 3,
        cacheLength : 0,
        multiple : true,
        matchContains : true,
        selectFirst : false,
        multipleSeparator : ",",
        extraParams : {
            p : "j"
        },
        formatItem : autocompleteFormatItem,
        formatResult: autocompleteFormatResult,
        highlight : autocompleteHighlight
    });
    
    var initPowerTermsAndExamples = function() {
    	// special_terms modal
        var appendToQuery = function(value) {
            dropDefaultInputValue(queryInput);
            var queryValue = queryInput.attr("value");
            var selection = queryInput.attr("selectionTrack");
            var insertPos;
            if (selection.end == 0) {
                insertPos = 0;
            } else {
                for (insertPos = selection.end - 1; insertPos < queryValue.length; insertPos++) {
                    if (queryValue.charAt(insertPos) == ' ') {
                        insertPos++;
                        break;
                    }
                }
            }
            queryValue = queryValue.substr(0, insertPos)
                    + (insertPos > 0 && queryValue.charAt(insertPos-1).match(/\s/)==null ? " ": "") // append space at insert position 
                    + value
                    + " " // append space after insert position
                    + queryValue.substr(insertPos,
                    queryValue.length);
            queryInput.attr("value", queryValue);
            queryInput.focus();
            selection.start = selection.end = insertPos + value.length + 1;
            queryInput.refreshSelection();
        };
        $("a.special-term").click(function(event) {
            var specialTerm = $(this).text();
            appendToQuery(specialTerm);
        });

        // exec examples
        $("a.view-example").click(function(event) {
            clearForm();
            f.find('input[name=query]').attr("value", $(this).text());
            f.submit();
        });
    };

    return {
//    	clear: clearForm,
    	initPopups: initPowerTermsAndExamples
    };
}


function initSearchResult(pageHitCount) {
    //Workaround for WebKit bug
    $("input.search-button,input.filter-submit").attr("value", "");

	$(".paging-page-link,.sorting").click(function() {
		if (window.vcId > 0)
			this.href += "&"+window.vcParam+"="+window.vcId;
		return true;
	});
	
    var relsTrigger = $("#allRelationsTrigger");
    if (relsTrigger.length > 0) {
        relsTrigger[0].expand = function() {
            relsTrigger.html("Collapse All Relationships");
            $.cookie("exp_rels", "true");
            this.expanded = true;
            for (var i = 0; i < pageHitCount; i++) {
                $("#v_f" + i + "M").hide();
                $("#v_f" + i + "C").show();
            }
        };
        relsTrigger[0].collapse = function() {
            relsTrigger.html("Expand All Relationships");
            $.cookie("exp_rels", null);
            this.expanded = false;
            for (var i = 0; i < pageHitCount; i++) {
                $("#v_f" + i + "M").show();
                $("#v_f" + i + "C").hide();
            }
        };
        relsTrigger.click(function(el) {
            if (this.expanded)
                this.collapse();
            else
                this.expand();
        });
        if ($.cookie("exp_rels") == "true")
            relsTrigger[0].expand();
        else
            relsTrigger[0].collapse();
        relsTrigger.show();
    }

    $("a.hit-content-text-tools").click(function (event) {
        var href = $(this).attr("href");
        var container = $(this).parent().parent().find("div.hit-content-abstract");
        if (href != "javascript:void(0)") {
            $(this).attr("href", "javascript:void(0)");
            if (href.indexOf('#') > 0)
                href = href.substring(0, href.indexOf('#'));
            // start ajax loading
            container.load(href, null, function(responseText, responseCode, xhr) {
                if (responseCode != "success") {
                    container.html("<span class=\"error\">Full abstract is not reachable</span>");
                }
            });
        }
        $(this).parent().parent().find("*[class^=hit-content-text]").hide();
        $(this).parent().parent().find("*[class^=hit-content-abstract]").show();
        return false;
    });

    $("a.hit-content-abstract-tools").click(function (event) {
        $(this).parent().parent().find("*[class^=hit-content-text]").show();
        $(this).parent().parent().find("*[class^=hit-content-abstract]").hide();
    });

    $("a.hit-expl").click(function (event) {
        var container = $(this).parent().find("div.hit-expl-content");
        if ($(container)[0].style.display == "none") {
            var href = $(this).attr("href");
            if (href != "javascript:void(0)") {
                $(this).attr("href", "javascript:void(0)");
                // start ajax loading
                container.load(href, null, function(responseText, responseCode, xhr) {
                    if (responseCode != "success") {
                        container.html("<span class=\"error\">" + xhr.statusText + "</span>");
                    }
                });
            }
            $(container).show();
        } else {
            $(container).hide();
        }
        return false;
    });

    // Highlihting On/Off
    $("a#highlightingTrigger").click(function (event) {
        $("td.search-results-area").toggleClass('hl-off');
        var highlightingTrigger = $("td.search-results-area").hasClass("hl-off") ? "true" : null;
        $.cookie("highlightingTrigger", highlightingTrigger);
    });
    
    $("#export").each(function(index) {
    	var d = $("#exportDialog");
    	this.popup = new PopupDialog(d[0], this);
    	var f = d.find("form");
    	f[0].popup = this.popup;
    	f[0].onsubmit = function() {
    		this.elements[window.vcParam].value = window.vcId;
    		setTimeout(function() {$("#export")[0].popup.hide();}, 200);
    		return true;
    	};
    	f.find("input[type=button]").click(function(event) {
    		this.form.popup.hide();
    	});
    	f.find(".export-button").hover(function(event) {
	    	$(this).addClass("export-button-hov").removeClass("export-button");
	    },function(event) {
	    	$(this).addClass("export-button").removeClass("export-button-hov");
	    });
    }).click(function(event) {
    	var s = $("#selection_count").html();
    	var sc = s == "" ? 0 : parseInt(s);
    	var option = $("#exportSrcSel");
    	option[0].disabled = sc == 0;
    	var label = option.next();
    	label[0].disabled = sc == 0;
    	label.html(sc == 0 ? "Selected" : s+" Selected");
    	$("#exportSrcAll")[0].checked = sc == 0;
    	option[0].checked = sc > 0;
    	this.popup.show();
    	return false;
    });
}

function log(s, logId) {
	if (!window.debug)
		return;
 	if (window.console) { //Safari supports console
 		window.console.log(s);
 		return;
 	} else if (window.dump) { //Gecko supports dump
		window.dump(s);
	}
	if (logId == null)
		logId = "log";
	var el = document.getElementById(logId);
	if (el == null)
		return;
	var row = document.createElement("DIV");
	row.className = "log-item";
	var text = document.createTextNode(s);
	row.appendChild(text);
	el.appendChild(row);
	el.appendChild(row);
}

new function($) {
    $.fn.setSelectionRange = function(start, end) {
        var element = $(this).get(0);
        if (element.setSelectionRange) {
            // dom 3.0
            element.setSelectionRange(start, end);
        } else if (element.createTextRange) {
            // IE
            var range = element.createTextRange();
            range.collapse(true);
            range.moveEnd('character', end);
            range.moveStart('character', start);
            range.select();
        }
    };

	$.fn.refreshSelection = function() {
		var element = $(this).get(0);
        $(this).setSelectionRange(element.selectionTrack.start, element.selectionTrack.end);
	};

	var trackSelection = function(event) {
		var element = $(this).get(0);
		var start = element.value.length;
		var end = start;
		if (element.selectionStart != undefined) {
			// dom 3.0
			start = element.selectionStart;
			end = element.selectionEnd;
		} else if (document.selection) {
			// IE
			var r = document.selection.createRange();
			if (r == null) {
				return { start: 0, end: element.value.length, length: 0 }
			}
			var re = element.createTextRange();
			var rc = re.duplicate();
			re.moveToBookmark(r.getBookmark());
			rc.setEndPoint('EndToStart', re);
			start = rc.text.length;
			end = rc.text.length + r.text.length;
		}
		element.selectionTrack.start = start;
		element.selectionTrack.end = end;
	};

	$.fn.trackSelection = function() {
		var element = $(this).get(0);
		var position = element.value.length;
		element.selectionTrack = {start:position, end:position};
		if($.browser.msie || $.browser.opera) {
			$(this).bind("keyup", trackSelection)
					.bind("click", trackSelection)
					.bind("change", trackSelection)
					.bind("select", trackSelection);
		} else {
			$(this).bind("blur", trackSelection);
		}
	};
}(jQuery);