/*
Para que un subtemplate sea parseado, debe haber un contenido dinamico
de nombre igual del pseudotag del subtemplate pero con show. precediendo al sub. que valga TRUE. 
Si no, no se parsea.

Es decir:
<%sub.pseudotag%> --> aqu� se coloca un subtemplate parseado
TemplateParser.dynamicContent["show.sub.pseudotag"] --> indicador de si un subtemplate debe ser parseado
*/
LNV.templateParser = (function () {
	var templatesDir 		= "",
		pseudotagRegexp		= "<%[^<%>]+%>",
		callbackIndicator	= "templateparsed",
		templates			= [],
		dynamicContent		= [],
		
		validate = function () {
			return (templatesDir !== "" && pseudotagRegexp !== "");
		},
	
		_setDynamicContent = function (contentName, contentValue) {
			dynamicContent[contentName] = contentValue;
		},
	
		_parseTemplate = function (templateName) {
			var stringToBeParsed = templates[templateName],
				pseudotags = [],
				matchRegex = new RegExp(pseudotagRegexp, "gi"),
				pseudotagsLength,
				x,
				pseudotagName,
				dyncontentName,
				rege,
				contenido;
			pseudotags = stringToBeParsed.match(matchRegex);
			if (pseudotags) {
				pseudotagsLength = pseudotags.length;
				for (x = 0; x < pseudotagsLength; x = x + 1) {
					pseudotagName = pseudotags[x].substr(2);
					pseudotagName = pseudotagName.substr(0, pseudotagName.length - 2);
					/* Si comienzo con sub. es un subtemplate */
					if (pseudotagName.search("sub.") > -1) {
						if (!templates[pseudotagName]) {
							templates[pseudotagName] = LNV.ajax({
								url: templatesDir + pseudotagName + '.html',
								async: false,
								dataType: 'text'
							});
						}
						if (dynamicContent["show." + pseudotagName] === true) {
							_setDynamicContent(pseudotagName, _parseTemplate(pseudotagName));
						} else {
							_setDynamicContent(pseudotagName, "");
						}
					}
					dyncontentName = pseudotags[x].replace(/\./g, "\\.");
					rege = new RegExp(dyncontentName, "g");
					contenido = (dynamicContent[pseudotagName]) ? dynamicContent[pseudotagName] : '';
					stringToBeParsed = stringToBeParsed.replace(rege, contenido);
				}
			}
			return stringToBeParsed;
		},
	
		_parse = function (templateName, targetBlock, callback) {
			callback = callback || function () {};
			if (validate()) {
				if (templates[templateName]) {
					targetBlock.innerHTML = _parseTemplate(templateName);
					callback(callbackIndicator);
				} else {
					var target_url = templatesDir + templateName + ".html";
					LNV.ajax({
						url: target_url,
						dataType: 'text',
						success: function (result) {
							templates[templateName] = result;
							_parse(templateName, targetBlock);
							callback(callbackIndicator);
						}
					});
				}
			}
		};
	
	return {
		setTemplateDir: function (dir) {
			templatesDir = dir;
		},
		
		setRegexp: function (regex) {
			pseudotagRegexp = regex;
		},

		parseTemplate: _parseTemplate,
		
		parse: _parse,
		
		setDynamicContent: _setDynamicContent,
		
		removeDynamicContent: function (contentName) {
			dynamicContent[contentName] = null;
		},
		
		appendDynamicContent: function (contentName, contentValue) {
			dynamicContent[contentName] += contentValue;
		}
	};
}());

