// Copyright 2008, Mats Mattsson http://howaboutanorange.com

var RowStyling_taskQueue = new Array
var RowStyling_taskIsRunning = false
var RowStyling_styledElements = new Array

function RowStyling(element, styles) {
	this.element = element
	this.styles = styles
	this.origHTML = element.innerHTML
	RowStyling_styledElements.push(this)
}

function RowStyling_addTask(fun) {
	if (typeof RowStyling_onRunning == 'function' && RowStyling_taskQueue.length == 0) {
		RowStyling_onRunning(true)
	}
	RowStyling_taskQueue.push(fun)
	RowStyling_runTasks()
}
function RowStyling_completedTask() {
	if (typeof RowStyling_onRunning == 'function' && RowStyling_taskQueue.length <= 0) {
		RowStyling_onRunning(false)
	}
	RowStyling_taskIsRunning = false
	RowStyling_runTasks()
}
function RowStyling_checkLayout() {
	for (var i = 0; i < RowStyling_styledElements.length; ++i) {
		RowStyling_styledElements[i].checkLayout()
	}
	RowStyling_completedTask()	
}
function RowStyling_runTasks() {
	if (!RowStyling_taskIsRunning) {
		if (RowStyling_taskQueue.length > 0) {
			RowStyling_taskIsRunning = true
			var fun = RowStyling_taskQueue.pop()
			setTimeout(fun, 100)
		} else if (RowStyling_styledElements.length > 0) {
			RowStyling_taskIsRunning = true
			setTimeout(RowStyling_checkLayout, 3000)
		}
	}
}
function RowStyling_run() {
	RowStyling_addTask(RowStyling_checkLayout)
}

RowStyling.prototype.t = function (oA, i) {
	if (oA[i]) {
		return
	}
	
	this.element.innerHTML = this.origHTML.substring(0,i) + "<span id=\"tt_a\">&#8203;</span>" + this.origHTML.substring(i, this.i_end) + "<span id=\"tt_b\">&#8203;</span>" + this.origHTML.substr(this.i_end)
	var ea = document.getElementById("tt_a")
	var eb = document.getElementById("tt_b")
	if (ea && eb && eb.offsetLeft == this.x_end && eb.offsetTop == this.y_end) {
		oA[i] = new Array(ea.offsetTop, ea.offsetLeft)
	} else {
		oA[i] = -2;
	}
}


RowStyling.prototype.findLayout = function () {
	while (this.i >= 0) {
		var n = this.i
		var i = n
		var oA = new Array(n)
		this.t(oA,n)
		this.t(oA,0)
		
		if (oA[n][0] == oA[0][0]) {
			this.i = -1
			this.rowsStack.push(this.origHTML.substring(0,n))
			var that = this
			RowStyling_addTask(function(){that.stylizeRows()})
			RowStyling_completedTask()
		} else {
			var s = 0
			var t = n
			i = Math.floor(n/2)
			while (true) {
				var j=i+1
				this.t(oA,i)
				this.t(oA,j)
				while(oA[i]==-2) {
					--i
					this.t(oA,i)
				}
				while(oA[j]==-2) {
					++j
					this.t(oA,j)
				}
				if (oA[j][0]!=oA[i][0]&&oA[n][0]==oA[j][0]) {
					var row = this.origHTML.substring(i, this.i_end)
					this.x_end = oA[i][1]
					this.y_end = oA[i][0]
					this.i_end = i
					this.rowsStack.push(row)
					break
				} else if (oA[n][0]==oA[i][0]) {
					t = i
					i = Math.floor((t+s)/2)
				} else {
					s = i
					i = Math.floor((t+s)/2)
				}
			}
			this.i = i
		}
	}
}

RowStyling.prototype.stylizeRows = function() {
	var rowCount = this.rowCount = this.rowsStack.length
	var result = ""
	var intag = 0
	for (i=0;i<rowCount;++i) {
		var row = this.rowsStack[rowCount-1-i]
		var begintag = "<span class=\""+ this.styles[i%this.styles.length]+"\">"
		var endtag = "</span>"

		do {
			var t = row.indexOf('<')
			if (t>=0) {
				var s = row.indexOf('>')
				if (t >= 0 && s > t) {
					if (!intag) {
						result += begintag + row.substring(0, t) + endtag + row.substring(t, s + 1)
						intag=1
					} else {
						result += row.substring(0, t) + row.substring(t, s + 1)
						if (row.charAt(t+1)=='/') {
							--intag
						} else {
							++intag
						}
					}

					row = row.substring(s+1)
				}
			}
		} while (t >= 0 && row.length > 0)
		if (intag>0) {
			result += row
		} else {
			result += begintag + row + endtag
		}
	}
	var endElementId = this.element.id + "" + Math.round(1e10*Math.random()) + "_end"
	this.element.innerHTML = result + "<span id=\"" + endElementId + "\">&nbsp;</span>"

	this.endElement = document.getElementById(endElementId)
	this.x_endElement = this.endElement.offsetLeft
	this.y_endElement = this.endElement.offsetTop
	if (this.onStylingComplete) {
		var that = this
		RowStyling_addTask(function() {
			that.onStylingComplete()
			RowStyling_completedTask()
		})
	}
	RowStyling_completedTask()
}

RowStyling.prototype.checkLayout = function() {
	var layoutChanged = false
	if (!this.x_endElement || this.x_endElement != this.endElement.offsetLeft || this.y_endElement != this.endElement.offsetTop) {
		this.resetStyling()
	}
}

RowStyling.prototype.resetStyling = function() {
	this.rowsStack = new Array
	this.i = this.origHTML.length
	this.element.innerHTML = this.origHTML + "<span id=\"tt\">&#8203;</span>"
	var et = document.getElementById("tt")
	this.x_end = et.offsetLeft
	this.y_end = et.offsetTop
	this.i_end = this.origHTML.length
	this.element.innerHTML = this.origHTML
	var that = this
	RowStyling_addTask(function(){that.findLayout()})
}

RowStyling.prototype.setStyles = function(styles) {
	this.styles = styles
	var that = this
	RowStyling_addTask(function(){that.stylizeRows()})
}

RowStyling.prototype.getStyles = function() {
	return this.styles
}

RowStyling.prototype.getRowCount = function() {
	return this.rowCount
}

function RowStylingOnCompleteCreator(aa, qq, index) {
	return function () {
		var s = qq.getStyles()
		var r = qq.getRowCount() % s.length
		aa.setStyles(s.slice(s.length - r).concat(s.slice(0, s.length - r)))
	}
}

function RowStyleChildNodes(e, s) {
	var b = document.getElementById(e)
	var p = null
	for (i = 0; i < b.childNodes.length; ++i) {
		var n = b.childNodes[i]
		if (n.nodeName == "P" && !n.id) {
			var a = new RowStyling(n, s)
			if (p) {
				p.onStylingComplete = RowStylingOnCompleteCreator(a, p, i)
			}
			p = a
		}
	}
}

// Copyright 2008, Mats Mattsson http://howaboutanorange.com
