sub GetModuleDir {
	my ($module)=@_;
	my ($directory) = "";

#	print "mymodule=".$module . "\n";
	open(MOD_FILE_ID,"$FICHERO_MODULOS");
	foreach $linea_modulo (<MOD_FILE_ID>)
	{
		($directorio_item, $nombre_modulo_item) = split(/\|/, $linea_modulo);
		chop $nombre_modulo_item;
		if ($nombre_modulo_item eq $module)
		{
			$directory=$directorio_item;
		}
	}
	close MOD_FILE_ID;
	return $directory;
}

sub ListModules {
	open(MOD_FILE_ID,"$FICHERO_MODULOS");
	%lista_modulos=();
	foreach $linea_modulo (<MOD_FILE_ID>)
	{
#		print "linea=$linea_modulo";
		($directorio, $nombre_modulo) = split(/\|/, $linea_modulo);
		chop $nombre_modulo;
#		print "entrada=$linea_modulo $directorio, $nombre_modulo";
		$lista_modulos{"$nombre_modulo"}="$nombre_modulo";
	}
	close MOD_FILE_ID;
	return %lista_modulos;
}

sub ListModulesComplex {
	open(MOD_FILE_ID,"$FICHERO_MODULOS") || die();
	%lista_modulos_comp=();
	my ($directorio, $nombre_modulo);
	foreach $linea_modulo (<MOD_FILE_ID>)
	{
		($directorio, $nombre_modulo) = split(/\|/, $linea_modulo);
		chop $nombre_modulo;
		$lista_modulos_comp{"$nombre_modulo"}="$directorio";
	}
	close MOD_FILE_ID;
	return %lista_modulos_comp;
}

sub AddNewLine {
	my ($anchor_text, $query)=@_;
	$javascript_command="document.formulario.ANCHOR.value='" . $anchor_text ."'";
	print $query->submit(-name=>'NEWLINE',
						-onClick=>"$javascript_command",
						-value=>'Añadir otra fila'
					);
}

sub RemoveLine {
	my ($element, $index, $anchor_text, $query)=@_;
	$javascript_command="document.formulario.$element" . $index . ".value='';document.formulario.ANCHOR.value='" . $anchor_text ."'";
	print $query->submit(-name=>'NEWLINE',
						-onClick=>"$javascript_command",
						-value=>'Borrar fila'
					);
}

sub GenerateAnchor {
	my ($anchor_text, $query)=@_;
	if ($query->param('ANCHOR') && $query->param('ANCHOR') eq $anchor_text) {
print <<END;
<A NAME="marca">&nbsp;</A>
END
	}
}

sub ListRows {
	my ($PATRON, $query)=@_;
	my $max=0;
	@elementos=();
	foreach $element ($query->param) {
		$_=$element;
		if (/$PATRON/ && $query->param($_) ne "") {
			s/$PATRON//;
			push @elementos, $_;
			if ($_ > $max) {
				$max=$_;
			}
		}
	}
	push @elementos, $max+1;
	return @elementos;
}

sub ListProcessesModule {
	my($module_name)=@_;
	@processes=();
	if (! defined($module_name)) {
		return @processes;
	}
	$directory=&GetModuleDir($module_name);
	foreach $process_file (glob($DIRECTORIO_ALMACENAMIENTO . $SEPARADOR . $directory . $SEPARADOR . '*')) {
		open (IN, "$process_file");
		my $process_reg=new CGI(IN);
		close IN;
		push @processes, $process_reg->param('NOMBRE_PROCESO');
	}
	return @processes;
}

sub SaveModule {
	my($query)=@_;
	my $module_name="";
	if ($query->param('MODULE_NAME_MENU') && $query->param('MODULE_NAME_MENU') ne "INICIO") {
		$dir_modulo=&GetModuleDir($query->param('MODULE_NAME_MENU'));
		$MODULE_FILENAME=$DIRECTORIO_ALMACENAMIENTO . $dir_modulo . ".txt";
		open(MODULE_FILEID,">$MODULE_FILENAME") || die ("$MODULE_FILENAME");
		$query->save(MODULE_FILEID);
		close(MODULE_FILEID);
	}
}