/*
Lenovo Tabs Script
Author: Juan Ignacio Dopazo (jdopazo@lenovo.com)
Owner: Diego Darriba (darrbad@lenovo.com)

The objective of this script is to provide unobtrusive use of tabs, capable of loading content with AJAX
while providing a good alternative when javascript is disabled (also useful for SEO purposes). It should:

- Work with existing markup
- Generate markup dinamically
- Load content with AJAX
- Have custom events that allow for history management and other systems to interact with it
- Interact well with other markup inside its area of effect, so as to have a (+) sign for adding tabs, for instance

Custom events are:
- Before: fires before an ajax operation. It doesn't fire if the content was cached or if there wasn't an ajax operation
- After: fires after an ajax operation. It doesn't fire if the content was cached or if there wasn't an ajax operation

------------------------
Implementation:

Each Tabs instance contains a "tabCollection" array which holds objects 
with the tab's information (url in case it uses ajax, label, content, etc).
Each object also contains a reference to the HTML element for the label (li) and content (div).
These references can be found in:

tabCollection[tabIndex].listElement
tabCollection[tabIndex].contentElement


@requires LNV.core
@requires LNV.events
@requires LNV.util.dom
@requires LNV.util.ajax
*/
LNV.widget.Tabs = function (target, settings) {
	if (this instanceof LNV.widget.Tabs) {
		
		settings = settings || {};
		
		var before = settings.before, 
			after  = settings.after || function () {}, 
			
		currentTabIndex = 0,
		
		dom = LNV.util.dom,
		
		/* classes names for better minification */
		FIRST_CLASS 			= "first",
		LAST_CLASS				= "last",
		CURRENT_CLASS			= "current",
		CURRENT_FIRST_CLASS		= "current-first",
		CURRENT_LAST_CLASS		= "current-last",
	
		/* All the tab object references */
		tabCollection = [],
		
		target = (target.constructor == String) ? LNV.get(target) : target,
		
		tabListHolder, tabContentHolder,
		
		isRendered = false,
		
		cache = {},
		
		loadContent = function (tab) {
			var onSuccess = function (result) {
				tab.contentElement.innerHTML = result;
				if (tab.cache) {
					cache[tab.url] = result;
				}
			};
			/* check if its already cached */
			if (tab.cache && cache[tab.url]) {
				tab.contentElement.innerHTML = cache[tab.url];
			} else {
				if (tab.loadingHTML) {
					tab.contentElement.innerHTML = tab.loadingHTML;
				}
				if (before) {
					before();
				}
				if (tab.url) {
					LNV.util.ajax({
						url: tab.url,
						dataType: "text",
						success: onSuccess,
						complete: after
					});
				} else if (tab.xml) {
					LNV.util.xsl.transform(tab.xml, tab.xsl, null, tab.contentElement);
				}
			}
		},
		
		updateList = function (index) {
			var i,
				le,
				cb;

			for (i = 0; i < tabCollection.length; i++) {
				le = tabCollection[i].listElement;
				cb = tabCollection[i].contentElement;
				if (le != this) {
					if (i === 0) {
						dom.addClass(le, FIRST_CLASS);
						dom.removeClass(le, CURRENT_FIRST_CLASS);
					} else if (i === tabCollection.length - 1) {
						dom.addClass(le, LAST_CLASS);
						dom.removeClass(le, CURRENT_LAST_CLASS);
					} else {
						dom.removeClass(le, CURRENT_CLASS);
						dom.removeClass(le, FIRST_CLASS);
						dom.removeClass(le, LAST_CLASS);
					}
					dom.hide(cb);
				} else {
					if (i === 0) {
						dom.removeClass(le, FIRST_CLASS);
						dom.addClass(le, CURRENT_FIRST_CLASS);
					} else if (i === tabCollection.length - 1) {
						dom.removeClass(le, LAST_CLASS);
						dom.addClass(le, CURRENT_LAST_CLASS);
					} else {
						dom.addClass(le, CURRENT_CLASS);
					}
					dom.show(cb);
					currentTabIndex = i;
				}
			}
		},

		/* Function attached to the onClick event of each A in a tab */
		clickHandler = function (index) {
			if (index != currentTabIndex) {
				updateList.call(this, index);
				if (tabCollection[index].url || (tabCollection[index].xml && tabCollection[index].xsl)) {
					loadContent(tabCollection[index]);
				}
			}
		},
		
		getIsCurrent = function (tab) {
			return dom.hasClass(tab, CURRENT_CLASS) || 
					dom.hasClass(tab, CURRENT_FIRST_CLASS) || 
					dom.hasClass(tab, CURRENT_LAST_CLASS);
		};
		
		this.getCurrentTab = function () {
			return this.getTab(currentTabIndex);
		};
		
		this.getTab = function (tabIndex) {
			return tabCollection[tabIndex];
		};
		
		this.getTabIndex = function (tab) {
			return LNV.indexOf(tab, tabCollection);
		};
		
		this.addTab = function (tab, index) {
			index = index || tabCollection.length;	
			tabCollection.splice(index, 0, tab);
			if (isRendered) {
				this.render();
			}
		};
		
		this.removeTab = function (tabIndex) {
			if (tabIndex.constructor == Object) {
				tabIndex = this.getTabIndex(tabIndex);
			}
			tabCollection.splice(tabIndex, 1);
			if (isRendered) {
				var listItem = tabContentHolder.childNodes[tabIndex];
				tabContentHolder.removeChild(listItem);
				tabListHolder.removeChild(tabListHolder.childNodes[tabIndex]);
			}
		};

		this.selectTab = function (index) {
			clickHandler.call(tabCollection[index].listElement, index);
		};
		
		/* Initializes the object and starts caching if required */
		this.render = function () {
			isRendered = true; /* flag as rendered */
			
			var listElement,
				listLink,
				tabContent,
				list		= tabListHolder.getElementsByTagName("li"),
				contents	= tabContentHolder.childNodes,
				i,
				callback;
				
			for (i = 0; i < tabCollection.length; i++) {
				/* if the tab object in the collection doesn't have references to the HTML elements, create them */
				if (!tabCollection[i].listElement) {
					listElement = dom.create("li");
					listLink	= dom.create("a");
					
					listLink.innerHTML = tabCollection[i].label;
					listLink.href = tabCollection[i].href || "#";
					listElement.appendChild(listLink);
					
					callback = (function (le, index) {
						return function () {
							clickHandler.call(le, index);
						};
					}(listElement, i));
					LNV.events.add(listLink, 'click', callback, true);
					LNV.events.add(listLink, 'focus', callback, true);
	
					if (i >= tabCollection.length - 1) {
						tabListHolder.appendChild(listElement);
					} else {
						tabListHolder.insertBefore(listElement, list[i]);
					}
					tabCollection[i].listElement = listElement;
				}
				if (!tabCollection[i].contentElement) {
					tabContent = dom.create("div");
					
					if (tabCollection[i].content) {
						tabContent.innerHTML = tabCollection[i].content;
					}
					
					if (i >= tabCollection.length - 1) {
						tabContentHolder.appendChild(tabContent);
					} else {
						tabContentHolder.insertBefore(tabContent, contents[i]);
					}
					
					dom.hide(tabContent);

					tabCollection[i].contentElement = tabContent;
				}
			}
			
			updateList.call(tabListHolder.getElementsByTagName("li")[currentTabIndex]);
		};
		
		this.getListHolder = function () {
			return tabListHolder;
		};
		
		this.getContentHolder = function () {
			return tabContentHolder;
		};
		
		/* initialization */
		(function () {
			var list = target.childNodes,
				i,
				contents = [],
				current = 0,
				callback;
			for (i = 0; i < list.length; i++) {
				if (list[i].nodeName.toLowerCase() == "ul") {
					tabListHolder = list[i];
				} else if (list[i].nodeName.toLowerCase() == "div") {
					tabContentHolder = list[i];
				}
			}
			if (!tabContentHolder) {
				tabContentHolder = dom.create("div");
				target.appendChild(tabContentHolder);
			}
			if (!tabListHolder) {
				tabListHolder = dom.create("ul");
				dom.addClass(tabListHolder, "clear");
				target.insertBefore(tabListHolder, tabContentHolder);
			}
			list = tabListHolder.getElementsByTagName("li");
			for (i = 0; i < tabContentHolder.childNodes.length; i++) {
				if (tabContentHolder.childNodes[i].nodeType == 1) {
					contents[contents.length] = tabContentHolder.childNodes[i];
				}
			}
			for (i = 0; i < list.length; i++) {
				if (list[i].getElementsByTagName("a")[0] && contents[i]) {
					 tabCollection[tabCollection.length] = {
						 label: list[i].getElementsByTagName("a")[0].firstChild.nodeValue,
						 content: contents[i].innerHTML,
						 current: getIsCurrent(list[i]),
						 contentElement: contents[i],
						 listElement: list[i]
					 };
					 
					 callback = (function (index) {
						 return function () {
						 	clickHandler.call(list[index], index);
						 };
					 }(i));
					 LNV.events.add(list[i].getElementsByTagName("a")[0], 'click', callback, true);
					 LNV.events.add(list[i].getElementsByTagName("a")[0], 'focus', callback, true);
				}
				if (dom.hasClass(list[i], CURRENT_CLASS) || dom.hasClass(list[i], CURRENT_FIRST_CLASS) || dom.hasClass(list[i], CURRENT_LAST_CLASS)) {
					current = i;
				}
			}
			updateList.call(list[current], current);
			if (list.length > 0) {
				isRendered = true;
			}
		}());
		
	} else {
		return new LNV.widget.Tabs();
	}
};

