(function($) {
	var elem, opts
	var esIE6 = ($.browser.msie && parseInt($.browser.version.substr(0,1),10) < 7);
	var esIE7 = ($.browser.msie && parseInt($.browser.version.substr(0,1),10) == 7);
	
	$.fn.aycogrid = function(opts) {
		
		opts	= $.extend({}, $.fn.aycogrid.defaults, opts);
		
		return this.each(function () {
			
			var __aycogrid = $(this);
			if (!__aycogrid.hasClass("aycogrid")) __aycogrid.addClass("aycogrid");
			
			var __aycogrid_header		= $(this).find("tr:first");
			var __aycogrid_data_all		= $(this).find("tr:not(.aycogrid-masInfo tr):not(:first):not([rel=aycogrid-noResults]):not(.aycogrid-masInfo)");
			var __aycogrid_data_info	= $(this).find("tr.aycogrid-masInfo");
			var __aycogrid_no_data		= $(this).find("tr[rel=aycogrid-noResults]");
			var __aycogrid_data_odd		= $(this).find("tr:not(:first):not(.aycogrid-masInfo tr):odd");
			var __aycogrid_data_evn		= $(this).find("tr:not(:first):not(.aycogrid-masInfo tr):even");
			var	__aycogrid_numcols		= __aycogrid_header.find("th").length;
			
			if ((esIE6) || (esIE7)) {
				__aycogrid_data_all.find("td div:empty").html("&nbsp;");
			} else {
				__aycogrid_data_all.find("td div:empty").remove();
			}
			
			//el atributo 'rel' de la tabla nos indica el 'name' formulario que alimenta esa tabla
			var	__aycogrid_form		= $("form[name=" + $(this).attr("rel") + "]");
			
			__aycogrid_form.aycosearch(opts);
			if (opts.pager) __aycogrid.aycopager(opts);
			
			__aycogrid_header.addClass("aycogrid-header").find("th").each(function () {
				if ((opts.orderBy) && ($(this).attr("rel"))) {
					$(this).attr("nowrap","nowrap").unbind("click").bind("click",function () {
						__search_ord	= $(this).attr("rel").replace("-",".");
						
						if (__aycogrid_form.length>0) {
							__act_ord		= __aycogrid_form.find("input[name=search_ord]");
							__act_ord_tp	= __aycogrid_form.find("input[name=search_ord_tp]");
							
							if (__search_ord==__act_ord.val()) {
								if (__act_ord_tp.val()=="ASC") {
									__act_ord_tp.val("DESC");
								} else {
									__act_ord_tp.val("ASC");
								}
							} else {
								__act_ord_tp.val("ASC");
							}
							__act_ord.val(__search_ord);
							__aycogrid_form.submit();
						}
					}).find("div:first").addClass("aycogrid-orderBy");
				} else {
					$(this).removeAttr("rel")
				}
			});
				
			__act_ord		= __aycogrid_form.find("input[name=search_ord]");
			__act_ord_tp	= __aycogrid_form.find("input[name=search_ord_tp]");
			
			if ((__act_ord.length>0) && (__act_ord_tp.length>0)) {
				__aycogrid_header.addClass("aycogrid-header").find("th[rel=" + __act_ord.val().replace(".","-") + "]").find(".aycogrid-orderBy").toggleClass(__act_ord_tp.val());
			}
			
			if (opts.swap) {
				__aycogrid_data_odd.addClass("aycogrid-odd");
				__aycogrid_data_evn.addClass("aycogrid-even");
			}
			
			__aycogrid_data_all.each(function () {
				if (opts.hover) {
					$(this).hover(
						function () {
							$(this).toggleClass("hover");
						},
						function () {
							$(this).toggleClass("hover",false);
						}
					);
				}
				if (opts.tdFirst) $(this).find("td:first").addClass("aycogrid-tdFirst");
				if (opts.tdFirst) $(this).find("td:not(:first):not(:last)").addClass("aycogrid-tdMid");
				if (opts.tdLast) {
					$(this).find("td:last").addClass("aycogrid-tdLast");
				}
			});
			
			__aycogrid_data_info.each(function () {
				var __aycogrid_masInfo_openerContainer	= $(this).prev("tr").find("td:last div").css("position","relative");
				var __aycogrid_masInfo			= $(this).find("div:first");
				var __aycogrid_masInfo_opener	= $("<a href='#' class='aycogrid-masInfo-opener'></a>");
				__aycogrid_masInfo.css({"overflow":"hidden","border-bottom":"1px solid #efefef","display":"none"})
				__aycogrid_masInfo_openerContainer.append(__aycogrid_masInfo_opener);
				__aycogrid_masInfo_opener.click(function () {
					__aycogrid_masInfo.slideToggle();
					return false;
				});
			}).find("td").attr("colspan",__aycogrid_numcols);
			
			__aycogrid_no_data.find("td").addClass("aycogrid-tdFirst").attr("colspan",__aycogrid_numcols);
			
			
			if ($.isFunction(opts.callback)) opts.callback.call();
			
		});
	};
	
	$.fn.aycosearch = function(opts) {
		//buscador
		opts	= $.extend({}, $.fn.aycogrid.defaults, opts);
		
		var __form	= this;
		
		if ((!opts.formOpened) && !($("input[type=hidden][name=search_active]",__form).val()==1)) __form.css("display","none");
		__formOpener		= $(opts.formOpener + "[rel=" + __form.attr("name") + "]");
		__formTrigger		= $(opts.formTrigger,__form);
		__formReset			= $(opts.formReset,__form);
		
		__formOpener.unbind("click").bind("click",function () {
			__form.slideToggle(opts.duration);
			return false;
		});
		
		if (opts.formAction!=null) __form.attr("action",opts.formAction);
		if ((opts.formAjax) && ($.isFunction($.fn.ajaxSubmit))) {
			__form.ajaxForm({
				target: opts.formTarget,
				success: function () {
					if (opts.rollover) __rollover(opts);
				}
			});
		}
		
		if (opts.rollover) __rollover(opts);
		
		__formTrigger.unbind("click").bind("click", function () {
			$("input[type=hidden][name=search_active]",__form).val("1");
			$("input[name=search_pag]",__form).val(1);
			__form.submit();
			return false;
		});
		
		__formReset.unbind("click").bind("click", function () {
			$("input[type=text],textarea,select",__form).val("");
			$("input[type=hidden][name=search_active]",__form).val("");
			$("input[name=search_pag]",__form).val(1);
			__form.submit();
			return false;
		});
		
		function __rollover(opts) {
			opts	= $.extend({}, $.fn.aycogrid.defaults, opts);
			$(".rollover[src*=_off.]",$(opts.formTarget)).unbind('hover').hover(
				function () {
					off_src	= $(this).attr("src");
					on_src	= off_src.replace("_off","_on");
					$(this).attr("src",on_src);
				},
				function () {
					on_src	= $(this).attr("src");
					off_src	= off_src.replace("_on","_off");
					$(this).attr("src",off_src);
				}
			);	
		}
	};
	
	$.fn.aycopager = function(opts) {
		//buscador
		opts	= $.extend({}, $.fn.aycogrid.defaults, opts);
		
		var	__aycogrid_form		= $("form[name=" + this.attr("rel") + "]");
		
		var __pag		= parseInt($("input[name=search_pag]", __aycogrid_form).val(),10);
		var __regsPag	= ((isNaN(parseInt($("input[name=search_regspag]", __aycogrid_form).val(),10))?parseInt($("input[name=search_regs_total]", __aycogrid_form).val(),10):parseInt($("input[name=search_regspag]", __aycogrid_form).val(),10)));
		var __pagFirst	= parseInt($("input[name=search_pag_first]", __aycogrid_form).val(),10);
		var __pagLast	= parseInt($("input[name=search_pag_last]", __aycogrid_form).val(),10);
		var __regsIni	= parseInt($("input[name=search_regs_ini]", __aycogrid_form).val(),10);
		var __regsFin	= parseInt($("input[name=search_regs_fin]", __aycogrid_form).val(),10);
		var __regsTotal	= parseInt($("input[name=search_regs_total]", __aycogrid_form).val(),10);		
		var __pagPrev	= parseInt((__pag <= __pagFirst) ? __pag : (__pag-1),10);
		var __pagFwd	= parseInt((__pag >= __pagLast) ? __pag : (__pag+1),10);
		
		
				
		var __aycopager_selectRegsPag = '';
		if ($.inArray(__regsPag, opts.pagerRegsPag) >= 0) {			
			for (var i=0; i<=opts.pagerRegsPag.length-1; i++) {
				if (parseInt(opts.pagerRegsPag[i],10)==__regsPag) {
					__aycopager_selectRegsPag	+= '' +
					'<td nowrap>' +
					'<div class="aycopager-regsMsg">' +
					'<div class="aycopager-regsMsgLeft">' +
					'<div class="aycopager-regsMsgRight">' +
						$.fn.aycogrid.format(opts.pagerRegsPagMsg,[__regsPag])
					'</div>' +
					'</div>' +
					'</div>';
					'</td>';
				} else {
					__aycopager_selectRegsPag	+= '<td><a href="#" class="aycopager-regs" rel="regs_' + opts.pagerRegsPag[i] + '">' + opts.pagerRegsPag[i] + '</a></td>';
				}
			}
		}
		
		if (opts.pagerMsgRegsPag) {
			var __aycopager_pagerRegsPagMsg	= '' +
			'<table cellspacing="0" cellpadding="0" border="0" align="center">' +
			'<tr>' +
				__aycopager_selectRegsPag +
				'<td align="left">' +
					
				'</td>' +
			'</tr>' +
			'</table>';
		} else {
			var __aycopager_pagerRegsPagMsg	= '';
		}
		
		switch (opts.pagerType) {
			case 'compact':
				var __firsts_disabled	= (__pag==__pagFirst) ? ' disabled' : '';
				var __lasts_disabled	= (__pag==__pagLast) ? ' disabled' : '';
				
				var __aycopager_select	= '<select name="aycopager_select">';
				for (var i=__pagFirst; i<=__pagLast; i++) {
					if (__pag==i) {
						__pag_selected	= ' selected';
					} else {
						__pag_selected	= '';
					}
					__aycopager_select	+= '<option value="' + i + '"' + __pag_selected + '>' + i + '</option>';
				}
				__aycopager_select	+= '</select>';
				
				if ((__pagFirst!=__pagLast) && (__regsTotal!=0)) {
					var __aycopager_tablePags	= '' +
					'<table cellspacing="0" cellpadding="0" border="0" align="' + opts.pagerPagAlign + '">' +
					'<tr>' +
						((opts.pagerShowFstLst) ? '<td><a href="#" class="aycopager-goFirst' + __firsts_disabled + '" rel="go_' + __pagFirst + '"><span>' + opts.pagerFirstMsg + '</span></a></td>' : '') +
						((opts.pagerShowPrvNxt) ? '<td><a href="#" class="aycopager-goPre' + __firsts_disabled + '" rel="go_' + __pagPrev + '"><span>' + opts.pagerPrevMsg + '</span></a></td>' : '') +
						'<td style="padding: 0 5px; vertical-align: bottom;">' + __aycopager_select + '</td>' +
						((opts.pagerShowPrvNxt) ? '<td><a href="#" class="aycopager-goFwd' + __lasts_disabled + '" rel="go_' + __pagFwd + '"><span>' + opts.pagerNextMsg + '</span></a></td>' : '') +
						((opts.pagerShowFstLst) ? '<td><a href="#" class="aycopager-goLast' + __lasts_disabled + '" rel="go_' + __pagLast + '"><span>' + opts.pagerLastMsg + '</span></a></td>' : '') +
					'</tr>' +
					'</table>';
				} else {
					var __aycopager_tablePags	= '&nbsp;';
				}
			
				var __aycopager_pagerRegsMsg	= (((__pagFirst!=__pagLast) && (__regsTotal!=0)) ? $.fn.aycogrid.format(opts.pagerRegsMsg,[__regsIni,__regsFin,__regsTotal]) : $.fn.aycogrid.format(opts.pagerRegsMsgMin,[__regsTotal]) );
				
				var __aycopager = $('' + 
				'<div class="aycopager" rel="' + this.attr("rel") + '">' +
					'<table cellspacing="0" cellpadding="0" border="0" width="100%">' +
					'<tr>' +
						((opts.pagerMsgRegsPag) ? 
							'<td align="left">' +
								__aycopager_pagerRegsPagMsg +
							'</td>'
						: '') +
						'<td style="width: 100%; text-align: ' + opts.pagerPagAlign + ';">' + 
							__aycopager_tablePags +
						'</td>' +
						'<td nowrap="nowrap" align="right">' +
							((opts.pagerMsgRegs) ? 
								'<div class="aycopager-regsMsg">' +
								'<div class="aycopager-regsMsgLeft">' +
								'<div class="aycopager-regsMsgRight">' +
									__aycopager_pagerRegsMsg +
								'</div>' +
								'</div>' +
								'</div>'
							: '') +
						'</td>' +
					'</tr>' +
					'</table>' +
				'</div>');
				
				$('.aycopager-goFirst,.aycopager-goPre,.aycopager-goFwd,.aycopager-goLast',__aycopager).unbind('click').bind('click',function () {												
					if (!$(this).hasClass("disabled")) {
						$("input[name=search_pag]",__aycogrid_form).val($(this).attr("rel").replace('go_',''));
						__aycogrid_form.submit();
					}
					return false;
				}).hover(
					function () {
						$(this).toggleClass('hover',true);
						return false;
					},
					function () {
						$(this).toggleClass('hover',false);
						return false;
					}
				);
				
				$("select[name=aycopager_select]",__aycopager).change(function () {
					$("input[name=search_pag]",__aycogrid_form).val($(this).val());
					__aycogrid_form.submit();
				});
				
				break;
				
			case 'full':
				var __firsts_disabled	= (__pag==__pagFirst) ? ' disabled' : '';
				var __lasts_disabled	= (__pag==__pagLast) ? ' disabled' : '';
				
				var __aycopager_pags	= '';
				
				__pagStart	= ((__pag-opts.pagerRadius)<__pagFirst) ? __pagFirst : (__pag-opts.pagerRadius);
				__pagEnd	= ((__pag+opts.pagerRadius)>__pagLast) ? __pagLast : (__pag+opts.pagerRadius);
				
				__aycopager_pags	+= (__pagStart > __pagFirst) ? '<td><span class="aycopager-go disabled">...</span></td>' : '';
				for (var i=__pagStart; i<=__pagEnd; i++) {
					if (__pag==i) {
						__pag_selected	= ' selected';
					} else {
						__pag_selected	= '';
					}
					__aycopager_pags	+= '<td><a href="#" class="aycopager-go' + __pag_selected + '" rel="go_' + i + '"><span>' + i + '</span></a></td>';
				}
				__aycopager_pags	+= (__pagEnd < __pagLast) ? '<td><span class="aycopager-go disabled">...</span></td>' : '';
				
				if ((__pagFirst!=__pagLast) && (__regsTotal!=0)) {
					var __aycopager_tablePags	= '' +
					'<table cellspacing="0" cellpadding="0" border="0" align="' + opts.pagerPagAlign + '">' +
					'<tr>' +
						((opts.pagerShowFstLst) ? '<td><a href="#" class="aycopager-goFirst' + __firsts_disabled + '" rel="go_' + __pagFirst + '"><span>' + opts.pagerFirstMsg + '</span></a></td>' : '') +
						((opts.pagerShowPrvNxt) ? '<td><a href="#" class="aycopager-goPre' + __firsts_disabled + '" rel="go_' + __pagPrev + '"><span>' + opts.pagerPrevMsg + '</span></a></td>' : '') +
						__aycopager_pags +
						((opts.pagerShowPrvNxt) ? '<td><a href="#" class="aycopager-goFwd' + __lasts_disabled + '" rel="go_' + __pagFwd + '"><span>' + opts.pagerNextMsg + '</span></a></td>' : '') +
						((opts.pagerShowFstLst) ? '<td><a href="#" class="aycopager-goLast' + __lasts_disabled + '" rel="go_' + __pagLast + '"><span>' + opts.pagerLastMsg + '</span></a></td>' : '') +
					'</tr>' +
					'</table>';
				} else {
					var __aycopager_tablePags	= '&nbsp;';
				}
				
				var __aycopager_pagerRegsMsg	= (((__pagFirst!=__pagLast) && (__regsTotal!=0)) ? $.fn.aycogrid.format(opts.pagerRegsMsg,[__regsIni,__regsFin,__regsTotal]) : $.fn.aycogrid.format(opts.pagerRegsMsgMin,[__regsTotal]) );
				
				var __aycopager = $('' + 
				'<div class="aycopager" rel="' + this.attr("rel") + '">' +
					'<table cellspacing="0" cellpadding="0" border="0" width="100%">' +
					'<tr>' +
						((opts.pagerMsgRegsPag) ? 
							'<td align="left">' +
								__aycopager_pagerRegsPagMsg +
							'</td>'
						: '') +
						'<td style="width: 100%; text-align: ' + opts.pagerPagAlign + ';">' + 
							__aycopager_tablePags +
						'</td>' +
						'<td nowrap="nowrap" align="right">' +
							((opts.pagerMsgRegs) ? 
								'<div class="aycopager-regsMsg">' +
								'<div class="aycopager-regsMsgLeft">' +
								'<div class="aycopager-regsMsgRight">' +
									__aycopager_pagerRegsMsg +
								'</div>' +
								'</div>' +
								'</div>'
							: '') +
						'</td>' +
					'</tr>' +
					'</table>' +
				'</div>');
				
				$('.aycopager-goFirst,.aycopager-goPre,.aycopager-goFwd,.aycopager-goLast,.aycopager-go',__aycopager).not(".disabled").unbind('click').bind('click',function () {
					if (!$(this).hasClass("disabled") && !$(this).hasClass("selected") && !$(this).hasClass("disabled")) {
						$("input[name=search_pag]",__aycogrid_form).val($(this).attr("rel").replace('go_',''));
						__aycogrid_form.submit();
					}
					return false;
				}).hover(
					function () {
						$(this).toggleClass('hover',true);
						return false;
					},
					function () {
						$(this).toggleClass('hover',false);
						return false;
					}
				);
				
				
				break;
		}
		
		$('.aycopager-regs',__aycopager).unbind('click').bind('click',function () {
			$("input[name=search_regspag]",__aycogrid_form).val($(this).attr("rel").replace('regs_',''));
			$("input[name=search_pag]",__aycogrid_form).val(1);
			__aycogrid_form.submit();
				
			return false;
		}).hover(
			function () {
				$(this).toggleClass('hover',true);
				return false;
			},
			function () {
				$(this).toggleClass('hover',false);
				return false;
			}
		);
		
		switch (opts.pagerPosition){
			case "both":
				this.before(__aycopager);
				this.after(__aycopager.clone(true));
				break;
			case "top":
				this.before(__aycopager);			
				break;
			default:
				this.after(__aycopager);
				break;		
		}
		
		return this;
	};
	
	
	$.fn.aycoexcel = function(opts) {
		opts	= $.extend({}, $.fn.aycogrid.defaults, opts);
		
		var __aycotabla = this;
		
		
		
		
		return this;
	};
	
	$.fn.aycogrid.defaults = {
		duration			: 'normal',			// duracion de las transiciones; 'slow', 'normal', 'fast', o milisegundos
		orderBy				: true,				// ordenacion en las tablas; true o false
		swap				: false,			// filas pares e impares llevan clases diferentes; true o false
		tdFirst				: true,				// primer td de cada fila lleva clase diferente; true o false
		tdLast				: true,				// ultimo td de cada fila lleva clase diferente; true o false
		hover				: true,				// efecto hover al pasar por encima de un tr; true o false
		
		showMasInfo			: false,			// si se quiere mostrar info adicional a cada linea de la tabla
		
		rollover			: true,				// si el formulario de busqueda necesita un control de rollover; true o false
		formAjax			: true,				// si el formulario de busqueda/ordenar/paginado se envia por ajax; true o false
		formOpened			: false,			// si el formulario de busqueda aparezca abierto siempre; true o false
		//formExcel			: ".search_excel",	// identificador (selector jquery) del elemento que convierte a excel la tabla que estamos mirando
		//formExcelUrl		: "auxiliares.php",	// url a la que se envia la tabla para para crear un excel
		formOpener			: ".search_opener",	// identificador (selector jquery) del elemento que abre el formulario de busqueda
		formTrigger			: ".search_go",		// identificador (selector jquery) del elemento que lanza la busqueda
		formReset			: ".search_reset",	// identificador (selector jquery) del elemento que resetea la busqueda
		formTarget			: '',				// identificador (selector jquery) del elemento donde se pinta el resultado de la busqueda
		formAction			: null,				// pagina a la que llama el formulario de busqueda.
		callback			: null,				// callback que se ejecuta al terminar de montar el grid
		
		pager				: false,			// indica si el grid lleva paginado
		pagerType			: 'compact',		// compact/full para diferentes tipos de paginacion
		pagerRadius			: 3,				// numero de paginas antes y despues de la actual en el paginado 'full'
		
		pagerPagAlign		: "center",			// alineado de los enlaces de las paginas; left, center o right
		
		pagerMsgRegs		: true, 			// mensaje de informacion de numero de registros; true o false
		pagerRegsMsg		: "{0} a {1} de {2} resultados", // mensaje de informacion de numero de registros
		pagerRegsMsgMin		: "{0} resultados",	// mensaje de informacion de numero de registros cuando solo hay una pagina
		pagerMsgRegsPag		: true,				// mensaje de informacion de numero de registros por pagina; true o false
		pagerRegsPag		: [25,100,250,500],
		pagerRegsPagMsg		: "{0} res./pág.",	// mensaje de informacion de numero de registros por pagina
		pagerFirstMsg		: "",				// texto a mostrar en el boton de primera pagina
		pagerPrevMsg		: "",				// texto a mostrar en el boton de anterior pagina
		pagerNextMsg		: "",				// texto a mostrar en el boton de siguiente pagina
		pagerLastMsg		: "",				// texto a mostrar en el boton de ultima pagina
		pagerShowFstLst		: true,				// mostrar botones de ultimo/primero; true o false
		pagerShowPrvNxt		: true,				// mostrar botones de anterior/siguiente; true o false
		pagerPosition		: "bottom"			// posición del paginador; valors: bottom, top, both
	};
	
	$.fn.aycogrid.format = function(source, params) {
		if ( arguments.length == 1 ) 
			return function() {
				var args = $.makeArray(arguments);
				args.unshift(source);
				return $.validator.format.apply( this, args );
			};
		if ( arguments.length > 2 && params.constructor != Array  ) {
			params = $.makeArray(arguments).slice(1);
		}
		if ( params.constructor != Array ) {
			params = [ params ];
		}
		$.each(params, function(i, n) {
			source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n);
		});
		return source;
	};
	
})(jQuery);