sub GenerarFicheroDescripcion {
	my($query)=@_;
	if ($query->param('MODULE_NAME_MENU') eq "INICIO") {
		return;
	}
	$nombre_modulo=$query->param('MODULE_NAME_MENU');
	$dir_modulo=&GetModuleDir($nombre_modulo);
#	$MODULE_FILENAME=$DIRECTORIO_ALMACENAMIENTO . $dir_modulo . ".txt";
#	if (open (IN, "$module_file")) {
#		$query=new CGI(IN);
#		close IN;
#	} 
	$MODULE_DESC_FILENAME=$DIRECTORIO_DESCRIPCION . $dir_modulo . ".txt";
	open(INFILE, ">$MODULE_DESC_FILENAME");

	print INFILE "<módulo>$NL"; # <módulo>

	print INFILE "$nombre_modulo$NL"; # nombre del modulo
	$fecha=$query->param('FECHA');
	print INFILE "$fecha$NL";  # fecha
	$version=$query->param('VERSION');
	print INFILE "$version$NL"; # version

	@lista_procesos=&ListProcessesModule($nombre_modulo);
	$num_procesos=@lista_procesos;
	print INFILE "$num_procesos$NL"; # nº de procesos
	$protocolo=$query->param('PROTOCOLO');
	print INFILE "$protocolo$NL"; # usuarios.protocolo
	$usu_conc=$query->param('NUM_USU');
	print INFILE "$usu_conc$NL"; # usuarios. numero de usuarios concurrentes

	&PrintMemo($query->param('PREVISION'), INFILE); # usuarios.prevision de crecimiento
	&PrintMemo($query->param('PROCESOS'), INFILE); # usuarios.tipo de procesos
	&PrintMemo($query->param('ADMIN_PERFIL'), INFILE); # administrador.perfil

	@columnas=("INTERLOCUTORES_NOMBRE_", "INTERLOCUTORES_DEP_", "INTERLOCUTORES_TELEF1_", "INTERLOCUTORES_TELEF2_");
	&PrintTable($query, "Interlocutores", 1, INFILE, @columnas); # interlocutores

	@columnas=("USUARIOS_NOMBRE_", "USUARIOS_DEP_", "USUARIOS_UBIC_", "USUARIOS_ACCESO_");
	&PrintTable($query, "Usuarios", 0, INFILE, @columnas); # usuarios

	@columnas=("ADMINISTRADORES_NOMBRE_", "ADMINISTRADORES_DEP_", "ADMINISTRADORES_TELEF1_", "ADMINISTRADORES_TELEF2_");
	&PrintTable($query, "Administradores", 0, INFILE, @columnas); # administradores

	# Ahora tengo que recorrer todos los procesos del modulo

	foreach $process_file (glob($DIRECTORIO_ALMACENAMIENTO . $SEPARADOR . $dir_modulo . $SEPARADOR . '*')) {
		open (IN, "$process_file");
		my $process_reg=new CGI(IN);
		close IN;
		&PrintProcess($process_reg, INFILE);

	}

	print INFILE "<fin de modulo>$NL";
	close INFILE;

	# Finalmente envio el correo
	&SendMailGenerateModule($dir_modulo, $nombre_modulo);
}

