/* 
* If this thing is worth anything to you please donate
* http://bravelayout.scarabeo.biz/
* mailto:brave1979@o2.pl
*/
var BraveLayout = {}
// ----------- CONFIG
BraveLayout.removeEmpty = true
BraveLayout.everyNodeOnlyOnce = true
BraveLayout.getElementsByCssSelector = function(parent, selector) { return jQuery(selector, parent); }
BraveLayout.layoutsHaveCssClass = "bl";
// ----------- END OF: CONFIG


// ----------- PUBLIC
BraveLayout.start = function (layout, options) {
	options = options || {}
	options.width = options.width || '100%'
	options.height = options.height || '100%'
	
	var uid = "bl_"+Math.floor(Math.random()*100000000)+"_BraveLayout";
	document.write('<div style="display:none;" id="'+uid+'">')
	BraveLayout.toMove.push({ uid: uid, items: [] })
	var layoutRoot = BraveLayout.makeNode(layout, BraveLayout.toMove[BraveLayout.toMove.length - 1].items, undefined, undefined, options.width, options.height)
	layoutRoot.style.display = 'none'
	if(BraveLayout.layoutsHaveCssClass) {
		layoutRoot.className += " "+BraveLayout.layoutsHaveCssClass;
	}
	if(options.cls) {
		layoutRoot.className = options.cls;
	}
	if(options.id) {
		layoutRoot.id = options.id;
	}
	BraveLayout.layoutStack.push({uid: uid, root: layoutRoot});		
}
BraveLayout.end = function() {
	document.write('</div>');
	var layout = BraveLayout.layoutStack.pop();
	var layoutContentContainer = document.getElementById(layout.uid)
	layoutContentContainer.parentNode.insertBefore(layout.root, layoutContentContainer);
}
BraveLayout.fill = function() {
	for(var i=BraveLayout.toMove.length-1 ; i>=0 ; --i) {
		var layout = BraveLayout.toMove[i]
		var layoutContentContainer	= document.getElementById(layout.uid)
		var layoutRoot			= layoutContentContainer.previousSibling
	
		BraveLayout.fillOne(layout.items, layoutContentContainer, '');
		
		layoutRoot.style.display=''
		if(layoutContentContainer.parentNode) {
			layoutContentContainer.parentNode.removeChild(layoutContentContainer);
		}
	}
	BraveLayout.toMove = {};
}
// ----------- END OF: PUBLIC