LNV.widget.Pager = function (params) {
	/*	
	params - object to store initialization parameters
	params.elementCount - number of elements
	params.elementsPerPage - number of elements per page
	*/
	params.previous 		= params.previous 			|| "anterior"; /* frase o simbolo que indica ir hacia atras */
	params.next 			= params.next 				|| "siguiente"; /* frase o simbolo que indica ir hacia adelante */
	this.currentPage 		= params.currentPage 		|| 1;
	var shownElements 		= params.shownElements 		|| 5,
		callbacks			= params.callback	|| function () {},
	
		instances = [];
	
	this.write = function (blockId, callback) {
		var targetBlock = LNV.get(blockId),
			block = document.createElement("div"),
			href = "",
			anterior,
			numeroPaginas,
			inicio,
			ifinal,
			i,
			pagina,
			espacio,
			siguiente;
		if (this.currentPage > 1) {
			anterior = document.createElement("a");
			href = ['javas', 'cript: ', callback, '(', (this.currentPage - 1), ');'];
			anterior.setAttribute("href", href.join(''));
			anterior.innerHTML = params.previous;
			block.appendChild(anterior);
		}
		numeroPaginas = LNV.math.roundUp(params.elementCount / params.elementsPerPage);
		inicio = this.currentPage - shownElements / 2 - shownElements % 2 / 2 > 0 ?
					this.currentPage - shownElements / 2 - shownElements % 2 / 2 :
					1;
		ifinal = inicio + shownElements - 1 <= numeroPaginas ? inicio + shownElements - 1 : numeroPaginas;
		if (numeroPaginas > 1) {
			for (i = inicio; i <= ifinal; i = i + 1) {
				if (i !== this.currentPage) {
					pagina = document.createElement("span");
					href = ['javas', 'cript: ', params.pageFunctionName, "(", i, ");"];
					pagina.setAttribute("href", href.join(''));
				} else {
					pagina = document.createElement("span");
				}
				pagina.innerHTML = i;
				block.appendChild(pagina);
			}
		} else {
			espacio = document.createElement("span");
			espacio.innerHTML = "&nbsp;";
			block.appendChild(espacio);
		}
		if (this.currentPage < numeroPaginas) {
			siguiente = document.createElement("a");
			href = ["javas", "cript: ", params.pageFunctionName, "(", (this.currentPage + 1), ");"];
			siguiente.setAttribute("href", href.join(''));
			siguiente.innerHTML = params.next;
			block.appendChild(siguiente);
		}
		targetBlock.innerHTML = block.innerHTML;
	};
	
	this.addInstance = function (instanceId) {
		if (LNV.inArray(instanceId, instances) === false) {
			instances.push(instanceId);
		}
	};
	
	this.removeInstance = function (instanceId) {
		var i = 0,
			instancesLength = instances.length;
		while (i < instancesLength) {
			if (instances[i] === instanceId) {
				instances.splice(i, 1);
			} else {
				i = i + 1;
			}
		}
	};
	
	this.update = function () {
		var instancesLength = instances.length,
			i;
		for (i = 0; i < instancesLength; i = i + 1) {
			this.write(instances[i]);
		}
	};
	
	this.go = function (numeroPagina) {
		this.currentPage = numeroPagina;
		this.update();
	};
	
	this.clear = function () {
		var instancesLength = instances.length,
			i;
		for (i = 0; i < instancesLength; i = i + 1) {
			LNV.get(instances[i]).innerHTML = "<span>&nbsp;</span>";
		}
	};
	
	this.getFirstElementInPage = function (pagina) {
		return (params.elementsPerPage * (pagina - 1));
	};
	this.getLastElementInPage = function (pagina) {
		return (params.elementsPerPage * (pagina) > params.elementCount) ? params.elementCount : (params.elementsPerPage * (pagina));
	};
};

