jQuery.fn.videowall = function(){
						
					   
					   
					  //Config
					   $.alto_celda 		= 189;
					   $.ancho_celda 		= 328;
					   
					   $.num_celdas_horiz	= 3;
					   $.num_celdas_vert 	= 3;
					   
					   $.overancho 			= $.ancho_celda/2;
					   $.overalto			= $.alto_celda/2;
					   
					   $.path_img 			= "http://img.lacomba.com/";
					   $.distribuciones		= new Array();
					   $.videowallMatrix	= new Array();
					   
					   $.debug				= false;
					   $.fotoActual			= 1;
					   
					   //Tiempo entre foto y foto
					   $.delay				= 6000;
					   
					   //Primera iteración
					   $.first = true;
					   
					   //Esta enmedio de una animación?
					   $.animando = false;
					   
					   //Hay que parar el videowall?
					   $.stop				= false;
					   
					   //Maximo de combinaciones recursivas para formar un elemento mayor
						$.maxComb			= 2;
					   
					   //Variable global de pushes validos
					   $.validas			= new Array(); 
					   $.min_permanencia	= 2;
						
						$.capa				= this.attr("id");
					  //Control para que no se cargue la siguiente si no se ha cargado el bloque anterior
					  $.necesarias =0;
					  $.procesadas =0;
					  $.maxTimeout = 5;
					  $.timeout = 0;
					  
					   //Define funcion de contar elementos repetidos
						Array.prototype.count_value = function(){
							var count = {};
							for(var i = 0; i < this.length; i++){
								if(!(this[i] in count)){
									count[this[i]] = 0;
								}
									count[this[i]]++;
							}
							return count;
						};
						
					   $.fn.videowall.videoWall = function(){
						  if(!$.stop){
							 var distribucion = $.fn.videowall.TypeSelection();
							 if(!$.stop){
								 if($.procesadas < $.necesarias){
									 //Aun no esta lista para ser procesada
									 $.timeout++;
									 if($.maxTimeout<$.timeout){
										$.timeout=0;
										$.procesadas = $.necesarias;
									 }
								 }else{
									 $.timeout=0;
									 if(distribucion != undefined){
										 //Si la distribución es multiple se va iterando
										 if(distribucion[1]=="mult"){
											 
											 $.necesarias =distribucion[2].length;
											 $.procesadas =0;
											for(var i=0; i< distribucion[2].length; i++){
												$.fn.videowall.getImg(distribucion[2][i][1], distribucion[2][i]);
											}
										 }else{
											$.fn.videowall.getImg(distribucion[1],distribucion);
										 }
									 }
								 }
							 }
						  }
					   };
					   
					   $.fn.videowall.inicialize = function(){
							$("#"+$.capa).fadeOut();
							$.fn.videowall.createEstructure();
							//Creamos todas las combinaciones
							$.fn.videowall.create_types();
							//Creamos la matriz de estado del videowall
							$.videowallMatrix = $.fn.videowall.createVideowallMatrix();
							$("#"+$.capa).fadeIn();
							
							//Lanzamos el videowall
							setInterval("$.fn.videowall.videoWall()",$.delay);
							$.fn.videowall.videoWall();
							//Creamos las interacciones cuando el raton esta encima
							$.fn.videowall.interactions();
					   };
					   
					   //Elegimos los tipos que se pueden aplicar
					   $.fn.videowall.TypeSelection = function (){
						   
						   
						   
						   $.validas = new Array();
						   /*for(var i=0;i<$.distribuciones.length;i++){
								if($.fn.videowall.typeValido($.distribuciones[i])){
									$.validas.push($.distribuciones[i]);
								}
						   }*/
						   $.fn.videowall.typesCombinados(0,0,$.fn.videowall.create_distributions());
						   
						   if($.debug)
							alert("Se han preseleccionado un total de "+ $.validas.length +" distribuciones");
							
							//Seleccionamos aleatoriamente una de las combinaciones validas
							var sel = $.validas[$.fn.videowall.aleatorio(0,$.validas.length)];
							
						   if($.debug)
							alert("Se han seleccionado la combinacion "+ sel[1]);
							
							return sel;
					   };
					   
					   //Buscamos las combinaciones de tipos que tambien funcionan
					   $.fn.videowall.typesCombinados = function (Init,profundidad,acumulado){
						  //alert("profundidad seleccionada "+profundidad);
							if(profundidad<$.maxComb){
								for(var i=Init;i<$.distribuciones.length;i++){
									acumulado_aux = acumulado;
									//Si ya quedan incompatibles lo saltamos
									if($.fn.videowall.typeCompatibles(acumulado_aux, $.distribuciones[i])){
										var sum = $.fn.videowall.typeSum(acumulado_aux, $.distribuciones[i]);
										//si el sumatorio ya vale, lo introducimos
										if($.fn.videowall.typeValido(sum)){
											$.validas.push(sum);
										}
										
										$.fn.videowall.typesCombinados(i,profundidad+1,sum);
									}
								}
							}
					   };
					   
					   $.fn.videowall.typeSum = function (type1,type2){
						   var suma = $.fn.videowall.create_distributions();
						   //Definimos como mult combinado
						   suma[1]= "mult";
						   
						   //Sumamos las matrices de distribucion
						   for(var i=0; i<suma[0].length;i++){
							   for(var j=0;j<suma[0][i].length;j++){
									suma[0][i][j][0] = type1[0][i][j][0]+type2[0][i][j][0];   
							   }
						   }
						   //Si type1 ya es un combinado, añadimos el type 2
						   if(type1[1]=="mult"){
								
								var swap = suma;
								suma = $.fn.videowall.copy(type1);
								suma[2].push(type2);
								suma[0] = swap[0];
								
						   }else{
								if(type1[1]!="undefinedxundefined")
									suma[2].push(type1);
								suma[2].push(type2);   
						   }
						   return suma;
					   };
					   
					   //Confirmamos que las 2 matrices se puedan poner sin solaparse
					   $.fn.videowall.typeCompatibles = function (type1,type2){
						   var compatibles= true;
							  for(var i=0;i<type1[0].length;i++){
								for(var j=0;j<type1[0][i].length;j++){
									//Si es 0 lo ignoramos directamente, porque no nos importa
									if((parseInt(type1[0][i][j][0]) + parseInt(type2[0][i][j][0])) >1){
										compatibles = false;
									}
								}
						   } 
						   return compatibles;
					   };
					   
					   
					   
					   //hacemos el producto de la matriz de 
					   $.fn.videowall.typeValido = function (distribucion){
						   var valido= true;
						   relevantes = new Array();
						   for(var i=0;i<distribucion[0].length;i++){
								for(var j=0;j<distribucion[0][i].length;j++){
									//Si es 0 lo ignoramos directamente, porque no nos importa
									if((parseInt(distribucion[0][i][j][0]) * parseInt($.videowallMatrix[i][j][0][0])) !=0){
										//Vamos metiendo los relevantes dentro de un array	
										relevantes.push($.videowallMatrix[i][j][0]);
										if($.videowallMatrix[i][j][1]>0){
											valido = false;
										}
									}
								}
						   };
						   
						   
						   
						   //Analizamos los que son relevantes
						   var repeticiones = relevantes.count_value();
						  
						   
						   for(var i=0;i<relevantes.length;i++){
							   //Multiplicamos sus 2 componentes y sabremos cuantos elementos se necesitan
							   //Si tiene menos elementos significa que no es válida
							   if((parseInt(relevantes[i][0])*parseInt(relevantes[i][1]))>1)
								
								if((parseInt(relevantes[i][0])*parseInt(relevantes[i][1]))> repeticiones[relevantes[i]]) {
									valido= false;
								}
						   }
						   return valido;
					   };
					   
					   //Creamos la matriz de estado actual del videowall y la inicializamos como si todo fuera
					   //imagenes individuales de numero 0
					   $.fn.videowall.createVideowallMatrix = function (){
						   a=new Array($.num_celdas_horiz);
						   
						   for(i=0;i<$.num_celdas_horiz;i++) a[i]=new Array($.num_celdas_vert);
						   
						   
						   
						   for(i=0;i<$.num_celdas_horiz;i++){
							for(j=0;j<$.num_celdas_vert;j++){
								a[i][j] = new Array("33-0",0);
							}
						   }
						   
						   return a;
					   };
					   
					   //Creamos cada tipo de colocación
					   //1x2, 2x2, 2x3, ....
					   $.fn.videowall.create_types = function (){
							for(var i=0;i<$.num_celdas_horiz;i++){
								for(var j=0; j<$.num_celdas_vert;j++){
									$.fn.videowall.create_type(i+1,j+1);
								}
							}
							if($.debug)
								alert("Creadas con exito "+$.distribuciones.length+" distribuciones" );
					   };
					  
					   $.fn.videowall.create_type = function (alto,ancho){
							//Creamos las matices de distribuciones
							for(var i=0;i<$.num_celdas_vert;i++){
								for(var j=0;j<$.num_celdas_horiz;j++){
									//alert(i+"-"+j);
									if((ancho +j -1)<$.num_celdas_horiz && (alto +i -1)<$.num_celdas_vert ){
										//Creamos la estructura de la distribución y de push
										$.distribuciones.push($.fn.videowall.create_distributions(alto,ancho));
										
										//Rellenamos su estructura
										for(var h=0; h<alto;h++){
											for(var v=0; v<ancho;v++){
												//Ponemos los valores a 1 donde iria la imagen
												$.distribuciones[$.distribuciones.length-1][0][i+h][j+v][0] = 1;

												//Ponemos los valores del push
												$.distribuciones[$.distribuciones.length-1][0][i+h][j+v][1] = new Array(h,v);
											}
										}
									}
								}
							} 
					   };
					   
					   //Crea la estructura de las distribuciones
					   //2 matrices, una de posiciones y otra para el push
					   //Estructura de las distribuciones
					   // 0 => array bidimensional de las casillas
					   //	0=>0 si no importa 1 si es necesaria para colocar este tipo
					   //	1=>-1 si no se pone la imagen ahi, en caso contrario es un array de 2 componentes que indica la posicion alto y ancho (en casillas)
					   // 1 => tamaño (en casillas)
					   // 2 => en caso de ser combinados
					  $.fn.videowall.create_distributions =  function (alto,ancho){
						   a=new Array($.num_celdas_horiz);
						   
						   for(i=0;i<$.num_celdas_horiz;i++) a[i]=new Array($.num_celdas_vert);
							 
						   for(i=0;i<$.num_celdas_horiz;i++){
							for(j=0;j<$.num_celdas_vert;j++){
								a[i][j] = new Array();
								a[i][j][0] = 0;
								a[i][j][1] =-1;
							}
						   }
							
							result = new Array(a,alto+"x"+ancho,new Array());
							
							
							
						   return result;
					   };
						//cargamos una imagen en una posicion
					   $.fn.videowall.prepareImg = function (distribucion,src,url,title){
							 
						   //Revisamos el tamaño de la foto
						   var newImg = new Image(); 
						   $(newImg).attr("src",src).load(function(){
							   
								 for(var i=0;i<distribucion[0].length;i++){
									for(var j=0;j<distribucion[0][i].length;j++){
										if(distribucion[0][i][j][1] !="-1"){
											//La pintamos en pantalla
											$.fn.videowall.pushImg((i+1),(j+1),src,url,title,distribucion[0][i][j][1][0],distribucion[0][i][j][1][1]);
											
											//Actualizamos la matriz actual
											$.videowallMatrix[i][j][0]=distribucion[1].replace('x', '')+"-"+$.fotoActual;
											if(distribucion[1]=="3x3")
												$.videowallMatrix[i][j][1]= 0;
											else
												$.videowallMatrix[i][j][1]= $.min_permanencia;
											//alert(dump($.videowallMatrix));
										}
										$.videowallMatrix[i][j][1]--;
									}
								 }
								 //Incrementamos el contador de fotos
								 $.fotoActual++;
								 //Lo reiniciamos para agilizar si ya es demasiado alto
								 if($.fotoActual>500)
									$.fotoActual=1;
									
								 if($.debug)
									 alert("imagen "+src+" Colocada con exito");
								 }); 
						   
						   
					   };
					   
					   
					   
					   
					   $.fn.videowall.pushImg = function (fila,columna,src,url,title,posy,posx){
						   $.animando = true;
						   $("#wall_"+fila+"_"+columna+" .viewer").fadeOut(100,function(){
							$("#wall_"+fila+"_"+columna+" a.viewer").attr("href",url).attr("title",title);
							$("#wall_"+fila+"_"+columna+" .viewer").css("background",'#000 url("'+src+'") no-repeat scroll -'+ posx*$.ancho_celda +'px -'+ posy*$.alto_celda +'px').fadeIn(function(){
								
									$.animando = false;
								});
								
							 });
																 
					   };
					   
					   //Funcion que devuelve la url de una foto
					   $.fn.videowall.getImg = function (type,distribucion){
						   var datos;
						   $.get("img/imagenes.php?dimensions="+type, function(data){
								//alert("Data Loaded: " + data);
								image = data.split('&&');
								src = image[0];
								url = image[1];
								title= image[2];
								$.fn.videowall.prepareImg(distribucion,src,url,title);
								$.procesadas++;
							});
								
								//alert(datos);
					   };
					   $.fn.videowall.aleatorio = function (a,b) {
							return Math.round(Math.random()*(b-a)+a);
					   };
					   
					   $.fn.videowall.copy = function (o) {
							if (typeof o != "object" || o === null) return o;
							var r = o.constructor == Array ? [] : {};
							for (var i in o) {
								r[i] = $.fn.videowall.copy(o[i]);
							}
							return r;
						};
						$.fn.videowall.stop = function(){
							$.stop = true;
						};
						$.fn.videowall.play = function(){
							$.stop = false;
						};
						$.fn.videowall.createEstructure = function(){
							for(i=1;i<$.num_celdas_horiz+1;i++){
								for(j=1;j<$.num_celdas_vert+1;j++){
									$("#"+$.capa).append('<div id="wall_'+ i +'_'+j +'" class="ladrillo"><a href="#" class="viewer" rel="'+i +'x'+j +'" alt=""></a><a href="#" class="viewer_fixed" rel="'+i +'x'+j +'"></a></div>');	
								}
							}
							
						};
						
						//Esta este array dentro de otro?
						$.fn.videowall.arrayInArray = function(component, array){
							var iguales = 0;
							for(i=0; i<array.length;i++){
								for(j=0;j<array[i].length;j++){
									if(array[i][j]==component[j]){
										iguales++;
									}
								}
								if(iguales == component.length)
									return true;
								else
									iguales =0;
							}							
							return false;
						};
						
						$.fn.mouseOver = function(){};
						$.fn.videowall.setMouseOver = function(funcion){
							$.fn.mouseOver = funcion;
						};
						
						//Creamos las interacciones cuando el raton esta encima
						$.fn.videowall.interactions = function(){
							$("#"+$.capa+" .ladrillo").mouseenter(function() {
								$.fn.videowall.stop();
								
								//sacamos las coordenadas de donde esta el raton
								var dimensiones =$(this).attr("id");
								dimensiones = dimensiones.replace("wall_","");
								dimensiones = dimensiones.split("_");
								estatus = $.videowallMatrix[dimensiones[0]-1][dimensiones[1]-1][0];
								
								animacion=estatus.split("-");
								
								//Si donde ha entrado no esta señalado y no es inicio de videowall, se recalcula
								if($(".viewer_fixed[rel="+dimensiones[0]+"x"+dimensiones[1]+"]").css("z-index")!="1" 
								   && animacion[1] != 0 ){
									//Limpiamos las señaladas actualmente
									$(".viewer_fixed").css("z-index","-1").css("border","none").css("margin","0px");
									$(".viewer_fixed").hover(function(){
										//$(this).qtip({content: '...' });
									});
									
									var casillas_resaltar = Array();
									//Calculamos las otras casillas a resaltar
									for(i=0;i<$.videowallMatrix.length;i++){
										for(j=0;j<$.videowallMatrix[i].length;j++){
											if($.videowallMatrix[i][j][0]==estatus){
												casillas_resaltar.push(new Array(i,j));
											}else{
												//quitamos opacidad a las casillas que que no nos importna
												x=i+1;
												y=j+1;
												$(".viewer_fixed[rel="+x+"x"+y+"]")
													.css("background","none repeat scroll 0 0 #000000")
													.css("border","none")
													.css("opacity","0.7")
													.css("z-index","0")
													.css("margin","1px");
												//	.animate({opacity: 0.7});
											}
										}
									}
									
									//Fijamos casilla a casilla
									for(ind=0;ind<casillas_resaltar.length;ind++){
										
										x = casillas_resaltar[ind][0] +1;
										y = casillas_resaltar[ind][1] +1;
										
											
											
											$(".viewer_fixed[rel="+x+"x"+y+"]")
											.attr("style",$(".viewer[rel="+x+"x"+y+"]").attr("style"))
											.attr("href",$(".viewer[rel="+x+"x"+y+"]").attr("href"))
											.attr("work",$(".viewer[rel="+x+"x"+y+"]").attr("title"))
											.css("margin","0px")
											.css("border","none")
											.css("opacity","1")
											.css("z-index","1");
											
											//Hay algo arriba?
											if(!$.fn.videowall.arrayInArray(new Array(casillas_resaltar[ind][0]-1,casillas_resaltar[ind][1]),casillas_resaltar)){
												  $(".viewer_fixed[rel="+x+"x"+y+"]")
													.css("border-top","2px solid #fff")
													.css("margin-top","-2px");
											}
											//Hay algo abajo?
											if(!$.fn.videowall.arrayInArray(new Array(casillas_resaltar[ind][0]+1,casillas_resaltar[ind][1]),casillas_resaltar)){
												  $(".viewer_fixed[rel="+x+"x"+y+"]").css("border-bottom","2px solid #fff");
											}
											//Hay algo izquierda?
											if(!$.fn.videowall.arrayInArray(new Array(casillas_resaltar[ind][0],casillas_resaltar[ind][1]-1),casillas_resaltar)){
												  $(".viewer_fixed[rel="+x+"x"+y+"]")
													.css("border-left","2px solid #fff")
													.css("margin-left","-2px");;
											}
											//Hay algo derecha?
											if(!$.fn.videowall.arrayInArray(new Array(casillas_resaltar[ind][0],casillas_resaltar[ind][1]+1),casillas_resaltar)){
												  $(".viewer_fixed[rel="+x+"x"+y+"]").css("border-right","2px solid #fff");
											}
									}
									
									//llamamos a la funcion predefinida por el usuario al moverse de sitio
									$.fn.mouseOver(".viewer_fixed[rel="+x+"x"+y+"]");
								}
								$.fn.videowall.play();
							});
							$("#"+$.capa).mouseleave(function() {
									//Si se sale del videowall se des-selecciona todo
									$(".viewer_fixed").css("z-index","-1").css("border","none").css("margin","0px");	
								});

						};
						
	//Inicializamos todos los valores necesarios
	$.fn.videowall.inicialize();
	
}