// ----------- PRIVATE
BraveLayout.layoutStack = []
BraveLayout.toMove = []
BraveLayout.position = function(node, element, container) {
	if(node.x) {
		var x = node.x.split(',');
		if(x[1]!='') {
 			element.style.width = x[1];
/* 			if(x[1] == 'auto') {
 			 	var containers = node.cols
				if(containers && containers.length) {
					for(var i = containers.length-1; i>=0; --i) {
						containers[i].dontFillLast = true;
					}
 				}
 			}*/
		}
		if(node.floating) {
			element.style.marginRight = x[2]!=''?x[2]:'0';
			element.style.marginLeft = x[0]!=''?x[0]:'0';
		} else {
			container.style.paddingRight = x[2]!=''?x[2]:'0';
			container.style.paddingLeft = x[0]!=''?x[0]:'0';
		}
		if(x[0]=='') {
			element.style.marginLeft = 'auto';
			if(x[2]=='') {
				container.style.textAlign = 'center';
				element.style.marginRight = 'auto';
			} else {
				container.style.textAlign = 'right';
			}
		} else {
			element.style.marginRight = 'auto';
			container.style.textAlign = 'left';
		}
/*		if(x[1].indexOf("%")!=-1) {
			node.dontFillLast = true;
		}*/
	}
	if(node.y) {
		var y = node.y.split(',');
		if(y[1]!='') {
			element.style.height = y[1];
/* 			if(y[1] == 'auto') {
 			 	var containers = node.rows
				if(containers && containers.length) {
					for(var i = containers.length-1; i>=0; --i) {
						containers[i].dontFillLast = true;
					}
 				}
 			}*/
		}
		if(node.floating) {
			element.style.marginBottom = y[2]!=''?y[2]:'0';
			element.style.marginTop = y[0]!=''?y[0]:'0';
		} else {
			container.style.paddingBottom = y[2]!=''?y[2]:'0';
			container.style.paddingTop = y[0]!=''?y[0]:'0';
		}
		if(y[0]=='') {
			if(y[2]=='') {
				container.style.verticalAlign = 'middle';
			} else {
				container.style.verticalAlign = 'bottom';
			}
		} else {
			container.style.verticalAlign = 'top';
		}
	}
	if(node.size) {
		if(node.size == 'fill') {
			node.size = '100%';
		}
		if(node.isRow) {
			container.style.height = node.size;
//  			container.innerHTML = '<div style="height:'+node.size+'; width: 1px; overflow: hidden; margin-right: -1px; float: right; background: none;"></div>';			
/*			if(node.size.indexOf('%')!==1) {
				element.style.height = node.size;
			}*/
		
/*			if(node.size.indexOf('%')!=-1) {
				node.dontFillLast = true;
			}*/
		} else {
			container.style.width = node.size;
 			container.innerHTML = '<div style="width:'+node.size+'; '+((x!=undefined && x[0]!=undefined)?'margin-left:-'+x[0]+';':'')+((x!=undefined && x[2]!=undefined)?'margin-right:-'+x[2]+';':'')+'line-height: 1px; height: 1px; overflow: hidden; margin-top: -1px; background: none;"></div>'; // possible problem of width of columns too large when they have padding due to settting of 'x'
			
/*			if(node.size.indexOf('%')==-1) {
				element.style.width = node.size;
			}*/
/*			if(node.size.indexOf('%')!=-1) {
				node.dontFillLast = true;
			}*/
		}
	}
}
BraveLayout.makeNode = function(node, listToMove, repeat, parent, width, height) {
	width = width || '100%'
	height = height || '100%'
	var table = document.createElement('table');
	var tbody = document.createElement('tbody');
	var tr = document.createElement('tr');
	var td = document.createElement('td');
	
	tr.appendChild(td);
	tbody.appendChild(tr);
	table.appendChild(tbody);
	
	table.style.textAlign = 'left';
	var x
	if(!parent || (node.x && (x = node.x.split(',')) && (x[0].indexOf('%')!=-1 || x[2].indexOf('%')!=-1))) {
		var outerTable = document.createElement('table');
		var outerTbody = document.createElement('tbody');
		var outerTr = document.createElement('tr');
		var outerTd = document.createElement('td');
		
		outerTable.style.borderCollapse = 'collapse'
		outerTable.style.width = width
		outerTable.style.height = height
		
		outerTd.style.padding = '0';
		outerTd.style.verticalAlign = 'top';
		outerTable.style.textAlign = 'left';
 		outerTd.style.width = '100%'
		outerTd.style.height = '100%'
		
		outerTd.appendChild(table);
		outerTr.appendChild(outerTd);
		outerTbody.appendChild(outerTr);
		outerTable.appendChild(outerTbody);
		
		table.style.width = '100%'
		table.style.height = '100%'
	} else {
		var outerTable = table
		var outerTd = parent
	
		table.style.width = width
		table.style.height = height
		
	}
	
	td.style.padding = '0';
	td.style.verticalAlign = 'top';
// 	td.style.width = '100%'
	td.style.height = '100%'
	
	table.style.borderCollapse = 'collapse'
		
	
	var containers = node.rows || node.cols || node.flow
	if(typeof(node) == 'string' || (node.place != undefined)) {
		listToMove.push({ 
			selector: node.place != undefined ? node.place : node, 
			to: td, 
			repeat: repeat || table,
			subs: containers ? [] : undefined, 
			keepIfEmpty: node.keepIfEmpty, 
			clsOfContainer: node.clsOfContainer && typeof(node.clsOfContainer)!='string' ? node.clsOfContainer : undefined, 
			clsOfPlaced: node.cls && typeof(node.cls)!='string' ? node.cls : undefined, 
			container: node.clsOfContainer && typeof(node.clsOfContainer)!='string' ? outerTd : undefined,
			node: node
		});
	} else if(!containers) {
		var filler = document.createElement("div");
		filler.innerHTML = "&nbsp;"
		filler.style.overflow = "hidden";
		filler.style.height = "0px";
		filler.style.lineHeight = "1px";
		filler.style.width = "0px";
		td.appendChild(filler);
	}
	
	if(node.rows || node.cols) {
		for(var i=0;i<containers.length;++i) {
			if(i>0) {
				if(node.rows) {
					tr = document.createElement('tr');
					tbody.appendChild(tr);
				}
				td = document.createElement('td');
				td.style.padding = '0';
				td.style.verticalAlign = 'top';
//				td.style.width = '100%'
				td.style.height = '100%'
				tr.appendChild(td);
			}
			containers[i].isRow = node.rows
			td.appendChild(BraveLayout.makeNode(containers[i], node.place != undefined ? listToMove[listToMove.length-1].subs : listToMove, node.rows ? tr : td, td));
		}
	} else if(node.flow) {
		for(var i=0;i<node.flow.length;++i) {
			node.flow[i].floating = true;
			var floatedBox = BraveLayout.makeNode(node.flow[i], node.place != undefined ? listToMove[listToMove.length-1].subs : listToMove, undefined, td);
			if(navigator.userAgent.indexOf("MSIE")!=-1) {
				floatedBox.style.display = "inline";
			} else {
				if(navigator.userAgent.indexOf("Gecko")!=-1) {
					floatedBox.style.display = "block";
				}
				floatedBox.style.cssFloat = "left";
				floatedBox.align = "left";
			}
			td.appendChild(floatedBox);
		}
	}
	
	if(typeof(node.cls) == 'string') {
		table.className += ' '+node.cls;
	}
	if(typeof(node.clsOfContainer) == 'string') {
		outerTd.className += ' '+node.clsOfContainer;
	}
	BraveLayout.position(node, table, outerTd);
	
	return outerTable;	
}
BraveLayout.fillOne = function(desc, context) {
	var detached = [], toReattach = [], i, j, k, kmax, item, node, obs, lastAdded, lastPlaced
	for(i=0;i<desc.length;++i) {
		item = desc[i]
		obs = item.selector=='' ? [context] : BraveLayout.getElementsByCssSelector(context, item.selector)
		if(!obs.length) { 
			if(BraveLayout.removeEmpty && !item.keepIfEmpty) {
				detached.push({ item: item.repeat, parent: item.repeat.parentNode, after: item.repeat.previousSibling })
				item.repeat.parentNode.removeChild(item.repeat);
			} else {
				item.to.innerHTML = ''
			}
		} else {
			for(j = obs.length - 1; j >= 0 ; j--) {
				if(item.subs) {
					toReattach = BraveLayout.fillOne(item.subs, lastPlaced = obs[j]);
				} else {
					item.to.innerHTML = ''
					if(BraveLayout.everyNodeOnlyOnce) {
						obs[j].parentNode.removeChild(obs[j])
						item.to.appendChild(lastPlaced = obs[j])
					} else {
						lastPlaced = obs[j].cloneNode(true);
 						item.to.appendChild(lastPlaced)
						if(navigator.userAgent.indexOf('MSIE')!=-1) {	// ie6,ie7 deselects cloned <select>
							var selects = item.to.getElementsByTagName('select');
							for(var k=0;k<selects.length;k++) {
								var t = selects[k];
								var p = new Array();
								var nt = t;
								while(nt != item.to) {
									var nn = nt;
									var ind = 0;
									while(nn = nn.previousSibling) ind++;
									p.unshift(ind);
									nt = nt.parentNode;
								}
								var s = obs[j];
								for(var k = 1; k < p.length; k++) {
									s = s.childNodes[p[k]];
								}
								t.selectedIndex = s.selectedIndex;
							}
						}
 					}
				}
				if(item.clsOfPlaced) {
					for(var cond in item.clsOfPlaced) {
						var ok = false
						switch(cond.charAt(0) == '!' ? cond.substring(1) : cond) {
							case 'first':
								ok = j==0;
							break;
							case 'last':
								ok = j==obs.length-1;
							break;
							case 'odd':
								ok = j%2==0;
							break;
							case 'even':
								ok = j%2==1;
							break;
							case 'all':
								ok = true;
							break;
						}
						if((cond.charAt(0) == '!') ^ ok) {
							lastPlaced.className += ' '+item.clsOfPlaced[cond];
						}
					}
				}
				if(j>0) {
					item.repeat.parentNode.insertBefore(lastAdded = item.repeat.cloneNode(true), item.repeat.nextSibling);
				} else {
					lastAdded = item.repeat
				}
				if(item.repeat.tagName == "TABLE" && navigator.userAgent.indexOf('MSIE')!=-1) {
					item.repeat.parentNode.insertBefore(document.createElement("wbr"), lastAdded.nextSibling);	
				}
				if(item.clsOfContainer) {
					for(var cond in item.clsOfContainer) {
						var ok = false
						switch(cond.charAt(0) == '!' ? cond.substring(1) : cond) {
							case 'first':
								ok = j==0;
							break;
							case 'last':
								ok = j==obs.length-1;
							break;
							case 'odd':
								ok = j%2==0;
							break;
							case 'even':
								ok = j%2==1;
							break;
							case 'all':
								ok = true;
							break;
						}
						if((cond.charAt(0) == '!') ^ ok) {
							if(lastAdded.tagName == 'TR') {
								lastAdded = lastAdded.firstChild;
							}
							lastAdded.className += ' '+item.clsOfContainer[cond];
						}
					}
				}
				if(j>0) {
					for(var k = toReattach.length-1; k >= 0; k--) {
						node = toReattach[k]
						node.parent.insertBefore(node.item, node.after ? node.after.nextSibling : node.parent.firstChild);
					}
				}
			}
			
			
		}
	}
/*	if(!item.node.dontFillLast) {
		var last = item.repeat;
		if(last.tagName == 'TD') {
			if(last.parentNode) {
				console.info(last.parentNode.lastChild.style.width);
				last.parentNode.lastChild.style.width = '100%'
				console.info(last, last.parentNode.lastChild)
			} else {
				last.style.width = '100%'
			}
		} else if(last.tagName == 'TR') {
			if(item.repeat.parentNode) {
				last.parentNode.lastChild.firstChild.style.height = '100%' 
			} else {
				last.firstChild.style.height = '100%'
			}
		}
	} else {
	}*/
	return detached
}
// ----------- END OF: PRIVATE