LNV.widget.gallery = function (config) {
	config.thumbnailContainer = config.thumbnailContainer || "tabla-galeria";
	config.bigImage = config.bigImage || "bigImage";
	config.caption = config.caption || "caption";
		
	var thumbnailContainer = config.thumbnailContainer.constructor == String ? LNV.get(config.thumbnailContainer) : config.thumbnailContainer,
		bigImage = config.bigImage.constructor == String ? LNV.get(config.bigImage) : config.bigImage,
		caption = config.caption.constructor == String ? LNV.get(config.caption) : config.caption,
	
	thumbnails = thumbnailContainer.getElementsByTagName("img"),

	onMouseOver = function (e) {
		for (var i = 0; i < thumbnails.length; i = i + 1) {
			if ( thumbnails[i].alt == "" ) {
				thumbnails[i].alt = caption.innerHTML;
			}
			if ( thumbnails[i].src == this.src ) {
				thumbnails[i].src = this.src.replace("a.gif", "b.gif");
			} else {
				thumbnails[i].src = thumbnails[i].src.replace("b.gif", "a.gif");
			}
		}
		bigImage.src = this.src.replace("b.gif", "L.jpg");
		caption.innerHTML = this.alt;
		this.alt = "";
	},
	
	i;
	
	for (i = 0; i < thumbnails.length; i = i + 1) {
		
		LNV.preloadImages(thumbnails[i].src.replace("a.gif", "b.gif"));
		
		LNV.events.add(thumbnails[i], "mouseover", onMouseOver);
	}
};
