﻿/**
 * Pinyin Tooltip
 *
 * @author hooriza@nhncorp.com
 * @version 0.1
 *
 * @created Nov.2.2007.
 */
 var Pinyin = {
	
	_ajax : new Include(),
	_overEl : null,
	
	_cache : {},
	_pinyin : null,
	
	_toEntity : function(sStr) {
		
		var sEntity = '';
		
		for (var i = 0, nLen = sStr.length; i < nLen; i++)
			sEntity += '&#' + sStr.charCodeAt(i) + ';';
			
		return sEntity;
	
	},

	_toChar : function(sEntity) {
		
		var self = this;
		
		return sEntity.replace(/&#([0-9]+);/g, function(sAll, sNum) {
			
			var sHex = self._decToHex(parseInt(sNum, 10));
			for (var i = 0, nLen = 4 - sHex.length; i < nLen; i++) sHex = '0' + sHex;

			return eval('"\\u' + sHex + '"');
			
		});
		
	},

	_decToHex : function(nNum) {
		
		var sHex = '';
		var aHexes = [ 'A', 'B', 'C', 'D', 'E', 'F' ];
		
		do {
			var n = nNum % 16;
			sHex = (n >= 10 ? aHexes[n - 10] : String(n)) + sHex;
			nNum = parseInt(nNum / 16);
		} while (nNum);
		
		return sHex;
		
	},
		
	show : function(oEl, oEvent) {
		
		var self = this;
		var sHanyi = oEl.textContent || oEl.innerHTML;
		
		oEl.style.backgroundColor = 'yellow';
		this._setLayerText(sHanyi, 'Loading');
		
		var oLayer = this._getLayer();
		oLayer.style.marginTop = oEl.offsetHeight + 5 + 'px';

		this._overEl = oEl;

		setTimeout(function() {
			
			if (!self._overEl) return;

			oLayer.style.display = 'inline';
			oEl.parentNode.insertBefore(oLayer, oEl);

			self._request(sHanyi);
			
		}, 0); // FF 버그
		
		
	},
	
	hide : function(oEl) {
		
		this._ajax.abort();
		
		this._getLayer().style.display = 'none';
		oEl.style.backgroundColor = '';
		
		this._overEl = null;
		
	},
	
	_getLayer : function() {
		
		if (!this._pinyin) {
			this._pinyin = document.createElement('div');
			this._pinyin.className = 'pinyin';
			this._pinyin.innerHTML = '<h3></h3><p></p>';
			
			document.body.insertBefore(this._pinyin, document.body.firstChild);
		}
		
		return this._pinyin;
		
	},
	
	_request : function(sHanyi) {
		
		var self = this;
		
		if (this._cache[sHanyi]) {
			this._setLayerText(null, this._cache[sHanyi]);
			return;
		}
		
		var sQuery = this._toEntity(sHanyi);
		var sUrl = 'http://hooriza.com/jsonp/pinyin.php?chinese=' + encodeURIComponent(sQuery);
		
		this._ajax.request(sUrl, function() { return self._receive.apply(self, arguments); });
		
	},
	
	_setLayerText : function(sHanyi, sPinyin) {
		
		var oLayer = this._getLayer();

		var oHanyi = oLayer.getElementsByTagName('h3')[0];
		var oPinyin = oLayer.getElementsByTagName('p')[0];
		
		if (navigator.userAgent.indexOf('MSIE') > -1) { // IE 면

			if (sHanyi) oHanyi.innerText = sHanyi;
			if (sPinyin) oPinyin.innerText = this._toChar(sPinyin);

		} else {
			
			if (sHanyi) oHanyi.innerHTML = sHanyi;

			if (sPinyin) {
				sPinyin = sPinyin.replace(/\//g, '<span class="seperator">/</span>');
				oPinyin.innerHTML = sPinyin;
			}
			
		}
				
	},
	
	_receive : function(sPinyin) {
		
		var oEl = this._overEl;
		var sHanyi = oEl.textContent || oEl.innerHTML;
		
		this._cache[sHanyi] = sPinyin;
		this._setLayerText(null, sPinyin);

	},

	_backup : function(sStr) {

		var fpUnique = function(sPrefix) { return (sPrefix || '') + new Date().getTime() + parseInt(Math.random() * 10000000); };
		var oReplace = Pinyin._keys = {};

		do {
			bChanged = false;
			sStr = sStr.replace(/(<[^\u4E00-\u9FFF>]*)([\u4E00-\u9FFF]+)(.*>)/g, function(_, sPre, sStr, sPost) {

				bChanged = true;

				var sUniq = fpUnique('S');
				oReplace[sUniq] = sStr;

				return sPre + sUniq + sPost;
			});

		} while (bChanged);

		return sStr;

	},

	_restore : function(sStr) {

		var oReplace = Pinyin._keys;

		for (var k in oReplace)
			sStr = sStr.replace(k, oReplace[k]);

		return sStr;

	},

	_transform : function(oEl) {

		var sStr = this._backup(oEl.innerHTML);

		sStr = sStr.replace(/([\u4E00-\u9FFF]+)/g, '<span class="hanyi" onmouseover="Pinyin.show(this, event);" onmouseout="Pinyin.hide(this);">$1</span>');
		sStr = this._restore(sStr);

		oEl.innerHTML = sStr;

	} 
	
};
