/*
* CongelarFilaColumna is a  jQuery plugin that allows freezing of rows and columns.
* Scrolling can be enabled. Both rows and columns can be frozen. Rows to be frozen 
* should be placed in 'thead' (whole frozen header). You can freeze rows and columns combined with colspan or rowspan.
*
*
* Copyright (c) 2016
* Author: Agustin Rios Reyes.
* Email:  nitsugario@gmail.com
* Github: https://github.com/nitsugario/jQuery-Freeze-Table-Column-and-Rows
*
* Licensed under MIT
* http://www.opensource.org/licenses/mit-license.php
*
*/
(function($)
{
	$.fn.CongelarFilaColumna = function (method)
	{
		var defaults =
		{
			width:         '100%',
			height:        '100%',
			idTablaThead:   'TableThead',
			idTablaColThead:'TablaColThead',
			idTablaColTbody:'TablaColTbody',
			Columnas:        1, //Number of columns fixed
			tfoot:           false
		};
		var settings = {};
		var methods  =
		{
			init: function (options)
			{
				settings = $.extend({}, defaults, options);

				return this.each(function ()
				{
					var $tabla = $(this); 

					if (helpers._EsUnaTabla($tabla))
					{ 
						methods.setup.apply(this, Array.prototype.slice.call(arguments, 1));
					}
					else
					{
						$.error('La Tabla No es válida. :( ');
					};
				});
			},
			setup: function ()
			{
				var $wrapper,
					$tabla       = $(this), 
					tabla        = this,
					contenedor   = $(this).parent(),
					heightConten = contenedor.height(),
					widthConten  = contenedor.width(), 
					classT       = $tabla.attr("class");

				settings.idTabla = $tabla.attr("id");
				$tabla.addClass('htCore');

				helpers._ObtenerAsignarAnchoAltoThead( $tabla );
				helpers._ObtenerAsignarAnchoAlto($tabla); 

				var thead        = $tabla.find("thead").clone(),
					anchotabla   = $tabla.width(),
					altotabla    = $tabla.height(),
					$divThead    = $('<div class="table-clone-Thead"><div class="wtHolder"><div class="wtHider"><div class="wtSpreader"></div></div></div></div>'),
					$divColThead = $('<div class="table-clone-lef-Colum-Thead"><div class="wtHolder"><div class="wtHider"><div class="wtSpreader"></div></div></div></div>'),
					$divColTbody = $('<div class="table-clone-lef-Colum"><div class="wtHolder"><div class="wtHider"><div class="wtSpreader"></div></div></div></div>'),
					tablaTH      = $("<table id='"+settings.idTablaThead+"'>").attr("class",classT).append(thead),
					$tablaTHCol  = $("<table id='"+settings.idTablaColThead+"' >").attr("class",classT).append($("<thead>")),
					$tablaTBCol  = $("<table id='"+settings.idTablaColTbody+"' >").attr("class",classT).append($("<thead>")).append($("<tbody>"));

				settings.scrollbarOffset  = helpers._OptenerWidthBarraScroll();
				$tabla.css({'width':anchotabla});
				tablaTH.css({'width':anchotabla});

				tablaTH.addClass('htCore');
				$tablaTHCol.addClass('htCore');
				$tablaTBCol.addClass('htCore');
				
				helpers._ClonarHeaderColumnasACongelar($tabla,$tablaTHCol,'thead',settings.Columnas);
				helpers._ClonarHeaderColumnasACongelar($tabla,$tablaTBCol,'thead',settings.Columnas);
				helpers._ClonarHeaderColumnasACongelar($tabla,$tablaTBCol,'tbody',settings.Columnas);

				if( settings.tfoot)
				{
					$tablaTBCol.append($("<tfoot>"));
					helpers._ClonarHeaderColumnasACongelar($tabla,$tablaTBCol,'tfoot',settings.Columnas);
				}

				var AltoCol      = $tabla.find('thead').outerHeight(),
					AnchoContenB = (widthConten - settings.scrollbarOffset),
					AltoContenB  = (heightConten - settings.scrollbarOffset);

				$divThead.css({'height':AltoCol,'width': AnchoContenB});
				$divThead.find('.wtHolder').css({'height':(AltoCol+settings.scrollbarOffset),'width': AnchoContenB});
				$divThead.find('.wtHider').css({'width': anchotabla});

				$divColTbody.css({'height':AltoContenB,'background-color': '#ffffff'});
				$divColTbody.find('.wtHolder').css({'height':AltoContenB});

				$tabla.wrap('<div class="table-wrapper"></div>');
				$tabla.wrap('<div class="table-original"></div>');
				$tabla.wrap('<div class="wtHolder" style="width: '+widthConten+'px; height: '+heightConten+'px;"></div>');
				$tabla.wrap('<div class="wtHider" style="width: '+anchotabla+'px; height: '+altotabla+'px;"></div>');
				$tabla.wrap('<div class="wtSpreader"></div>');
				$wrapper   = $tabla.closest('.table-wrapper');

				$divThead   .find('.wtSpreader').append(tablaTH);
				$divColThead.find('.wtSpreader').append($tablaTHCol);
				$divColTbody.find('.wtSpreader').append($tablaTBCol);

				$wrapper.append($divThead);
				$wrapper.append($divColTbody);
				$wrapper.append($divColThead);

				var AnchoCol = $wrapper.find('.table-clone-lef-Colum table').outerWidth()+1;

				$wrapper.find('.table-clone-lef-Colum').css({'width': AnchoCol});
				$wrapper.find('.table-clone-lef-Colum table').css({'width': AnchoCol});
				$wrapper.find('.table-clone-lef-Colum .wtHolder').css({'width': (AnchoCol+settings.scrollbarOffset)});

				$wrapper.find('.table-clone-lef-Colum-Thead').css({'width': AnchoCol});
				$wrapper.find('.table-clone-lef-Colum-Thead table').css({'width': AnchoCol});

				helpers._onScroll($wrapper);
				helpers._onScrollTabDLA($wrapper);
				return tabla;
			}
		}
		var helpers  =
		{
			/*
			* return boolean
			* valida si el elemento tien un thead y un tbody.
			*/
			_EsUnaTabla: function($obj)
			{
				var $tabla = $obj,
				TieneTable = $tabla.is('table'),
				TieneThead = $tabla.find('thead').length > 0,
				TieneTbody = $tabla.find('tbody').length > 0;

				if (TieneTable && TieneThead && TieneTbody)
				{
					return true;
				}

				return false;
			},
			_ObtenerAsignarAnchoAltoThead: function($obj)
			{
				var $lobTable = $obj;

				$lobTable.find("thead tr").each(function()
				{
					$(this).find("th").each(function()
					{
						$(this).css({'width':$(this).width(),'height':$(this).height(),'overflow': 'hidden'});
					});
				});
			},
			_ObtenerAsignarAnchoAlto: function($obj)
			{
				var $tabla         = $obj,
					ThTd           = "",
					rowspanAntes   = false,
					colspanAntes   = false,
					mascolumnas    = true,
					cuantosColspan = 0,
					cuentaColumnas = 0,
					cuentaRowspan  = 0,
					cuentafilass   = 0,
					cuantasCols    = settings.Columnas;

				$tabla.find("tr").each(function(fila)
				{
					var ThTd       = ( $(this).parent().is('thead') ) ? 'th' : ( $(this).parent().is('tbody') ) ? 'td' : ( $(this).parent().is('tfoot') ) ? 'td' : 'undefined';
					var lnuAlto = helpers._obtenerHeightMax( $(this), ThTd );
					if ( cuantasCols == 1 )
					{
						if (!rowspanAntes)
						{
							$(this).find(ThTd).each(function(index)
							{
								if (index == 0)
									{
										if (!colspanAntes) {
											$(this).css({'width':$(this).width(),'height':lnuAlto,'overflow': 'hidden'});
										}
										else
										{
											console.log("Error: colspan in 1 column.");
										}

										if ( $(this).attr( "rowspan" ) ) {
											rowspanAntes  = true;
											cuentaRowspan = $(this).attr("rowspan");
										};
										
										if ( $(this).attr( "colspan" ) ) {
											colspanAntes   = true;
											cuantosColspan = $(this).attr("colspan");
										}
										if (colspanAntes) {
											if (cuantosColspan == cuantasCols) {
												colspanAntes   = false;
												mascolumnas    = false;
												cuentaColumnas = cuantasCols;
											}else if( (cuantasCols-cuantosColspan) > 0){
												colspanAntes   = false;
												mascolumnas    = true;
												cuentaColumnas = cuantosColspan;
											}
										}
									}
							});

							colspanAntes   = false;
							mascolumnas    = true;
							cuantosColspan = 0;
							cuentaColumnas = 1;

							if (rowspanAntes) {
								cuentaRowspan--;
							}
						}
						else
						{
							cuentaRowspan--;
						}

						if ( cuentaRowspan == 0 )
						{
							rowspanAntes = false;

						}
					}
					else
					{
						if (!rowspanAntes)
						{							
							$(this).find(ThTd).each(function(index)
							{
								if(cuentaColumnas < cuantasCols )
								if (index < cuantasCols && mascolumnas)
								{
									if (index == 0)
									{
										if (!colspanAntes)
										{
											$(this).css({'width':$(this).width(),'height':lnuAlto,'overflow': 'hidden'});
										}

										if ( $(this).attr( "rowspan" ) )
										{
											rowspanAntes  = true;
											cuentaRowspan = $(this).attr("rowspan");
										};
										
										if ( $(this).attr( "colspan" ) )
										{
											colspanAntes   = true;
											cuantosColspan = $(this).attr("colspan");
										}

										if (colspanAntes)
										{
											if (cuantosColspan == cuantasCols)
											{
												colspanAntes   = false;
												mascolumnas    = false;
												cuentaColumnas = cuantasCols;
											}
											else if( (cuantasCols-cuantosColspan) > 0)
											{
												colspanAntes   = false;
												mascolumnas    = true;
												cuentaColumnas = cuantosColspan;
											}
										}
									}
									else
									{
										if (colspanAntes)
										{
											if (cuantosColspan == cuantasCols)
											{
												colspanAntes = false;
												mascolumnas  = false;
											}
											else if(cuantosColspan < cuantasCols)
											{
												colspanAntes = false;
												mascolumnas  = true;
											}
										}
										else
										{
											if (!colspanAntes)
											{
												if ( $(this).attr( "colspan" ) )
												{
													colspanAntes   = true;
													cuantosColspan = $(this).attr("colspan");
													cuentaColumnas = parseInt(cuentaColumnas) + parseInt(cuantosColspan);
												}
												else
												{
													cuentaColumnas++;
												}
												$(this).css({'width':$(this).width(),'height':lnuAlto,'overflow': 'hidden'});
											}

											if ( $(this).attr( "colspan" ) )
											{
												colspanAntes   = true;
												cuantosColspan = $(this).attr("colspan");
												cuentaColumnas = parseInt(cuentaColumnas) + parseInt(cuantosColspan);
											}

											if ( $(this).attr( "rowspan" ) )
											{
												rowspanAntes  = true;
												cuentaRowspan = $(this).attr("rowspan");
											};

											if (colspanAntes)
											{
												if (cuantosColspan == cuantasCols)
												{
													colspanAntes   = false;
													mascolumnas    = false;
													cuentaColumnas = cuantasCols;
												}
												else if(cuentaColumnas == cuantasCols)
												{
													colspanAntes   = false;
													mascolumnas    = false;
													cuentaColumnas = cuantasCols;
												}
												else if( (cuantasCols-cuantosColspan) > 0)
												{
													colspanAntes   = false;
													mascolumnas    = true;
												}
											}
										}								
									}
								}
							});

							colspanAntes   = false;
							mascolumnas    = true;
							cuantosColspan = 0;
							cuentaColumnas = 1;

							if (rowspanAntes) {
								cuentaRowspan--;
							}
						}
						else
						{
							cuentaRowspan--;
						}

						if ( cuentaRowspan == 0 )
						{
							rowspanAntes = false;

						}
					}

					cuentafilass++;
				});
			},
			_ClonarHeaderColumnasACongelar: function($tabla,$donde,tipothtd,cuantasCols)
			{
				var ThTd           = "",
					rowspanAntes   = false,
					colspanAntes   = false,
					mascolumnas    = true,
					cuantosColspan = 0,
					cuentaColumnas = 0,
					cuentaRowspan  = 0,
					cuentafilass   = 0,
					$trThTd        = $tabla.find(tipothtd),
					$newRow;

				if (tipothtd == "thead")
				{
					ThTd  = "th";
				}
				else if(tipothtd == "tbody" || tipothtd =='tfoot')
				{
					ThTd  = "td";
				};

				$trThTd.find("tr").each(function()
				{
					if ( cuantasCols == 1 )
					{
						if (!rowspanAntes)
						{
							var tr = $(this).clone(true).html("");

							$(this).find(ThTd).each(function(index)
							{
								if (index == 0)
									{
										$newRow = tr.appendTo($donde.find(tipothtd));
										if (!colspanAntes) {

											$newRow.append($(this).clone());
										}
										else
										{
											console.log("Error: colspan in 1 column.");
										}

										if ( $(this).attr( "rowspan" ) ) {
											if ( $(this).attr( "rowspan" ) > 0 )
											{
												rowspanAntes  = true;
												cuentaRowspan = $(this).attr("rowspan");
											}
										};
										
										if ( $(this).attr( "colspan" ) ) {
											colspanAntes   = true;
											cuantosColspan = $(this).attr("colspan");
										}
										if (colspanAntes) {
											if (cuantosColspan == cuantasCols) {
												colspanAntes   = false;
												mascolumnas    = false;
												cuentaColumnas = cuantasCols;
											}else if( (cuantasCols-cuantosColspan) > 0){
												colspanAntes   = false;
												mascolumnas    = true;
												cuentaColumnas = cuantosColspan;
											}
										}
									}
							});

							colspanAntes   = false;
							mascolumnas    = true;
							cuantosColspan = 0;
							cuentaColumnas = 1;

							if (rowspanAntes) {
								cuentaRowspan--;
							}
						}
						else
						{
							cuentaRowspan--;
							var tr = $(this).clone(true).html("");
							tr.appendTo($donde.find(tipothtd));
						}

						if ( cuentaRowspan == 0 )
						{
							rowspanAntes = false;

						}
					}
					else
					{
						if (!rowspanAntes)
						{

							var tr = $(this).clone(true).html("");
							
							$(this).find(ThTd).each(function(index)
							{
								if(cuentaColumnas < cuantasCols )
								if (index < cuantasCols && mascolumnas)
								{
									if (index == 0)
									{
										$newRow = tr.appendTo($donde.find(tipothtd));

										if (!colspanAntes)
										{
											$newRow.append($(this).clone());
										}

										if ( $(this).attr( "rowspan" ) )
										{
											if ( $(this).attr( "rowspan" ) > 0 )
											{
												rowspanAntes  = true;
												cuentaRowspan = $(this).attr("rowspan");
											}
										};
										
										if ( $(this).attr( "colspan" ) )
										{
											colspanAntes   = true;
											cuantosColspan = $(this).attr("colspan");
										}

										if (colspanAntes)
										{
											if (cuantosColspan == cuantasCols)
											{
												colspanAntes   = false;
												mascolumnas    = false;
												cuentaColumnas = cuantasCols;
											}
											else if( (cuantasCols-cuantosColspan) > 0)
											{
												colspanAntes   = false;
												mascolumnas    = true;
												cuentaColumnas = cuantosColspan;
											}
										}
									}
									else
									{
										if (colspanAntes)
										{
											if (cuantosColspan == cuantasCols)
											{
												colspanAntes = false;
												mascolumnas  = false;
											}
											else if(cuantosColspan < cuantasCols)
											{
												colspanAntes = false;
												mascolumnas  = true;
											}
										}
										else
										{
											if (!colspanAntes)
											{
												if ( $(this).attr( "colspan" ) )
												{
													colspanAntes   = true;
													cuantosColspan = $(this).attr("colspan");
													cuentaColumnas = parseInt(cuentaColumnas) + parseInt(cuantosColspan);
												}
												else
												{
													cuentaColumnas++;
												}

												$newRow.append($(this).clone());
											}

											if ( $(this).attr( "colspan" ) )
											{
												colspanAntes   = true;
												cuantosColspan = $(this).attr("colspan");
												cuentaColumnas = parseInt(cuentaColumnas) + parseInt(cuantosColspan);
											}

											if ( $(this).attr( "rowspan" ) )
											{
												if ( $(this).attr( "rowspan" ) > 0 )
												{
													rowspanAntes  = true;
													cuentaRowspan = $(this).attr("rowspan");
												}
											};

											if (colspanAntes)
											{
												if (cuantosColspan == cuantasCols)
												{
													colspanAntes   = false;
													mascolumnas    = false;
													cuentaColumnas = cuantasCols;
												}
												else if(cuentaColumnas == cuantasCols)
												{
													colspanAntes   = false;
													mascolumnas    = false;
													cuentaColumnas = cuantasCols;
												}
												else if( (cuantasCols-cuantosColspan) > 0)
												{
													colspanAntes   = false;
													mascolumnas    = true;
												}
											}
										}								
									}
								}
							});

							colspanAntes   = false;
							mascolumnas    = true;
							cuantosColspan = 0;
							cuentaColumnas = 1;

							if (rowspanAntes) {
								cuentaRowspan--;
							}
						}
						else
						{
							cuentaRowspan--;
							var tr = $(this).clone(true).html("");
							tr.appendTo($donde.find(tipothtd));
						}

						if ( cuentaRowspan == 0 )
						{
							rowspanAntes = false;

						}
					}

					cuentafilass++;
				});
			},
			_onScroll:function($obj)
			{
				var $tabla      = $obj,
					$Scrolling  = $tabla.find('.table-original .wtHolder'),
					$LeftScroll = $tabla.find('.table-clone-Thead .wtHolder'),
					$TopScroll  = $tabla.find('.table-clone-lef-Colum .wtHolder');

				$Scrolling.on('scroll',function()
				{
					$LeftScroll.scrollLeft(this.scrollLeft);
					$TopScroll.scrollTop($Scrolling.scrollTop());
				});

				$TopScroll.on('scroll',function()
				{
					$Scrolling.scrollTop($TopScroll.scrollTop());
				});

				$LeftScroll.on('scroll',function()
				{
					$Scrolling.scrollLeft(this.scrollLeft);
				});
			},
			_onScrollTabDLA:function($contenedor)
			{
				$(document).on("keyup",function(event)//Capturamos el evento keyup de una tecla
				{
				    event.preventDefault();
				    var t = event.keyCode ? event.keyCode : event.which ? event.which : event.charCode;

					if (t == 9)//--Validamos si es la tecla tab.
					{
						var $Scrolling  = $contenedor.find('.table-original .wtHolder'),
							$LeftScroll = $contenedor.find('.table-clone-Thead .wtHolder'),
							$TopScroll  = $contenedor.find('.table-clone-lef-Colum .wtHolder');

						$contenedor.find(":focus").each(function()//--buscamos el elemento que tiene focus.
						{
							var padreInput = $(this).parent().prop("tagName");

							if (  padreInput == "DIV" )
							{
								var filaActual  = $(this).parent().parent().parent().parent(),
									nameTabla   = $(this).parent().parent().parent().parent().parent().parent(),
									tdActual    = $(this).parent().parent().parent();
							}
							else if (  padreInput == "TD" || padre == "TH" )
							{
								var filaActual  = $(this).parent().parent(),
									nameTabla   = $(this).parent().parent().parent().parent(),
									tdActual    = $(this).parent();
							};

							if( nameTabla.attr("id") == settings.idTabla)//--Validamos si el foco está en Tbody de la tabla inicial
							{
								if( tdActual.index() == 0 )
								{
									var $filaTab = $("#"+settings.idTabla+" tbody tr:eq("+filaActual.index()+")");
									$(this).blur();
									$filaTab.find("input:eq(1)").focus();
									$Scrolling.scrollLeft(0);
									$LeftScroll.scrollLeft(0);
								}
							}
							else if( nameTabla.attr("id") == settings.idTablaColTbody)//--Validamos si el foco está en Tbody de la tabla TablaColTbody
							{
								var $filaTab = $("#"+settings.idTabla+" tbody tr:eq("+filaActual.index()+")");

								if( filaActual.index() == 0 )
								{
									$TopScroll.scrollTop(0);
									$Scrolling.scrollTop(0);
								}

								$(this).blur();
								$filaTab.find("input:eq(1)").focus();
								$Scrolling.scrollLeft(0);
								$LeftScroll.scrollLeft(0);
							}
						});
					}
				});
			},
			_obtenerHeightMax:function( $objTr, ThTd )
			{
				var mayor = 0;

				$objTr.find(ThTd).each(function()
				{
					var Alto = $(this).height();

					if( Alto > mayor )
					{
						mayor = Alto;
					}
				});

				return mayor;
			},
			_OptenerWidthBarraScroll: function()
			{
				var scrollbarWidth = 0;

				if (!scrollbarWidth)
				{
					if (/msie/.test(navigator.userAgent.toLowerCase()))
					{
						var $textarea1 = $('<textarea cols="10" rows="2"></textarea>').css({ position: 'absolute', top: -1000, left: -1000 }).appendTo('body'),
							$textarea2 = $('<textarea cols="10" rows="2" style="overflow: hidden;"></textarea>').css({ position: 'absolute', top: -1000, left: -1000 }).appendTo('body');

						scrollbarWidth = $textarea1.width() - $textarea2.width() + 2; 
						$textarea1.add($textarea2).remove();

					}
					else
					{
						var $div = $('<div />').css({ width: 100, height: 100, overflow: 'auto', position: 'absolute', top: -1000, left: -1000 })
											.prependTo('body').append('<div />').find('div')
											.css({ width: '100%', height: 200 });

						scrollbarWidth = 100 - $div.width();
						$div.parent().remove();

					}
				}

				return scrollbarWidth;
			}
		}

		if (methods[method])
		{
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
		}
		else if (typeof method === 'object' || !method)
		{
			return methods.init.apply(this, arguments);
		}
		else
		{
			$.error('El Método "' +  method + '" No existe en el plugin congelaheaderunocolumn! :( ');
		}
	}
})(jQuery);