sub PrintProcess {
	my($query, $INFILEID)=@_;

	$isbatch=0;
	$tipo=$query->param('TIPO');
	if ($tipo eq "batch") {
		$isbatch=1;
	} elsif ($tipo eq "online") {
		$isbatch=0;
	} else {
		# Esto no puede ser, simepre debe llegar un parametro
		die("Esto es un error de invocacion");
	}

	if ($isbatch) {
		print $INFILEID "<proceso batch>$NL"; # <proceso>
	} else {
		print $INFILEID "<proceso on-line>$NL"; # <proceso>
	}

	$nombre_proceso=$query->param('NOMBRE_PROCESO');
	print $INFILEID "$nombre_proceso$NL";  # nombre del proceso
	$fichero=$query->param('FICHERO');
	print $INFILEID "$fichero$NL"; # nombre del fichero
	$codigo=$query->param('CODIGO');
	print $INFILEID "$codigo$NL"; # codigo
	$autor=$query->param('AUTOR');
	print $INFILEID "$autor$NL"; # autor
	$fecha=$query->param('FECHA');
	print $INFILEID "$fecha$NL"; # fecha
	$version=$query->param('VERSION');
	print $INFILEID "$version$NL"; # version
	$num_servicios=&ListServices($query);

	# Los procesos batch no tienen servicios
	if (!$isbatch) {
		print $INFILEID "$num_servicios$NL"; #nº de servicios
	}

	$en_archivo=$query->param('EN_ARCHIVO');
	print $INFILEID "$en_archivo$NL"; # informacion para gestion de entradas.archivo
	$en_ubicacion=$query->param('EN_UBICACION');
	print $INFILEID "$en_ubicacion$NL"; # informacion para gestion de entradas.ubicacion
	$en_procedencia=$query->param('EN_PROCEDENCIA');
	print $INFILEID "$en_procedencia$NL"; # informacion para gestion de entradas.procedencia
	$en_contenido=$query->param('EN_CONTENIDO');
	print $INFILEID "$en_contenido$NL"; # informacion para gestion de entradas.contenido
	$sal_archivo=$query->param('SAL_ARCHIVO');
	print $INFILEID "$sal_archivo$NL"; # informacion para gestion de salidas.archivo
	$sal_ubicacion=$query->param('SAL_UBICACION');
	print $INFILEID "$sal_ubicacion$NL"; # informacion para gestion de salidas.ubicacion
	$sal_contenido=$query->param('SAL_CONTENIDO');
	print $INFILEID "$sal_contenido$NL"; # informacion para gestion de salidas.contenido
	$rollbacks=$query->param('SEGMENTOS');
	print $INFILEID "$rollbacks$NL"; # rdbms.rollbacks
	$commit=$query->param('COMMIT');
	print $INFILEID "$commit$NL"; # rdbms.commit
	$buffers=$query->param('ESPACIOS');
	print $INFILEID "$buffers$NL"; # rdbms.buffers

	&PrintMemo($query->param('DESCRIPCION'), $INFILEID); # descripcion del proceso
	
	# Los procesos online no tienen "arranque y parada
	if ($isbatch) {
		&PrintMemo($query->param('ARRANQUE'), $INFILEID); # arranque, parada y monitorizacion
	}

	&PrintMemo($query->param('FICHEROS'), $INFILEID); # mensajes de log

	if ($isbatch) {
		@columnas=("MENSAJES_CODIGO_", "MENSAJES_DESC_", "MENSAJES_ACCION_", "MENSAJES_TIVOLI_", "MENSAJES_EXITCODE_");
		&PrintTable($query, "Detalle de los mensajes de logs (Batch)", 1, $INFILEID, @columnas); # detalle de los mensajes de log (batch)
	} else {
		@columnas=("MENSAJES_CODIGO_", "MENSAJES_DESC_", "MENSAJES_ACCION_");
		&PrintTable($query, "Detalle de los mensajes de logs (On-line)", 1, $INFILEID, @columnas); # detalle de los mensajes de log (on-line)
	}

	@columnas=("TABLAS_PROC_NOMBRE_", "TABLAS_PROC_BBDD_", "TABLAS_PROC_S_", "TABLAS_PROC_D_", "TABLAS_PROC_U_", 
		"TABLAS_PROC_I_", "TABLAS_PROC_ORDERBY_", "TABLAS_PROC_GROUPBY_", "TABLAS_PROC_DISTINCT_", 
		"TABLAS_PROC_UNION_", "TABLAS_PROC_FILAS_");
	&PrintTable($query, "Tablas referenciadas por el proceso", 0, $INFILEID, @columnas); # tablas referenciadas
	
	@columnas=("CLAVES_PROC_"); 
	&PrintTable($query, "Claves e índices usados por el proceso", 0, $INFILEID, @columnas); # claves e indices usados

	@columnas=("SECUENCIAS_PROC_"); 
	&PrintTable($query, "Secuencias usadas por el proceso", 0, $INFILEID, @columnas); # secuencias

	@columnas=("VISTAS_PROC_"); 
	&PrintTable($query, "Vistas usadas por el proceso", 0, $INFILEID, @columnas); # vistas

	@id_servicios=&ListServices($query);
	foreach $id_serv (@id_servicios) {
		&PrintService($id_serv, $query, $INFILEID);
	}
}

