var __jackie = function() {
	var param = {}, textNodes = [];
	var gv = {
		skip : ['HTML','HEAD','META','TITLE','STYLE','SCRIPT','IFRAME','OBJECT','EMBED','A','LEGEND','BUTTON','TEXTAREA','OPTION','LABEL','PRE', 'BR', 'IMG'],
		nexus : { req:null, load:null, maxDelay:3000 },
		match : { all:[], val:[], N:0, C:0, P:0 },
		rule : { kwdCnt:5, maxCnt:15, deco:'color:#5162d5' }
	};
	var inArray = function(arr, val) {
		for (var i = 0, len = arr.length; i < len; i++) {
			if(arr[i] === val) return true;
		}
		return false;
	};
	var available = function() {
		var ua = navigator.userAgent.toLowerCase();
		var v = (navigator.vendor || '').toLowerCase();
		var p = (navigator.platform || '').toLowerCase();

		if (ua.indexOf('opera') !== -1) return false; //opera (cuz : readyState)
		if (v.indexOf('apple') !== -1 && p.indexOf('win') !== -1) return false; //safari (cuz : link escape)
		if (!Array.prototype.push) return false;
		if (!document.createDocumentFragment) return false;

		return true;
	};
	var check = function(opts) {
		if (typeof opts != 'object' || !opts.target) return false;
		if (/[^NCP]/.test(opts.kwd)) opts.kwd = 'NCP';
		if (!parseInt(opts.max)) opts.max = gv.rule.maxCnt;
		if (opts.max > gv.rule.maxCnt) opts.max = gv.rule.maxCnt;
		if (!opts.deco) opts.deco = gv.rule.deco;
		for (var prop in opts) param[prop] = opts[prop];

		return true;
	};
	var requestNexus = function() {
		var js = document.createElement('script');
		js.type = 'text/javascript';
		js.charset = 'utf-8';
		js.src = 'http://tag.daum-img.net/daumtag/tagger/?target=' + param.target.id + '&kwd=' + param.kwd + '&url=' + encodeURIComponent(window.location.href);
        js.onload = loadedNexus;
        js.onreadystatechange = function() {
			var state = this.readyState;
            if (state == 'loaded' || state == 'complete') loadedNexus();
        }

		var head = document.getElementsByTagName('head');
		if (head && head[0]) head[0].appendChild(js);
		else if (document.body) document.body.appendChild(js);
		else return;

		gv.nexus.req = new Date().getTime();
	};
	var loadedNexus = function() {
		if (!gv.nexus.load) gv.nexus.load = new Date().getTime();
		else return;

		if ((gv.nexus.load - gv.nexus.req) > gv.nexus.maxDelay) return;
		if (typeof __nexus != 'object') return;

		getTextNodes(param.target);
		findReplace();
	};
	var getTextNodes = function(ele) {
		var cNodes = ele.childNodes;
		for (var i = 0, len = cNodes.length; i < len; i++) {
			if (cNodes[i].nodeType === 1) {
				if (inArray(gv.skip, cNodes[i].nodeName)) continue;
				else arguments.callee(cNodes[i]);
			}
			if (cNodes[i].nodeType === 3 && /\S/.test(cNodes[i].nodeValue)) textNodes.push(cNodes[i]);
		}
	};
	var findReplace = function() {
		var queue = [];
		var html, span, fragment;
		for (var i = 0, len = textNodes.length; i < len; i++) {
			html = replaceKeyword(textNodes[i].nodeValue);
			if (html) queue[queue.length] = [textNodes[i], html];
		}
		for (var i = 0, len = queue.length; i < len; i++) {
			span = document.createElement('span');
			span.innerHTML = queue[i][1];

			fragment = document.createDocumentFragment();
			//fragment.appendChild(document.createTextNode(' '));
			while (span.firstChild) {
				fragment.appendChild(span.firstChild);
			}
			try {
				queue[i][0].parentNode.replaceChild(fragment, queue[i][0]);
			} catch (e) {}
		}
	};
	var overlapKeyword = function(arr, str) {
		for (var i = 0, len = arr.length; i < len; i++) {
			var kwd = arr[i];
			if (str.indexOf(kwd) !== -1 || kwd.indexOf(str) !== -1) return true;
		}
		return false;
	};
	var replaceKeyword = function(val) {
		var reg, kwd, link, title;
		var rtn = val, nil = 'nil_profile=tagkwd&nil_id=';
		gv.match.val = [];

		for (var i = 0, len = param.kwd.length; i < len; i++) {
			kwd = param.kwd.substr(i, 1);
			link = 'http://local.daum.net/map/index.jsp?';
			title = ' : À§Ä¡º¸±â';

			if (kwd == 'N' && __nexus.news) {
				reg = __nexus.news;
				link = 'http://search.daum.net/search?w=tot&';
				title = ' : °Ë»öÇÏ±â';
			}
			else if (kwd == 'C' && __nexus.company) reg = __nexus.company;
			else if (kwd == 'P' && __nexus.phone) reg = __nexus.phone;
			else continue;

			reg.lastIndex = 0;
			if (reg.test(rtn)) {
				rtn = rtn.replace(reg, function($1) {
					if (gv.match.all.length >= param.max) return $1;
					if (gv.match[kwd] >= gv.rule.kwdCnt) return $1;
					if (inArray(gv.match.all, $1)) return $1;
					if (overlapKeyword(gv.match.val, $1)) return $1;

					gv.match.all.push($1);
					gv.match.val.push($1);
					gv.match[kwd]++;

					var q = (kwd == 'N') ? encodeURIComponent($1) : escape($1);
					return '<a href="' + link + nil + kwd + '&q=' + q + '" target="_blank" title="' + $1 + title + '" style="' + param.deco + '">' + $1 + '</a>';
				});
			}
		}
		return (rtn == val) ? '' : rtn;
	};
	this.convert = function(opts) {
		if (!available()) return;
		if (!check(opts)) return;
		requestNexus();
	};
}
