var iCab_InPageSearchInstalled = 1;
var iCab_SearchResults = 0;
var iCab_SearchLastIndex = -1;
var iCab_SearchLastTerm = "";
var iCab_InPageInspectFrames = 0;
var iCab_InPageIndexOffset = 0;
var iCab_InPageSearchTimeout = 0;
var iCab_InPageSearchExact = 0;
var iCab_SearchTimeout = 0;

/*
function Log(s)
{
	var now = new Date();
	var t = now.getTime() - 1319378385896;
	debug(t+": "+s);
}
 */


function iCab_SplitNode(win,element,startOffset,endOffset,leftBorder,rightBorder) {
	var value = element.nodeValue;
	
	if (startOffset < 0) startOffset = 0;
	if (endOffset < 0) endOffset = value.length;
	var span = win.document.createElement("span");
	var text = win.document.createTextNode(value.substr(startOffset,endOffset-startOffset));
	span.appendChild(text);
	var sidx = iCab_InPageIndexOffset + iCab_SearchResults;
	span.setAttribute("class","icabselection_"+sidx);
	span.style.backgroundColor = "#ffe";
	span.style.color = "black";
	span.style.display = "inline";
	span.style.webkitBorderRadius = "3px";
	if (leftBorder == false) {
		span.style.borderTopLeftRadius = "0 0";
		span.style.borderBottomLeftRadius = "0 0";
	}
	if (rightBorder == false) {
		span.style.borderTopRightRadius = "0 0";
		span.style.borderBottomRightRadius = "0 0";
	}
	span.style.webkitBoxShadow = "0 0 5px #441";
	span.style.position = "relative";
	span.style.zIndex = "123456";
	
	var newElement = span;
	var next = element.nextSibling;
	if (endOffset < value.length) {
		text = win.document.createTextNode(value.substr(endOffset));
		element.parentNode.insertBefore(text, next);
		next = text;
		newElement = text;
	}
	element.parentNode.insertBefore(span, next);
	if (startOffset > 0) {
		next = span;
		text = win.document.createTextNode(value.substr(0,startOffset));
		element.parentNode.insertBefore(text, next);
	}
	element.parentNode.removeChild(element);
	return newElement;
}
	

function iCab_NextNode(node, endNode)
{
	if (node == endNode) {
		return null;
	}
	if (node.nodeType != 1 || node.firstChild == null) {
		if (node.nextSibling) {
			node = node.nextSibling;
		} else {
			while (node) {
				node = node.parentNode;
				if (node == null || node == endNode) return null;
				if (node.nextSibling) {
					node = node.nextSibling;
					break;
				}
			}
		}
	} else {
		node = node.firstChild;
	}
	return node;
}


function iCab_SelectKeywordsInFrame(win, keyword, exact) {
	win.getSelection().removeAllRanges();   
	var date = new Date();
	var curDate = null;
	
	var allRanges = new Array();
	while (win.find(keyword, exact, false)) {
		var selectionObject = win.getSelection();
		allRanges.push(selectionObject.anchorNode);
		allRanges.push(selectionObject.focusNode);
		allRanges.push(selectionObject.anchorOffset);
		allRanges.push(selectionObject.focusOffset);
		var now = new Date();
		if (now.getTime() - iCab_SearchTimeout > 380) {
			break;	// Max 0.3 sec to avoid blocking
		}
	}
	var lastOffset = 0;
	var lastElement = 0;
	var newElement = 0;
	
	for (var i=0; i<allRanges.length; i+=4) {
		var startNode = allRanges[i];
		var endNode = allRanges[i+1];
		var startOffset = allRanges[i+2];
		var endOffset = allRanges[i+3];
		var sameNode = (startNode == endNode);
		
		if (newElement && lastElement == startNode) {
			if (startNode == endNode) {
				endOffset -= lastOffset;
				startNode = newElement;
				endNode = newElement;
			} else {
				startNode = newElement;
			}
			startOffset -= lastOffset;
		} else {
			lastOffset = 0;
		}
		var nodes = new Array();
		var node = startNode;
		while (node) {
			if (node.nodeType == 3) {
				nodes.push(node);
			}
			node = iCab_NextNode(node, endNode);
		}

		for (var j=0; j<nodes.length; j++) {
			var now = new Date();
			if (now.getTime() - iCab_SearchTimeout > 450) {
				return;	// Max 0.3 sec to avoid blocking
			}
			
			var soff = -1;
			var eoff = -1;
			var left = false;
			var right = false;
			if (j == 0) {
				left = true;
				soff = startOffset;
			}
			if (j == nodes.length-1) {
				right = true;
				eoff = endOffset;
			}
			var node = nodes[j];
			if (right) {
				lastElement = node;
				lastOffset = eoff;
			}
			newElement = iCab_SplitNode(win, node,soff,eoff,left,right);
			if (newElement.nodeType == 1) newElement = null;
			
			if (sameNode && newElement) {
				for (var k=i+4; k<allRanges.length; k+=4) {
					if (allRanges[k] == startNode) {
						allRanges[k] = newElement;
						allRanges[k+2] -= endOffset;
					}
					if (allRanges[k+1] == endNode) {
						allRanges[k+1] = newElement;
						allRanges[k+3] -= endOffset;
					}
				}
			}
			
		}
		iCab_SearchResults++;
	}
	if (iCab_InPageInspectFrames && win && win.frames) {
		for (var i=0; i<win.frames.length; i++) {
			var now = new Date();
			if (now.getTime() - iCab_SearchTimeout > 500) return;	// Max 0.3 sec to avoid blocking
			try {
				iCab_SelectKeywordsInFrame(win.frames[i], keyword, exact);
			} catch(e) {
			}
		}
	}	
}