sub PrintMemo {
	my($memo, $INFILEID)=@_;
	my @lineas=();
	$memo =~ s/\\r\\n/\\n/ ;
	$memo =~ s/\\n/\\r\\n/ ;
	@lineas=split("\\r\\n", $memo);
	$num_lineas=@lineas;
	print $INFILEID "$num_lineas$NL";
	print $INFILEID "$memo$NL";
}

sub PrintTable {
	# obligatorio=1 quiere decir que se imprime la tabla aunque no tenga ninguna fila (aunque en teoria
	#siempre la tendra)

	my ($query, $identificador, $obligatorio, $INFILEID, @columnas)=@_;
	my $salida="";
	$clave=$columnas[0];
	$num_columnas=@columnas;
	my $num_filas=0;
	foreach $element ($query->param) {
		$_=$element;
		if (/^$clave/ && $query->param($_) ne "") {
			s/^$clave//;
			$indice=$_;
			foreach $columna (@columnas) {
				$value=$query->param($columna . $indice);
				$salida.="$value$NL";
			}
			$num_filas++;
		}
	}
	if (!$obligatorio && $num_filas == 0) {
	} else {
	print $INFILEID "<tabla>$NL";
	print $INFILEID "$identificador$NL";
	print $INFILEID "$num_filas$NL";
	print $INFILEID "$num_columnas$NL";
	print $INFILEID "$salida";
	}
}

sub PrintService {
	my ($id_service, $query, $INFILEID)=@_;
	print $INFILEID "<servicio>$NL"; # <servicio>
	$nombre_servicio=$query->param("NOMBRE_SRV_".$id_serv);
	print $INFILEID "$nombre_servicio$NL"; # nombre del servicio
	&PrintMemo($query->param("DESC_SRV_".$id_serv), $INFILEID); # descripcion del proceso

	@columnas=("TABLAS_SRV_NOMBRE_".$id_serv."_", "TABLAS_SRV_BBDD_".$id_serv."_", "TABLAS_SRV_S_".$id_serv."_",
		"TABLAS_SRV_D_".$id_serv."_", "TABLAS_SRV_U_".$id_serv."_", "TABLAS_SRV_I_".$id_serv."_", 
		"TABLAS_SRV_ORDERBY_".$id_serv."_", "TABLAS_SRV_GROUPBY_".$id_serv."_", 
		"TABLAS_SRV_DISTINCT_".$id_serv."_", "TABLAS_SRV_UNION_".$id_serv."_", 
		"TABLAS_SRV_FILAS_".$id_serv."_");
	&PrintTable($query, "Tablas referenciadas por el servicio", 0, $INFILEID, @columnas); # tablas referenciadas
	
	@columnas=("CLAVES_SRV_".$id_serv."_"); 
	&PrintTable($query, "Claves e índices usados por el servicio", 0, $INFILEID, @columnas); # claves e indices usados

	@columnas=("SECUENCIAS_SRV_".$id_serv."_"); 
	&PrintTable($query, "Secuencias usadas por el servicio", 0, $INFILEID, @columnas); # secuencias

	@columnas=("VISTAS_SRV_".$id_serv."_"); 
	&PrintTable($query, "Vistas usadas por el servicio", 0, $INFILEID, @columnas); # vistas
}

