//
// Autohyphen library for DOM-endabled browsers.
// Version 2003-12-02.
// (C) Dmitry Koteroff, 2003.
// http://dklab.ru
// 
// Autohyphen: class to add hyphens into the specially styled text 
// elements on the page. Also it can remove hyphens from elements.
//
// Direct usage:
// ------
// <style>
//   p  { filter:hyphenize() }
//   td { filter:hyphenize("text-align:justify") }
// </style>
// <script language=JavaScript src="Autohyphen.js"><\script>
// <body onload="new Autohyphen().hyphenizeTree(this)">
//   ...
// </body>
//
// In the second example (td element) also sets aditional style
// (justification) for those elements who was really hyphenized
// (used to avoid justification in browsers which do not support &shy;).
//
// Исходный материал
// -----------------
// Есть алгоpитм (П.Хpистова в модификации Дымченко и Ваpсанофьева),
// в котоpом заложены шесть пpавил, и они накpывают 99.99%.
// Итак, х - это одна из "ьъй", тогда пpавила:
// "х-" "г-г" "гс-сг" "сг-сг" "гс-ссг" "гсс-ссг"
// Пpименяются последовательно, в поpядке наpастания длины,
// и не надо забывать, что они могyт пеpекpываться концами.
// 
// Модификация
// -----------
// Похоже, в этом алгоритме ошибка. По крайней мере, в соответствии
// с ним будут откусываться одиночные буквы в начале и конце слов.
// Я модифицировал его так (см. ниже правила в переменной rules).
// Правила применяются к тексту по очереди, начиная С ПОСЛЕДНЕГО.
// 
function Autohyphen() { this.Autohyphen() }
Autohyphen.prototype = {
	tshy:         "&shy;",      // hyphen entity
	shy:          null,         // hyphen unicode character 
	x:            '[йьъ]',      // специальная
	g:            '[аеёиоуыэюяaeiouy]', // гласная
	s:            '(?:sh|ch|qu|[бвгджзклмнпрстфхцчшщbcdfghjklmnpqrstvwxz])', // согласная
	l:            '[ьъйаеёиоуыэюябвгджзйклмнпрстфхцчшщъьaeiouybcdfghjklmnpqrstvwxz]', // буква
	rules:        null,         // hyphenization rules
	filterName:   "hyphenize",  // name of filter style entity
	argCache:     {},

	// Constructor. Creates the new hyphenizer for element and
	// attaches the cleaner to it (to handle Copy+Paste).
	Autohyphen: function() {
		// Translate shy to Unicode char. 
		// ATTENTION: Called only once per class!
		if (Autohyphen.prototype.shy == null) with (Autohyphen.prototype) {
			var node = document.createElement("span");
			node.innerHTML = tshy;
			shy = node.childNodes[0].nodeValue; // works good
			// Prepare all the rules.
			rules = [
				[s+g, g+l],
				[g+s, s+g],
				[s+g, s+g],
				[g+s, s+s+g],
				[g+s+s, s+g],
				[g+s+s, s+s+g],
				[x, l+l],
				null
			];
		}
	},

	// Hyphenizes all properly styled child nodes of this node.
	hyphenizeTree: function (node, forceApply) {
		var children = node.childNodes;
		var apply = forceApply || this.getApplyMethod(node);
		for (var i=0, len=children.length; i<len; i++) {
			var child = children[i];
			if (child.nodeType == 3) {
				if (apply) {
					child.nodeValue = this.hyphenizeText(child.nodeValue);
					if (apply != true) node.style.cssText = apply;
				}
			} else {
				this.hyphenizeTree(child, apply);
			}
		}
	},

	// Removes hyphens from all the child nodes.
	dehyphenizeTree: function (node) {
		var children = node.childNodes;
		for (var i=0, len=children.length; i<len; i++) {
			var child = children[i];
			if (child.nodeType == 3) {
				child.nodeValue = this.dehyphenizeText(child.nodeValue);
			} else {
				this.dehyphenizeTree(child);
			}
		}
	},

	// Adds hyphens to static text.
	hyphenizeText: function (text) {
		for (var i=this.rules.length-1; i>=0; i--) {
			var ru = this.rules[i]; if (!ru) continue;
			var re = new RegExp('('+ru[0]+')(?='+ru[1]+')', 'gi')
			text = text.replace(re, '$1'+this.shy);
		}
		return text;
	},

	// Removes hyphens from static text.
	dehyphenizeText: function (text) {
		re = new RegExp(this.shy, 'g');
		return text.replace(re, "");
	},

	// Determines if this node needs to be hyphenized.
	getApplyMethod: function(elt) {
		// IE-specific!
		var filter = (elt.currentStyle || elt.style || "").filter;
		if (!filter || !filter.indexOf || filter.indexOf(this.filterName)<0) return false;
		// Extrace argument if present.
		if (new RegExp(this.filterName+"\s*(\\((.*)\\))?").exec(filter) != null) {
			var st = RegExp.$2;
			if (st) return st.replace(/^(["'])(.*)\1$/, "$2");
			return true;
		}
		return false;
	}
};
autoLH = function() { 
	$$('.block_hyphen').each(function(s) {
			new Autohyphen().hyphenizeTree(s, true);
			//s.innerHTML = new Autohyphen().hyphenizeText(s.innerHTML);
		} );	
}
//addLoadEvents( autoLH );
//window.addEvent('domready',autoLH);
document.observe("dom:loaded", autoLH); 