function iCab_UnselectKeywordsElement(element) {
	if (element) {
		var i;
		if (element.nodeType == 1) {
			var c = element.getAttribute("class");
			if (c && c.indexOf("icabselection_") >= 0) {
				var text = element.removeChild(element.firstChild);
				var parent = element.parentNode;
				parent.insertBefore(text,element);
				parent.removeChild(element);
				return true;
			} else {
				var normalize = false;
				for (i=element.childNodes.length-1; i>=0; i--) {
					if (iCab_UnselectKeywordsElement(element.childNodes[i])) {
						normalize = true;
					}
				}
				if (normalize) {
					element.normalize();
				}
			}
		}
	}
	return false;
}


function iCab_UnselectKeywordsInFrame(win) {
	if (win && win.document) {
		iCab_UnselectKeywordsElement(win.document.body);
	}
	if (iCab_InPageInspectFrames && win && win.frames) {
		var i;
		for (i=0; i<win.frames.length; i++) {
			try {
				iCab_UnselectKeywordsInFrame(win.frames[i]);
			} catch(e) {
			}
		}
	}
}


function addDarkLayer(win) {
	if (win && win.document) {
		var darkLayer = win.document.getElementById("icabselection");
		if (!darkLayer) {
			var span = win.document.createElement("span");
			span.setAttribute("id","icabselection");
			span.style.position = "absolute";
			span.style.zIndex = "100000";
			span.style.left = "0";
			span.style.top = "0";
			span.style.backgroundColor = "rgba(32,32,0,0.08)";
			span.addEventListener("click", 
								  function() { 
									iCab_UnselectKeywords();
									var event = window.event;
									var node = win.document.elementFromPoint(event.clientX, event.clientY);
									var evObj = document.createEvent('MouseEvents');
									evObj.initMouseEvent( 'click', true, true, win, 1, event.screenX, event.screenY, event.clientX, event.clientY, event.ctrlKey, event.altKey, event.shiftKey, event.metaKey, event.button, null );
									node.dispatchEvent(evObj);
                                    iCabSearchDone();
								  });
			var w = win.document.width;
			if (w < win.document.documentElement.offsetWidth) {
				w = win.document.documentElement.offsetWidth;
			}
			var h = win.document.height;
			if (h < win.document.documentElement.offsetHeight) {
				h = win.document.documentElement.offsetHeight;
			}
			span.style.width = w + "px";
			span.style.height = h + "px";
			win.document.body.insertBefore(span, null);
		}
	}
	if (win && win.frames) {
		var i;
		for (i=0; i<win.frames.length; i++) {
			try {
				addDarkLayer(win.frames[i]);
			} catch(e) {
			}	
		}
	}
}

function removeDarkLayer(win) {
	if (win && win.document) {
		var darkLayer = win.document.getElementById("icabselection");
		if (darkLayer) {
			darkLayer.parentNode.removeChild(darkLayer);
		}
	}
	if (iCab_InPageInspectFrames && win && win.frames) {
		var i;
		for (i=0; i<win.frames.length; i++) {
			try {	
				removeDarkLayer(win.frames[i]);
			} catch(e) {
			}	
		}
	}
}


function iCab_SelectKeywords(keyword,exact,offset) {
	iCab_InPageIndexOffset = offset;
	iCab_SearchLastTerm = keyword;
	iCab_InPageSearchExact = exact;
	iCab_UnselectKeywords();
	var now = new Date();
	iCab_SearchTimeout = now.getTime();
	try {
		if (keyword && keyword.length > 0) {
			if (exact == false) {
				keyword = keyword.toLowerCase();
			}
			iCab_SelectKeywordsInFrame(window,keyword,exact);
			if (iCab_SearchResults > 0) {
				addDarkLayer(window);
			} else {
				removeDarkLayer(window);
			}
		}
	} catch(e) {
	}	
}


function iCab_UnselectKeywords() {
	if (iCab_SearchResults > 0) {
		iCab_SearchResults = 0;
		try {
			iCab_UnselectKeywordsInFrame(window);
			removeDarkLayer(window);
		} catch(e) {
		}	
	}
}



function iCab_SelectResultElement(element, cls, sel) {
	if (element) {
		if (element.nodeType == 1) {
			if (element.getAttribute("class") == cls) {
				element.style.backgroundColor = sel ? "yellow" : "#ffe";
				if (sel) element.scrollIntoViewIfNeeded(true);
//				return true;
			} else {
				var i;
				for (i=element.childNodes.length-1; i>=0; i--) {
					try {
						if (iCab_SelectResultElement(element.childNodes[i],cls,sel)) {
//							return true;
						}
					} catch(e) {
					}	
				}
			}
		}
	}
	return false;	
}

function iCab_SelectResultInWindow(win,cls,sel) {
	try {
		if (win && win.document) {
			if (iCab_SelectResultElement(win.document.body,cls,sel)) return true;
		}
		if (iCab_InPageInspectFrames && win && win.frames) {
			var i;
			for (i=0; i<win.frames.length; i++) {
				try {
					if (iCab_SelectResultInWindow(win.frames[i],cls,sel)) return;
				} catch(e) {
				}	
			}
		}
	} catch(e) {
	}	
}


function iCab_SelectResult(idx) {
	iCab_SearchLastIndex = idx;
	return iCab_SelectResultInWindow(window,"icabselection_"+idx,true);
}

function iCab_DeselectResult(idx) {
	return iCab_SelectResultInWindow(window,"icabselection_"+idx,false);
}