sub SaveProcess {
	my($query)=@_;
	my $module_name="";
	if ($query->param('CODIGO')) {
		if ($query->param('MODULE_NAME')) {
			$module_name=$query->param('MODULE_NAME');
			&NewModule($query->param('MODULE_NAME'));
			$query->param(-name=>'MODULE_NAME_MENU', -value=>"$module_name");
			$query->delete('MODULE_NAME');
		} else {
			$module_name=$query->param('MODULE_NAME_MENU');
		}	
		$dir_modulo=&GetModuleDir($module_name);
		print "dir_modulo=".$dir_modulo;
		$codigo=$query->param('CODIGO');
		# Primero tngo que borrar el antiguo, este en el modulo que este
		($PROCESS_FILENAME) = (glob($DIRECTORIO_ALMACENAMIENTO . '*' . $SEPARADOR . $codigo));
		if (-f $PROCESS_FILENAME) {
			unlink $PROCESS_FILENAME;
		}
		$PROCESS_FILENAME=$DIRECTORIO_ALMACENAMIENTO . $dir_modulo . $SEPARADOR . $codigo;
		open(PROCESS_FILEID,">$PROCESS_FILENAME") || die;
		$query->save(PROCESS_FILEID);
		close(PROCESS_FILEID);
	}
}

sub NewModule {
	my($module)=@_;
	my ($secs, $aleatorio, $directory);
	%lista_modulos=&ListModulesComplex();
	$secs=time();
	$aleatorio=rand(100);
	$aleatorio =~ s/\..*//;
	$directory="$secs" . '_' . "$aleatorio"; 
	$lista_modulos{"$module"}=$directory;
	mkdir $DIRECTORIO_ALMACENAMIENTO . $SEPARADOR . $directory, 0775;
	open(MOD_FILE_ID, ">$FICHERO_MODULOS") || die();
	foreach $module_item (keys %lista_modulos) {
		print MOD_FILE_ID $lista_modulos{$module_item} . "|" . $module_item . "\n";
	}
	close MOD_FILE_ID;
}
		
sub ListProcesses {
	my ($tipo)=@_;
	%processes=();
	foreach $process_file (glob($DIRECTORIO_ALMACENAMIENTO . $SEPARADOR . '*' . $SEPARADOR . '*')) {
		open (IN, "$process_file");
		my $process_reg=new CGI(IN);
		close IN;
		if ($process_reg->param('TIPO') eq $tipo) {
			$proceso=$process_reg->param('NOMBRE_PROCESO');
			$codigo=$process_reg->param('CODIGO');
			$processes{$codigo}=$proceso;
		}
	}
	return %processes;
}


sub ListServices {
	my ($query)=@_;
	my $max=0;
	@elementos=();
	foreach $element ($query->param) {
		$_=$element;
		if (/^NOMBRE_SRV_/ && $query->param($_) ne "") {
			s/^NOMBRE_SRV_//;
			push @elementos, $_;
			if ($_ > $max) {
				$max=$_;
			}
		}
	}
	if ($query->param('NEWSERVICE')) {
			push @elementos, $max+1;
	}
	return @elementos;
}




sub RemoveService {
	my ($element, $index, $anchor_text, $query)=@_;
	$javascript_command="document.formulario.$element" . $index . ".value='';document.formulario.ANCHOR.value='" . $anchor_text ."'";
	print $query->submit(-name=>'NEWLINE',
						-onClick=>"$javascript_command",
						-value=>'Eliminar Servicio'
					);
}



sub AddService {
	my ($query)=@_;
	$javascript_command="document.formulario.ANCHOR.value='"."SERVICIOS"."'";

	print $query->submit(-name=>'NEWSERVICE',
						-onClick=>"$javascript_command",
						-value=>'Crear Servicio Nuevo'
						);

}

sub SendMailGenerateModule {
	my ($module_id, $module_name)=@_;

	use MongerMail;
	foreach $direccion (@DIRECCIONES_EMAIL) {
		my $mail = new MongerMail($MAIL_PROGRAM);
		$mail->to($direccion);
		$mail->from($ADMIN_EMAIL);
		$mail->subject("Nuevo módulo generado " . $module_name);
		$mail->content("Este es un mensaje automático enviado por el sistema de documentación \r\n de producción para indicarle que se ha generado un nuevo documento de módulo.\r\n El anexo contiene el fichero de descripción del módulo: " . $module_name . " .\r\n Por favor, recuerde que para generar el documento Word final debe procesar el fichero descriptor de módulo \r\n que acaba de recibir con la aplicación GENDOC");
		$mail->attachment($DIRECTORIO_DESCRIPCION . $module_id. ".txt");
		$mail->send;
	}
}
1;