                                copy.width = trimmed.width;
                                copy.height = trimmed.height;
                                copyCtx.putImageData(trimmed, 0, 0);
                        
                                return copy;
                            };
                        })();
					</script>';


        //Agrega etiqueta del campo si es diferente de vacio
		if ($registro_campos["titulo"]!="" && $registro_campos["ocultar_etiqueta"]=="0")
            $salida.='<label for="'.$registro_campos["campo"].'">'.PCO_ReemplazarVariablesPHPEnCadena($registro_campos["titulo"],$registro_datos_formulario).':</label>';
		//Abre el marco del control de datos
		$salida.='<div class="form-group input-group" style="display: block !important; ">';
		
		//Verifica si el ancho o el alto tienen alguna barra de proporcion indicando porcentaje final de escalado
		$PartesAncho=explode("|",$registro_campos["ancho"]);
		$AnchoCanvas=$PartesAncho[0]; //Toma el ancho inicial del canvas
		$ProporcionFinalAnchoCanvas=$PartesAncho[1]; if ($ProporcionFinalAnchoCanvas=="") $ProporcionFinalAnchoCanvas=1; //Define Proporcion final (0.5,2,1.5,etc)
		$PartesAlto=explode("|",$registro_campos["alto"]);
		$AltoCanvas=$PartesAlto[0]; //Toma el ancho inicial del canvas
		$ProporcionFinalAltoCanvas=$PartesAlto[1]; if ($ProporcionFinalAltoCanvas=="") $ProporcionFinalAltoCanvas=1; //Define Proporcion final (0.5,2,1.5,etc)

		// Muestra el campo
		$salida.='<canvas id="CANVAS_'.$registro_campos["campo"].'" width="'.$AnchoCanvas.'" height="'.$AltoCanvas.'" style="border: 1px solid #acc; display: block;">Su navegador no soporta Canvas</canvas>
			<!--<a href="javascript:limpiar_CANVAS_'.$registro_campos["campo"].'();"><i class="fa fa-times fa-2x"></i></a>-->
            <a href="#CANVAS_'.$registro_campos["campo"].'" data-tool="eraser" class="btn btn-link" role="button">Borrar</a>
            <a href="#CANVAS_'.$registro_campos["campo"].'" data-tool="marker" class="btn btn-link" role="button">Marcador</a>
			<script type="text/javascript">';

        //Prepara la funcion de reactivacion del canvas para el final del script
        $funciones_activacion_canvas.='
                $(function ()
					{
						$(\'#CANVAS_'.$registro_campos["campo"].'\').sketch({defaultColor: "'.$registro_campos["color_trazo"].'", defaultSize: "'.$registro_campos["tamano_pincel"].'"});
					});';

        $salida.='
				/*
				// Genera el vinculo entre el enlace de upload y la funcion
				$("#upload").on("click", function ()
					{
						var oCanvas = document.getElementById("CANVAS_'.$registro_campos["campo"].'");
						var strDataURI = oCanvas.toDataURL();
						//alert(strDataURI); //Muestra el resultado en base64
					});
				*/

				function limpiar_CANVAS_'.$registro_campos["campo"].'()
					{
						// Busca el contexto del canvas y le reasigna ancho y alto para limpiarlo
						var oCanvas = document.getElementById("CANVAS_'.$registro_campos["campo"].'");
						var oContext = oCanvas.getContext("2d");
						//FORMA1:
							oContext.clearRect(0, 0, oCanvas.width, oCanvas.height);
						/*//FORMA2:
							oCanvas.width = oCanvas.width;*/
						/*//FORMA3:
							oContext.save();
							oContext.fillStyle = "#FFF";
							oContext.fillRect(0, 0, oCanvas.width, oCanvas.height);
							oContext.restore();
							oCanvas.clear();*/
						/*//FORMA4:
							var ancho_anterior = oCanvas.width;
							oCanvas.width = 1;
							oCanvas.width = ancho_anterior;*/
					}

				function actualizar_CANVAS_'.$registro_campos["campo"].'()
					{
						// Pasa el valor del canvas al campo que se usa en almacenamiento
						if (!isCanvasBlank(CANVAS_'.$registro_campos["campo"].'))
						    {
                				oCanvas=RecortarCANVAS_'.$registro_campos["campo"].'(CANVAS_'.$registro_campos["campo"].');
                				//document.'.$IdHTMLFormulario.'.'.$registro_campos["campo"].'.value=oCanvas.toDataURL();	 //Almacena imagen al 100%

                                //Redimensiona el canvas sobre otro (Si aplica)
                                RedimensionarCanvas(oCanvas,'.$ProporcionFinalAnchoCanvas.','.$ProporcionFinalAltoCanvas.');
                				document.'.$IdHTMLFormulario.'.'.$registro_campos["campo"].'.value=oCanvas.toDataURL();	     //Almacena imagen redimensionada
						    }
						window.setTimeout("actualizar_CANVAS_'.$registro_campos["campo"].'()",1000);
					}

				$( document ).ready(function() {
				    actualizar_CANVAS_'.$registro_campos["campo"].'();
				});
			</script>
			<input type="hidden" name="'.$registro_campos["campo"].'">';

		//Si hay algun indicador adicional del campo abre los add-ons
        if ($registro_campos["valor_unico"] == "1" || $registro_campos["obligatorio"] || $registro_campos["ayuda_titulo"] != "")
            {
                $salida.= '<span class="input-group-addon">';
                // Muestra indicadores de obligatoriedad o ayuda
                if ($registro_campos["obligatorio"]) $salida.= '<a href="#"   data-toggle="tooltip" data-html="true"  data-placement="auto" title="<b>'.$MULTILANG_TitObligatorio.'</b><br>'.$MULTILANG_DesObligatorio.'"><i class="fa fa-exclamation-triangle icon-orange"></i></a>';
                if ($registro_campos["ayuda_titulo"] != "") $salida.= '<a href="#"   data-toggle="tooltip" data-html="true"  data-placement="auto" title="<b>'.PCO_ReemplazarVariablesPHPEnCadena($registro_campos["ayuda_titulo"],$registro_datos_formulario).'</b><br>'.PCO_ReemplazarVariablesPHPEnCadena($registro_campos["ayuda_texto"],$registro_datos_formulario).'"><i class="fa fa-question-circle"></i></a>';
                $salida.= '</span>';
            }
        //Cierra marco del control de datos
        $salida.= '</div>';
		return $salida;
	}


########################################################################
########################################################################
/*
	Function: PCO_CargarObjetoCamara
	Genera el codigo HTML y CSS correspondiente a un campo de canvas usado para la captura de una imagen desde webcam

	Variables de entrada:

		registro_campos - listado de campos sobre el formulario en cuestion
		registro_datos_formulario - Arreglo asociativo con nombres de campo y valores cuando se hacen llamados de registro especificos

	Salida:

		HTML, CSS y Javascript asociado al objeto publicado dentro del formulario

	Ver tambien:
		<PCO_CargarFormulario>
*/
function PCO_CargarObjetoCamara($registro_campos,$registro_datos_formulario,$formulario)
	{
		global $TablasCore,$PCO_CampoBusquedaBD,$PCO_ValorBusquedaBD;
		global $MULTILANG_Cerrar,$MULTILANG_FrmCanvasLink,$MULTILANG_Capturar,$MULTILANG_FrmErrorCam,$MULTILANG_DesObligatorio,$MULTILANG_TitObligatorio;

        //Busca datos del formulario
        $RegistroDisenoFormulario=PCO_EjecutarSQL("SELECT * FROM ".$TablasCore."formulario WHERE id=?", "$formulario")->fetch();
        $IdHTMLFormulario=$RegistroDisenoFormulario["id_html"];

		$salida='';
		$nombre_campo=$registro_campos["campo"];

		// Si detecta un valor en el registro entonces agrega el contenido
		if ($PCO_CampoBusquedaBD!="" && $PCO_ValorBusquedaBD!="" && $registro_datos_formulario["$nombre_campo"]!="")
			{
				$cadena_decodificada=$registro_datos_formulario["$nombre_campo"];
				$cadena_decodificada=gzdecode($cadena_decodificada);
				$salida.='<a href="javascript:AbrirPopUp(\'CANVASPrevio'.$registro_campos["campo"].'\');"><i class="fa fa-picture-o"></i><b>'.$MULTILANG_FrmCanvasLink.'</b></a><br>
					<!-- INICIO DE MARCOS POPUP -->
					<div id="CANVASPrevio'.$registro_campos["campo"].'" class="FormularioPopUps">
						<div align=center>
							<table bgcolor="#FFFFFF"><tr><td>
								<img src="'.$cadena_decodificada.'" border=1>
							</td></tr></table>
						</br>
						<input type="Button"  class="Botones" value=" -- '.$MULTILANG_Cerrar.' -- " onClick="OcultarPopUp(\'CANVASPrevio'.$registro_campos["campo"].'\')">
						</div>
					<!-- FIN DE MARCOS POPUP -->
					</div>';
			}

		// Muestra el campo
		$escala_reduccion=1;
        //Agrega etiqueta del campo si es diferente de vacio
		if ($registro_campos["titulo"]!="" && $registro_campos["ocultar_etiqueta"]=="0")
            $salida.='<label for="'.$registro_campos["campo"].'">'.PCO_ReemplazarVariablesPHPEnCadena($registro_campos["titulo"],$registro_datos_formulario).':</label>';
		//Abre el marco del control de datos
		$salida.='<div class="form-group input-group">';

		$salida.='
			<table border=0>
				<tr>
					<td valign=top>
						<div id="container" style="margin: 0px auto; width: '.$registro_campos["ancho"].'px; height: '.$registro_campos["alto"].'px; border: 1px solid #acc;">
							<video autoplay id="videoElement"  style="width: '.$registro_campos["ancho"].'px; height: '.$registro_campos["alto"].'px;">
							</video>
						</div>
					</td>
					<td valign=top>
                        <i class="fa fa-camera" OnClick="draw(v,context,w,h);"></i>
						<br>
						<canvas id="CANVAS_'.$registro_campos["campo"].'" width="'.(($registro_campos["ancho"]/$escala_reduccion)).'" height="'.(($registro_campos["alto"]/$escala_reduccion)).'" style="width: '.(($registro_campos["ancho"]/$escala_reduccion)).'px; height: '.(($registro_campos["alto"]/$escala_reduccion)).'px; background-color: #CCC; visibility:visible;"></canvas>
					</td>
				</tr>
			</table>

			<script>
				var video = document.querySelector("#videoElement");
				navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia || navigator.oGetUserMedia;

				if (navigator.getUserMedia) {
					navigator.getUserMedia({video: true}, handleVideo, videoError);
				}

				function handleVideo(stream) {
					video.src = window.URL.createObjectURL(stream);
				}

				function videoError(e) {
					alert("'.$MULTILANG_FrmErrorCam.'");
				}

				var v,CANVAS_'.$registro_campos["campo"].',context,w,h;
				var sel = document.getElementById(\'fileselect\');

				document.addEventListener(\'DOMContentLoaded\', function(){
				v = document.getElementById(\'videoElement\');
				CANVAS_'.$registro_campos["campo"].' = document.getElementById(\'CANVAS_'.$registro_campos["campo"].'\');
				context = CANVAS_'.$registro_campos["campo"].'.getContext(\'2d\');
				w = CANVAS_'.$registro_campos["campo"].'.width;
				h = CANVAS_'.$registro_campos["campo"].'.height;
				},false);

				function draw(v,c,w,h) {
				if(v.paused || v.ended) return false;
				context.drawImage(v,0,0,w,h);
				var uri = CANVAS_'.$registro_campos["campo"].'.toDataURL("image/png");
				}

				var fr;
				sel.addEventListener(\'change\',function(e){
				var f = sel.files[0];
				fr = new FileReader();
				fr.readAsDataURL(f);
				})
			</script>';

		$salida.='
			<script>
				function actualizar_CANVAS_'.$registro_campos["campo"].'()
					{
						// Pasa el valor del canvas al campo que se usa en almacenamiento
						var oCanvas = document.getElementById("CANVAS_'.$registro_campos["campo"].'");
						var strDataURI = oCanvas.toDataURL();
						document.'.$IdHTMLFormulario.'.'.$registro_campos["campo"].'.value=strDataURI;
						window.setTimeout("actualizar_CANVAS_'.$registro_campos["campo"].'()",1000);
					}
				window.setTimeout("actualizar_CANVAS_'.$registro_campos["campo"].'()",1000);
			</script>
			<input type="hidden" name="'.$registro_campos["campo"].'">';
		//Si hay algun indicador adicional del campo abre los add-ons
        if ($registro_campos["valor_unico"] == "1" || $registro_campos["obligatorio"] || $registro_campos["ayuda_titulo"] != "")
            {
                $salida.= '<span class="input-group-addon">';
                // Muestra indicadores de obligatoriedad o ayuda
                if ($registro_campos["obligatorio"]) $salida.= '<a href="#"   data-toggle="tooltip" data-html="true"  data-placement="auto" title="<b>'.$MULTILANG_TitObligatorio.'</b><br>'.$MULTILANG_DesObligatorio.'"><i class="fa fa-exclamation-triangle icon-orange"></i></a>';
                if ($registro_campos["ayuda_titulo"] != "") $salida.= '<a href="#"   data-toggle="tooltip" data-html="true"  data-placement="auto" title="<b>'.PCO_ReemplazarVariablesPHPEnCadena($registro_campos["ayuda_titulo"],$registro_datos_formulario).'</b><br>'.PCO_ReemplazarVariablesPHPEnCadena($registro_campos["ayuda_texto"],$registro_datos_formulario).'"><i class="fa fa-question-circle"></i></a>';
                $salida.= '</span>';
            }
        //Cierra marco del control de datos
        $salida.= '</div>';




		$salidaNuevo='';
        $salidaNuevo.='
			<table border=0>
				<tr>
					<td valign=top>
						<div id="container" style="margin: 0px auto; width: '.$registro_campos["ancho"].'px; height: '.$registro_campos["alto"].'px; border: 1px solid #acc;">
							<video id="PCO_WebCam_'.$registro_campos["campo"].'" playsinline autoplay style="width: '.$registro_campos["ancho"].'px; height: '.$registro_campos["alto"].'px;"></video>
						    <div id="CANVAS_ErrorMsg'.$registro_campos["campo"].'"></div>
						</div>
					</td>
					<td valign=top>
                        <i id="BotonCaptura_CANVAS_'.$registro_campos["campo"].'" class="fa fa-camera" OnClick="var context = canvas.getContext(\'2d\'); context.drawImage(videoPCO_WebCam_'.$registro_campos["campo"].', 0, 0, '.$registro_campos["ancho"].', '.$registro_campos["alto"].');"></i>
						<br>
						<canvas id="CANVAS_'.$registro_campos["campo"].'" width="'.(($registro_campos["ancho"])).'" height="'.(($registro_campos["alto"])).'" style="width: '.(($registro_campos["ancho"])).'px; height: '.(($registro_campos["alto"])).'px; background-color: #CCC; visibility:visible;"></canvas>
					</td>
				</tr>
			</table>

			<script language="JavaScript">
                \'use strict\';
                
                const videoPCO_WebCam_'.$registro_campos["campo"].' = document.getElementById("PCO_WebCam_'.$registro_campos["campo"].'");
                const canvas = document.getElementById("CANVAS_'.$registro_campos["campo"].'");
                const snap = document.getElementById("snap");
                const errorMsgElement = document.querySelector("errorMsg");
                
                const constraints = {
                  audio: true,
                  video: {
                    width: '.$registro_campos["ancho"].', height: '.$registro_campos["alto"].'
                  }
                };
                
                // Access webcam
                async function init() {
                  try {
                    const stream = await navigator.mediaDevices.getUserMedia(constraints);
                    handleSuccess(stream);
                  } catch (e) {
                    $("#CANVAS_ErrorMsg'.$registro_campos["campo"].'").html("<b>Error Camara</b><br> "+"navigator.getUserMedia error:"+e.toString());
                  }
                }
                
                // Success
                function handleSuccess(stream) {
                  window.stream = stream;
                  videoPCO_WebCam_'.$registro_campos["campo"].'.srcObject = stream;
                }
                
                // Load init
                init();
			</script>';

        $salida = $salidaNuevo;





		return $salida;
	}


########################################################################
########################################################################
/*
	Function: PCO_CargarObjetoBotonComando
	Genera el codigo HTML y CSS correspondiente a un boton de comando sobre un formulario

	Variables de entrada:

		registro_campos - listado de campos sobre el formulario en cuestion
		registro_datos_formulario - Arreglo asociativo con nombres de campo y valores cuando se hacen llamados de registro especificos
		formulario - ID unico del formulario al cual pertenece el objeto

	Salida:

		HTML, CSS y Javascript asociado al objeto publicado dentro del formulario

	Ver tambien:
		<PCO_CargarFormulario>
*/
function PCO_CargarObjetoBotonComando($registro_campos,$registro_datos_formulario,$registro_formulario)
	{
		global $PCO_CampoBusquedaBD,$PCO_ValorBusquedaBD,$IdiomaPredeterminado;
        global $funciones_activacion_datepickers;
		global $MULTILANG_TitValorUnico,$MULTILANG_DesValorUnico,$MULTILANG_TitObligatorio,$MULTILANG_DesObligatorio;
		global $TabIndex_Elemento;
		$salida='';

        //Determina si el estilo del objeto debe ser inline o no
		$cadena_modo_inline='';
        if ($registro_campos["modo_inline"])
            $cadena_modo_inline='display:inline;';

		//Transfiere variables de mensajes de retorno asociadas al boton
		$comando_javascript="";
		if ($registro_campos["retorno_titulo"]!="")
			$comando_javascript="document.".$registro_formulario["id_html"].".PCO_ErrorTitulo.value='".$registro_botones["retorno_titulo"]."'; document.".$registro_formulario["id_html"].".PCO_ErrorDescripcion.value='".$registro_botones["retorno_texto"]."'; document.".$registro_formulario["id_html"].".PCO_ErrorIcono.value='".$registro_botones["retorno_icono"]."'; document.".$registro_formulario["id_html"].".PCO_ErrorEstilo.value='".$registro_botones["retorno_estilo"]."';";

        //Define el tipo de boton de acuerdo al tipo de accion
        switch ($registro_campos["tipo_accion"]) {

            case 'interna_guardar':    $comando_javascript.="PCOJS_ValidarCamposYProcesarFormulario('".$registro_formulario["id_html"]."'); ";     break;
            case 'interna_limpiar':    $comando_javascript.="document.getElementById('".$registro_formulario["id_html"]."').reset();"; break;
            case 'interna_escritorio': $comando_javascript.="document.PCO_FormVerMenu.submit();"; break;
            case 'interna_actualizar': $comando_javascript.="document.".$registro_formulario["id_html"].".PCO_Accion.value='PCO_ActualizarDatosFormulario'; PCOJS_ValidarCamposYProcesarFormulario('".$registro_formulario["id_html"]."'); "; break;
            case 'externa_postcode':   $comando_javascript.="document.".$registro_formulario["id_html"].".PCO_Accion.value='PCO_EjecutarPostAccionForm'; PCOJS_ValidarCamposYProcesarFormulario('".$registro_formulario["id_html"]."'); "; break;
            case 'interna_eliminar':   $comando_javascript.="document.".$registro_formulario["id_html"].".PCO_Accion.value='PCO_EliminarDatosFormulario';document.".$registro_formulario["id_html"].".submit();"; break;
            case 'interna_cargar':     $comando_javascript.="document.".$registro_formulario["id_html"].".PCO_Accion.value='PCO_CargarObjeto';document.".$registro_formulario["id_html"].".PCO_Objeto.value='".$registro_campos["accion_usuario"]."';  PCOJS_SanitizarValoresListaMultiple(); document.".$registro_formulario["id_html"].".submit(); "; break;
            case 'externa_formulario': $comando_javascript.="document.".$registro_formulario["id_html"].".PCO_Accion.value='".$registro_campos["accion_usuario"]."'; PCOJS_SanitizarValoresListaMultiple(); document.".$registro_formulario["id_html"].".submit();"; break;
            case 'externa_javascript': $comando_javascript.=$registro_campos["accion_usuario"];
        }


		//Verifica si el registro de botones presenta algun texto de confirmacion y lo antepone al script
		$cadena_confirmacion_accion_pre="";
		$cadena_confirmacion_accion_pos="";
		if (@$registro_campos["confirmacion_texto"]!="")
			{
				$cadena_confirmacion_accion_pre=" if (confirm('".PCO_ReemplazarVariablesPHPEnCadena($registro_campos["confirmacion_texto"],$registro_datos_formulario)."')) {";
				$cadena_confirmacion_accion_pos=" } else {} ";
			}

        //Genera cadena par el identificador del elemento usando el campo "campo". Normalmente oculto
        $cadena_identificador='';
        if ($registro_campos["campo"]!="")
            $cadena_identificador='id="'.$registro_campos["id_html"].'"';

        //Genera la cadena del enlace
        $cadena_javascript='href="javascript:  '.$cadena_confirmacion_accion_pre.'  '.@$comando_javascript.'  '.$cadena_confirmacion_accion_pos.'  "';

        //Abre el marco del control de datos style="display:inline;"
		$salida.='<div '.$cadena_identificador.' style="'.$cadena_modo_inline.'" class="form-group input-group">';
        // Muestra el campo
		$salida.='<a tabindex="'.$TabIndex_Elemento.'" id="'.$registro_campos["id_html"].'" class="btn '.$registro_campos["personalizacion_tag"].'" '.@$cadena_javascript.'><i class="'.$registro_campos["imagen"].'"></i> '.PCO_ReemplazarVariablesPHPEnCadena($registro_campos["titulo"],$registro_datos_formulario).'</a>';
        //Cierra marco del control de datos
        $salida.= '</div>';

		return $salida;
	}


########################################################################
########################################################################
/*
	Function: PCO_AgregarFuncionesEdicionObjeto
	Genera el codigo HTML y CSS correspondiente los botones y demas elementos para la edicion en caliente de un objeto

	Variables de entrada:

		registro_campos - listado de campos sobre el formulario en cuestion
		tipo_elemento - Tipo de elemento a ser generado

	Salida:

		HTML, CSS y Javascript asociado al objeto publicado dentro del formulario

	Ver tambien:
		<PCO_CargarFormulario>
*/
function PCO_AgregarFuncionesEdicionObjeto($registro_campos,$registro_formulario,$tipo_elemento)
	{
	    global $MULTILANG_FrmEstaSeguro,$MULTILANG_FrmDesplazarObjetos,$MULTILANG_SaltoEdicion,$MULTILANG_Embebido,$MULTILANG_FrmValida,$MULTILANG_FrmPredeterminado,$MULTILANG_FrmCampo,$MULTILANG_MnuPropiedad,$MULTILANG_Detalles,$MULTILANG_Evento,$TablasCore,$MULTILANG_Cerrar,$ArchivoCORE,$MULTILANG_Editar,$MULTILANG_FrmAdvDelCampo,$MULTILANG_Eliminar,$MULTILANG_FrmAumentaPeso,$MULTILANG_FrmDisminuyePeso,$MULTILANG_Anterior,$MULTILANG_Columna,$MULTILANG_Siguiente;
		$salida='';
        if ($tipo_elemento=="ComplementoDisenoElemento")
            {
                $salida='onmouseenter="$(this).css(\'border\', \'1px solid\'); $(this).css(\'border-color\', \'#ff0000\');  //c2a7a7
                $(\'#PCOEditorContenedor_'.$registro_campos["id"].'\').css({\'visibility\':\'visible\'});
                $(\'#PCOEditorContenedor_'.$registro_campos["id"].'\').css({\'display\':\'block\'}); "
                onmouseleave="$(this).css(\'border\', \'0px solid\'); $(\'#PCOEditorContenedor_'.$registro_campos["id"].'\').css({\'visibility\':\'hidden\'}); $(\'#PCOEditorContenedor_'.$registro_campos["id"].'\').css({\'display\':\'none\'});  "';
            }
        if ($tipo_elemento=="ComplementoDisenoMarcoOpciones")
            {
                //Determina estados de activacion o no para controles segun valores actuales del registro
                $EstadoDeshabilitadoMoverIzquierda="";
                $EstadoDeshabilitadoMoverDerecha="";
                $EstadoDeshabilitadoMoverArriba="";
                if($registro_campos["PCOBD_Columna"]-1<=0) $EstadoDeshabilitadoMoverIzquierda="disabled";
                if($registro_campos["PCOBD_Columna"]+1>$registro_formulario["columnas"]) $EstadoDeshabilitadoMoverDerecha="disabled";
                if($registro_campos["PCOBD_Peso"]-1<=0) $EstadoDeshabilitadoMoverArriba="disabled";

                //Busca si el elemento tiene o no eventos para poner un boton de enlace
                $ComplementoBotonEventos="";
                $RegistroConteoEventos=PCO_EjecutarSQL("SELECT COUNT(*) as conteo_eventos FROM ".$TablasCore."evento_objeto WHERE objeto=? ",$registro_campos["id"])->fetch();
                if($RegistroConteoEventos["conteo_eventos"]>0)
                    {
                        //Listado de eventos
                        $ResultadoEventos=PCO_EjecutarSQL("SELECT evento,LENGTH(javascript) as bytes_codigo FROM ".$TablasCore."evento_objeto WHERE objeto=? ",$registro_campos["id"]);
                        $CadenaDetalleEventos="";
                        $ConteoEventos=1;
                        while ($RegistroEventos=$ResultadoEventos->fetch())
                            {
                                $CadenaDetalleEventos.="<li><b>".$RegistroEventos["evento"]."</b> (".$RegistroEventos["bytes_codigo"]." bytes)";
                                $ConteoEventos++;
                            }
                        $ComplementoBotonEventos_DEPRECATED='<br><a class="btn btn-xs btn-default" data-toggle="tooltip" data-html="true"  data-placement="top" title="'.$MULTILANG_Evento.'(s)'.$CadenaDetalleEventos.'" href=\''.$ArchivoCORE.'?PCO_Accion=PCO_EditarFormulario&campo='.$registro_campos["id"].'&formulario='.$registro_campos["formulario"].'&popup_activo=FormularioCampos&pestana_activa_editor=eventos_objeto-tab&nombre_tabla='.$registro_formulario["tabla_datos"].'\'><i class="fa fa-bolt fa-fw texto-blink"></i></a>';
                        $ComplementoBotonEventos='<br><a class="btn btn-xs btn-default" data-toggle="tooltip" data-html="true"  data-placement="top" title="'.$MULTILANG_Evento.'(s)'.$CadenaDetalleEventos.'" href=\'javascript:PCOJS_ActualizarControlFormulario('.$registro_campos["formulario"].','.$registro_campos["id"].',3);\'><i class="fa fa-bolt fa-fw texto-blink"></i></a>';
                    }

                //Si el elemento es un formulario o informe embebido busca ademas el nombre del mismo
                $Complemento_NombreEmbebido="";
                if ($registro_campos["tipo"]=="informe")
                    {
                        $IdentificadorBusqueda=$registro_campos["informe_vinculado"];
                        $RegistroEmbebido=PCO_EjecutarSQL("SELECT id,titulo FROM ".$TablasCore."informe WHERE id=$IdentificadorBusqueda ")->fetch();
                        $Complemento_NombreEmbebido="Inf ID ".$RegistroEmbebido["id"].": <b>".$RegistroEmbebido["titulo"]."</b>";
                    }
                if ($registro_campos["tipo"]=="form_consulta")
                    {
                        $IdentificadorBusqueda=$registro_campos["formulario_vinculado"];
                        $RegistroEmbebido=PCO_EjecutarSQL("SELECT id,titulo FROM ".$TablasCore."formulario WHERE id=$IdentificadorBusqueda ")->fetch();
                        $Complemento_NombreEmbebido="Frm ID ".$RegistroEmbebido["id"].": <b>".$RegistroEmbebido["titulo"]."</b>";
                    }

                //Pone controles
                $salida='<div id="PCOEditorContenedor_'.$registro_campos["id"].'" style="margin:2px; display:none; visibility:hidden; position: absolute; z-index:1000;">
                            <div style="display: inline-block; vertical-align:top;">
                                <a class="btn btn-xs btn-warning" data-toggle="tooltip" data-html="true"  data-placement="top" title="'.$MULTILANG_Editar.'" href=\'javascript:PCOJS_ActualizarControlFormulario('.$registro_campos["formulario"].','.$registro_campos["id"].',1);\'><i class="fa fa-fw fa-pencil"></i></a>
                                <!--DEPRECATED:<a class="btn btn-xs btn-warning" data-toggle="tooltip" data-html="true"  data-placement="top" title="'.$MULTILANG_Editar.'" href=\''.$ArchivoCORE.'?PCO_Accion=PCO_EditarFormulario&campo='.$registro_campos["id"].'&formulario='.$registro_campos["formulario"].'&popup_activo=FormularioCampos&nombre_tabla='.$registro_formulario["tabla_datos"].'\'><i class="fa fa-fw fa-pencil"></i></a>-->
                                '.$ComplementoBotonEventos.'
                                <br><br>
                                <a onclick=\'return confirm("'.$MULTILANG_FrmDesplazarObjetos.'\n\n'.$MULTILANG_FrmEstaSeguro.'");\' class="btn btn-xs btn-success" data-toggle="tooltip" data-html="true"  data-placement="top" title="'.$MULTILANG_FrmDesplazarObjetos.'" href=\''.$ArchivoCORE.'?PCO_Accion=PCO_DesplazarObjetosForm&idObjetoForm='.$registro_campos["id"].'&accion_retorno=PCO_EditarFormulario&nombre_tabla='.$registro_formulario["tabla_datos"].'\'><i class="fa fa-fw fa-step-forward fa-rotate-90"></i></a>                                
                            </div>
                            <div style="display: inline-block;">
                                <a class="btn btn-xs btn-info '.$EstadoDeshabilitadoMoverIzquierda.'" data-toggle="tooltip" data-html="true"  data-placement="top" title="'.$MULTILANG_Anterior.' '.$MULTILANG_Columna.'" href=\''.$ArchivoCORE.'?PCO_Accion=cambiar_estado_campo&id='.$registro_campos["id"].'&tabla=formulario_objeto&campo=PCOBD_Columna&formulario='.$registro_campos["formulario"].'&accion_retorno=PCO_EditarFormulario&valor='.($registro_campos["PCOBD_Columna"]-1).'&nombre_tabla='.$registro_formulario["tabla_datos"].'\'><i class="fa fa-arrow-left"></i></a>
                            </div>
                            <div style="display: inline-block;">
                                <a class="btn btn-xs btn-info '.$EstadoDeshabilitadoMoverArriba.'" data-toggle="tooltip" data-html="true"  data-placement="top" title="'.$MULTILANG_FrmDisminuyePeso.' a '.($registro_campos["PCOBD_Peso"]-1).'" href=\''.$ArchivoCORE.'?PCO_Accion=cambiar_estado_campo&id='.$registro_campos["id"].'&tabla=formulario_objeto&campo=PCOBD_Peso&formulario='.$registro_campos["formulario"].'&accion_retorno=PCO_EditarFormulario&valor='.($registro_campos["PCOBD_Peso"]-1).'&nombre_tabla='.$registro_formulario["tabla_datos"].'\'><i class="fa fa-arrow-up"></i></a>
                                <br>
                                <a class="btn btn-xs btn-info" data-toggle="tooltip" data-html="true"  data-placement="top" title="'.$MULTILANG_FrmAumentaPeso.' a '.($registro_campos["PCOBD_Peso"]+1).'" href=\''.$ArchivoCORE.'?PCO_Accion=cambiar_estado_campo&id='.$registro_campos["id"].'&tabla=formulario_objeto&campo=PCOBD_Peso&formulario='.$registro_campos["formulario"].'&accion_retorno=PCO_EditarFormulario&valor='.($registro_campos["PCOBD_Peso"]+1).'&nombre_tabla='.$registro_formulario["tabla_datos"].'\'><i class="fa fa-arrow-down"></i></a>
                            </div>
                            <div style="display: inline-block;">
                                <a class="btn btn-xs btn-info '.$EstadoDeshabilitadoMoverDerecha.'" data-toggle="tooltip" data-html="true"  data-placement="top" title="'.$MULTILANG_Siguiente.' '.$MULTILANG_Columna.'" href=\''.$ArchivoCORE.'?PCO_Accion=cambiar_estado_campo&id='.$registro_campos["id"].'&tabla=formulario_objeto&campo=PCOBD_Columna&formulario='.$registro_campos["formulario"].'&accion_retorno=PCO_EditarFormulario&valor='.($registro_campos["PCOBD_Columna"]+1).'&nombre_tabla='.$registro_formulario["tabla_datos"].'\'><i class="fa fa-arrow-right"></i></a>
                            </div>
                            
                            <div style="display: inline-block; vertical-align:top;">
                                <a class="btn btn-xs" data-toggle="tooltip" data-html="true"  data-placement="top" title="<div align=left><font color=yellow>'.$MULTILANG_Detalles.' <i>('.$MULTILANG_MnuPropiedad.')</i></font><br>ID HTML: <b>'.$registro_campos["id_html"].'</b><br>'.$MULTILANG_FrmCampo.': <b>'.$registro_campos["campo"].'</b><br>'.$MULTILANG_FrmPredeterminado.': <b>'.$registro_campos["valor_predeterminado"].'</b><br>'.$MULTILANG_FrmValida.': <b>'.$registro_campos["validacion_datos"].'</b> Extra: <b>'.$registro_campos["validacion_extras"].'</b></div>" href=\'#\'><i class="fa fa-info-circle"></i></a>';
                            //Si el objeto es un formulario o informe embebido agrega enlace para su edicion directa
                            if ($registro_campos["tipo"]=="form_consulta")
                                $salida.='<br><a onclick=\'return confirm("'.$MULTILANG_SaltoEdicion.'");\' href=\''.$ArchivoCORE.'?PCO_Accion=PCO_EditarFormulario&formulario='.$registro_campos["formulario_vinculado"].'&popup_activo=\' class="btn btn-primary btn-xs"  data-toggle="tooltip" data-html="true"  data-placement="top" title="'.$MULTILANG_Editar.' '.$MULTILANG_Embebido.'<br>'.$Complemento_NombreEmbebido.'"><i class="fa fa fa-object-ungroup"></i></a>';
                            if ($registro_campos["tipo"]=="informe")
                                $salida.='<br><a onclick=\'return confirm("'.$MULTILANG_SaltoEdicion.'");\' href=\''.$ArchivoCORE.'?PCO_Accion=PCO_EditarInforme&informe='.$registro_campos["informe_vinculado"].'&popup_activo=\' class="btn btn-primary btn-xs"  data-toggle="tooltip" data-html="true"  data-placement="top" title="'.$MULTILANG_Editar.' '.$MULTILANG_Embebido.'<br>'.$Complemento_NombreEmbebido.'"><i class="fa fa fa-object-ungroup"></i></a>';
                $salida.='</div>
                            <div style="display: inline-block;">
                                <a class="btn btn-xs " data-toggle="tooltip" data-html="true"  data-placement="top" title="'.$MULTILANG_Cerrar.'" href="javascript:OcultarOpcionesEdicion(this,\'#PCOEditorContenedor_'.$registro_campos["id"].'\');"><i class="fa fa-times"></i></a>
                                <br>
                                <a onclick=\'return confirm("'.$MULTILANG_FrmAdvDelCampo.'");\' href=\''.$ArchivoCORE.'?PCO_Accion=PCO_EliminarCampoFormulario&campo='.$registro_campos["id"].'&formulario='.$registro_campos["formulario"].'&nombre_tabla='.$registro_formulario["tabla_datos"].'\' class="btn btn-danger btn-xs"  data-toggle="tooltip" data-html="true"  data-placement="top" title="'.$MULTILANG_Eliminar.'"><i class="fa fa-trash"></i></a>
                            </div>
                            </div>';
            }
		return $salida;
	}


########################################################################
########################################################################
/*
	Function: PCO_CargarFormulario
	Genera el codigo HTML correspondiente a un formulario de la aplicacion y hace los llamados necesarios para la diagramacion por pantalla de los diferentes objetos que lo componen.

	Variables de entrada:

		formulario - ID unico del formulario que se desea cargar
		en_ventana - Opcional, determina si el formulario es cargado en una ventana o directamente sobre el escritorio
		PCO_CampoBusquedaBD - Opcional, indica el campo sobre el cual se deben realizar busquedas para el cargue automatico de campos del formulario desde la base de datos
		PCO_ValorBusquedaBD - Opcional, indica el valor que sera buscado sobre el PCO_CampoBusquedaBD para encontrar los valores de cada objeto en el formulario
		anular_form - Opcional, indica si las etiquetas del formulario HTML deben ser eliminadas y agregar los campos crudos dentro del form
		modo_diseno_formulario - Opcional, indica si se esta disenando el formulario para presentar algunos controles extra

	(start code)
		SELECT * FROM ".$TablasCore."formulario WHERE id='$formulario'
		SELECT id,PCOBD_Peso,visible FROM ".$TablasCore."formulario_objeto WHERE formulario='$formulario' AND fila_unica='1' AND visible=1 UNION SELECT 0,$limite_superior,0 ORDER BY PCOBD_Peso
		SELECT * FROM ".$TablasCore."formulario_objeto WHERE formulario='$formulario' AND columna='$cl' AND visible=1 AND PCOBD_Peso >'$limite_inferior' AND PCOBD_Peso <='$limite_superior' ORDER BY PCOBD_Peso
		Por cada registro
			Llamar creacion de objeto correspondiente
		SELECT * FROM ".$TablasCore."formulario_objeto WHERE formulario='$formulario' AND id='$ultimo_id'
		SELECT * FROM ".$TablasCore."formulario_boton WHERE formulario='$formulario' AND visible=1 ORDER BY peso
	(end)

	Salida:

		HTML, CSS y Javascript asociado al formulario

	Ver tambien:
		<PCO_CargarInforme>
*/
    //Funcion para compatibilidad hacia atras.  Desaparecera en la version 18.9
    function cargar_formulario($formulario,$en_ventana=1,$PCO_CampoBusquedaBD="",$PCO_ValorBusquedaBD="",$anular_form=0,$modo_diseno_formulario=0)
    { echo "ERROR: Llamado a funcion obsoleta del framework cargar_formulario().  En su lugar utilice PCO_CargarFormulario() "; }
function PCO_CargarFormulario($formulario,$en_ventana=1,$PCO_CampoBusquedaBD="",$PCO_ValorBusquedaBD="",$anular_form=0,$modo_diseno_formulario=0,$ComplementoPestanas="")
  {
        global $ModoDesarrolladorPractico,$PCO_RegistroDatosFormulario;
        global $ConexionPDO,$ArchivoCORE,$TablasCore,$LlaveDePaso;
        global $PCO_InformeFiltro,$PCO_FuncionesJSInternasFORM;
		global $_SeparadorCampos_;
		// Carga variables de definicion de tablas
		global $ListaCamposSinID_formulario,$ListaCamposSinID_formulario_objeto,$ListaCamposSinID_formulario_boton,$ListaCamposSinID_menu;
		global $MULTILANG_Formularios,$MULTILANG_Editar,$MULTILANG_Elementos,$MULTILANG_Agregar,$MULTILANG_Configuracion,$MULTILANG_AvisoSistema,$MULTILANG_ErrFrmObligatorio,$MULTILANG_ErrorTiempoEjecucion,$MULTILANG_ObjetoNoExiste,$MULTILANG_ContacteAdmin,$MULTILANG_Formularios,$MULTILANG_VistaImpresion,$MULTILANG_InfRetornoFormFiltrado,$MULTILANG_FrmMsj1,$MULTILANG_Documentar;
        global $PCO_InformesListaColumnasDT,$PCO_InformesRecuperacionAJAX,$PCO_InformesIdCache,$PCO_InformesDataTable,$PCO_InformesDataTablePaginaciones,$PCO_InformesDataTableTotales,$PCO_InformesDataTableFormatoTotales,$PCO_InformesDataTableExrpotaCLP,$PCO_InformesDataTableExrpotaCSV,$PCO_InformesDataTableExrpotaXLS,$PCO_InformesDataTableExrpotaPDF,$PCO_InformesDataTableDefineCOLS,$PCO_InformesDataTable_pane_activado,$PCO_InformesDataTable_pane_cascada,$PCO_InformesDataTable_pane_colapsado,$PCO_InformesDataTable_pane_columnas,$PCO_InformesDataTable_pane_subtotalesrelativos,$PCO_InformesDataTable_pane_conteos,$PCO_InformesDataTable_pane_controles,$PCO_InformesDataTable_pane_control_colapsar,$PCO_InformesDataTable_pane_control_ordenar;
        global $POSTForm_ListaCamposObligatorios,$POSTForm_ListaTitulosObligatorios;
		global $PCO_BarraHerramientasFormulario; 
		global $TabIndex_Elemento;

		// Busca datos del formulario
		$registro_formulario=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_formulario." FROM ".$TablasCore."formulario WHERE id=?","$formulario")->fetch();

        //Determina si el usuario es un disenador de aplicacion para mostrar el ID de objeto a manera informativa y un boton de salto a edicion
        $BotonSaltoEdicion='
                    <a class="btn btn-default btn-xs" href="index.php?PCO_Accion=PCO_EditarFormulario&popup_activo=&formulario='.$formulario.'" id="PCO_BotonEdicionFormulario">
                        <div><i class="fa fa-pencil-square"></i> '.$MULTILANG_Editar.' '.$MULTILANG_Formularios.' <i>[ID='.$formulario.']</i></div>
                    </a>';
		if (PCO_EsAdministrador($_SESSION['PCOSESS_LoginUsuario']) && ($formulario>=0 || $ModoDesarrolladorPractico==-10000) )
		    $ComplementoIdObjetoEnTitulo="  $BotonSaltoEdicion";

		echo '
		<script type="text/javascript">
			function AgregarElemento(columna,fila,elemento)
				{
					//carga dinamicamente objetos html a marcos
					var capa = document.getElementById(ubicacion);
					var zona = document.createElement("po");
					zona.innerHTML = elemento;
					capa.appendChild(zona);
				}

			function ImprimirMarco(nombre)
				{
				  var marco_contenidos = document.getElementById(nombre);
				  var ventana_impresion = window.open(" ", "PopUpImpresion");

				  //Agrega estilos basicos
                    //ventana_impresion.document.write( \'<link rel="stylesheet" type="text/css" href="general.css">\' );

				  //Agrega titulo del formulario
					//ventana_impresion.document.write( \'<div align=CENTER><b>'.$registro_formulario["titulo"].'</b></div><hr>\' );

				  //Agrega el concenito del DIV al documento
					ventana_impresion.document.write( marco_contenidos.innerHTML );
					ventana_impresion.document.close();

				  //Abre ventana de impresion
					ventana_impresion.print( );

				  //Cierra ventana de impresion
					ventana_impresion.close();
				}

			function OcultarOpcionesEdicion(ObjetoEnlazado,NombreMarcoOpciones)
			    {
				    BasuritaVar1=$(ObjetoEnlazado).css(\'border\', \'0px solid\');
				    BasuritaVar2=$(NombreMarcoOpciones).css({\'visibility\':\'hidden\'});
				    BasuritaVar3=$(NombreMarcoOpciones).css({\'display\':\'none\'});
			    }
		</script>
		<!--<input type=button onclick=\'AgregarElemento("1","1","hello world");\'>-->';

        if ($modo_diseno_formulario==1)
            {
        		echo '<script type="text/javascript">
                        function PCOJS_LlamadoRemotoEditarFormulario()
            				{
            					document.getElementById("PCO_BotonEdicionFormulario").click();
            				}
				
                        function PCOJS_ActualizarControlFormulario(idformulario,idcontrol,pestana_activa){
                            //Salta a edicion de control
                            var URLPopUp="index.php?PCO_Accion=PCO_CargarObjeto&PCO_Objeto=frm:-36:0:id:"+idcontrol+"&Presentar_FullScreen=1&Precarga_EstilosBS=1&formulario="+idformulario+"&pestana_activa_apertura="+pestana_activa+"&PCO_TipoControlDirecto=";
                            PCOJS_MostrarMensaje("'.$MULTILANG_FrmMsj1.'","Cargando...","modal-wide oculto_impresion");
                            $("#PCO_Modal_MensajeCuerpo").html(\'<iframe id="IFrameEmbebido" scrolling="yes" style="margin:10px; border:0px;" height=500 width=100% src="\'+URLPopUp+\'"></iframe>\');
                            $("#PCO_Modal_MensajeBotones").html(\'<button id="boton_filtrar" type="button" class="btn btn-outline btn-info" data-dismiss="modal" onclick="PCOJS_LlamadoRemotoEditarFormulario();" >Cerrar</button></a>\');
                        }
        		    </script>';
            }

        //Funciones asociadas a documentacion
		echo '<script type="text/javascript">
                function PCOJS_DocumentacionFormulario(idformulario,IdInforme){
                    //Presenta informe con documentacion del formulario o posibilidad de crear nueva documentacion
                    
                    //Define los campos segun el informe a utilizar
                    lista_campos_segun_informe="titulo as Titulo,formato as Formato,visibilidad as Visible";
                    if (IdInforme==-56) lista_campos_segun_informe="titulo as Titulo,formato as Formato";
                    
                    //Define ancho de ventana segun tipo de informe/usuario
                    estilo_ancho_ventana="modal-wide ";
                    if (IdInforme==-56) estilo_ancho_ventana="";

                    var URLPopUp="index.php?PCO_Accion=PCO_CargarObjeto&PCO_Objeto=inf:"+IdInforme+":0&Presentar_FullScreen=1&Precarga_EstilosBS=1&origen=Formulario&detalle_origen="+idformulario+"&lista_campos_documentacion="+lista_campos_segun_informe;
                    PCOJS_MostrarMensaje("'.$MULTILANG_Documentar.'","Cargando...",estilo_ancho_ventana+" oculto_impresion");
                    $("#PCO_Modal_MensajeCuerpo").html(\'<iframe id="IFrameEmbebido" scrolling="yes" style="margin:10px; border:0px;" height=450 width=100% src="\'+URLPopUp+\'"></iframe>\');
                    $("#PCO_Modal_MensajeBotones").html(\'<button id="boton_filtrar" type="button" class="btn btn-outline btn-info" data-dismiss="modal" onclick="CargarFormulario();" >Cerrar</button></a>\');
                }
                
                //TODO: Pasar a JS general para permitir llamado desde otros apartados, ej, Kanban
                //IdDocumentacion contiene dos datos, IdRegistro|TipoDocumentacion
                //TipoDocCreacion contiene el formato de documentacion (redundante con parte del primer parametro pero usado solo en creacion)
                function PCOJS_EditarDocumentacion(IdDocumentacion,TipoDocCreacion)
                    {
                        IdDocumentacion=IdDocumentacion+"";
                        PartesIdDocumentacion=IdDocumentacion.split("|");
                        //Determina tipo de documentacion para establecer el tipo de llamado.
                        
                        IdRegistro=PartesIdDocumentacion[0];
                        TipoRegistro=PartesIdDocumentacion[1];
                        if (IdRegistro!="" && IdRegistro!="0")
                            {
                                //Determina si va a editar un contenido enriquecido o un diagrama
                                if (TipoRegistro=="Enriquecido" || TipoDocCreacion=="Enriquecido")
                                    var URLPopUp="index.php?PCO_Accion=PCO_CargarObjeto&PCO_Objeto=frm:-43:0:id:"+IdRegistro+"&Presentar_FullScreen=1&Precarga_EstilosBS=1&origen=Formulario&formato="+TipoRegistro;
                                if (TipoRegistro=="Diagrama")
                                    var URLPopUp="inc/mxgraph/javascript/scripts/grapheditor/www/index.php?PCO_CampoOrigen=documentacion&PCO_TablaOrigen=core_documentacion&PCO_CampoLlave=id&PCO_ValorLlave="+IdRegistro;
                            }
                        else
                            var URLPopUp="index.php?PCO_Accion=PCO_CargarObjeto&PCO_Objeto=frm:-43:0&Presentar_FullScreen=1&Precarga_EstilosBS=1&origen_creacion=Formulario&detalle_origen_creacion='.$registro_formulario["id"].'&formato_creacion="+TipoDocCreacion;
                        
                        //Carga el editor de documentacion
                        PCO_VentanaPopup(URLPopUp,"Docs"+IdRegistro,"toolbar=no, location=no, directories=0, directories=no, status=no, location=no, menubar=no ,scrollbars=no, resizable=yes, fullscreen=no, titlebar=no, width=900, height=700");
                    }
                function PCOJS_VisualizarDocumentacion(IdDocumentacion)
                    {
                        alert("Sin acceso a elemento: "+IdDocumentacion);
                    }
		    </script>';


		//Si no encuentra formulario presenta error
		if ($registro_formulario["id"]=="")	PCO_Mensaje($MULTILANG_ErrorTiempoEjecucion,$MULTILANG_ObjetoNoExiste." ".$MULTILANG_ContacteAdmin."<br>(".$MULTILANG_Formularios." $formulario)", '', 'fa fa-times fa-5x icon-red texto-blink', 'alert alert-danger alert-dismissible');

		// En caso de recibir un campo base y valor base se hace la busqueda para recuperar la informacion
		if ($PCO_CampoBusquedaBD!="" && $PCO_ValorBusquedaBD!="")
			{
				$consulta_datos_formulario = $ConexionPDO->prepare("SELECT * FROM ".$registro_formulario["tabla_datos"]." WHERE $PCO_CampoBusquedaBD='$PCO_ValorBusquedaBD'");
				$consulta_datos_formulario->execute();
				$registro_datos_formulario = $consulta_datos_formulario->fetch();
				$PCO_RegistroDatosFormulario=$registro_datos_formulario;
			}
		
		//Carga cualquier script PRE para el formulario
		if ($registro_formulario["pre_script"]!="" && $modo_diseno_formulario==0)
		    {
		        //Evalua si el codigo ya inicia con <?php y sino lo agrega
		        $ComplementoInicioScript="";
		        if (substr(trim($registro_formulario["pre_script"]),0,5)!='<?php')
		            $ComplementoInicioScript="<?php\n";
		        PCO_EvaluarCodigo($ComplementoInicioScript.$registro_formulario["pre_script"],1,"Detalles: PRE-Code Form ID=".$formulario);
		    }
		    
		
		// Define la barra de herramientas mini superior (en barra de titulo)
		@$PCO_BarraHerramientasFormulario.='
				<a  href="#" data-toggle="tooltip" data-html="true"  title="'.$MULTILANG_VistaImpresion.'" name="">
					<i class="fa fa-print" OnClick="ImprimirMarco(\'MARCO_IMPRESION\');"></i>
				</a>';

		// Establece color de fondo para el form
		$color_fondo="#f2f2f2";

		//Determina si esta en modo diseno para agregar algunos elementos extra al titulo del form
        if ($modo_diseno_formulario)
            {
                //Genera llaves de apertura unicos para los archivos de pcoder 
                //FORMA 1: Enlaces estandar (Modo de emergencia o depuracion de PCoder)
                // $PCO_EnlaceScriptPRE ="javascript:PCO_VentanaPopup('index.php?PCO_Accion=PCO_CargarObjeto&PCO_Objeto=frm:-33:0&Presentar_FullScreen=1&Precarga_EstilosBS=1&Origen_Archivo=B&Tabla_Archivo=core_formulario&Campo_Archivo=pre_script&PCODER_extension=php&PCODER_ModoEditor=PHP&PCODER_TipoMenu=Iconos&PCODER_EstadoSimple=1&Llave_Registro={$formulario}&PCODER_Titulo=Script_PRE_Formulario_{$formulario}_(PHP)','PcoderNG','toolbar=no, location=no, directories=0, directories=no, status=no, location=no, menubar=no ,scrollbars=no, resizable=yes, fullscreen=no, titlebar=no, width=800, height=600');";  //ANTES  width='+screen.width+', height='+screen.height);
                // $PCO_EnlaceScriptPOST="javascript:PCO_VentanaPopup('index.php?PCO_Accion=PCO_CargarObjeto&PCO_Objeto=frm:-33:0&Presentar_FullScreen=1&Precarga_EstilosBS=1&Origen_Archivo=B&Tabla_Archivo=core_formulario&Campo_Archivo=post_script&PCODER_extension=php&PCODER_ModoEditor=PHP&PCODER_TipoMenu=Iconos&PCODER_EstadoSimple=1&Llave_Registro={$formulario}&PCODER_Titulo=Script_POST_Formulario_{$formulario}_(PHP)','PcoderNG','toolbar=no, location=no, directories=0, directories=no, status=no, location=no, menubar=no ,scrollbars=no, resizable=yes, fullscreen=no, titlebar=no, width=800, height=600');";  //ANTES  width='+screen.width+', height='+screen.height);
                // $PCO_EnlaceScriptJS  ="javascript:PCO_VentanaPopup('index.php?PCO_Accion=PCO_CargarObjeto&PCO_Objeto=frm:-33:0&Presentar_FullScreen=1&Precarga_EstilosBS=1&Origen_Archivo=B&Tabla_Archivo=core_formulario&Campo_Archivo=javascript&PCODER_extension=js&PCODER_ModoEditor=JavaScript&PCODER_TipoMenu=Iconos&PCODER_EstadoSimple=1&Llave_Registro={$formulario}&PCODER_Titulo=Script_JS_Formulario_{$formulario}_(JS)' ,'PcoderNG','toolbar=no, location=no, directories=0, directories=no, status=no, location=no, menubar=no ,scrollbars=no, resizable=yes, fullscreen=no, titlebar=no, width=800, height=600');";  //ANTES  width='+screen.width+', height='+screen.height);
                //FORMA 2: Con funcion interna de apertura - Sobreescribe FORMA 1 - Comentar para pasar a modo de emergencia
                $TituloPCoder_COMPLEMENTO=" - <font color=white>".$registro_formulario["titulo"]."</font> ";
                $LlaveParcial_FirmaSistema=substr($LlaveDePaso,-3);
                $PCO_EnlaceScriptPRE ="javascript:PCOJS_CargarArchivoPCoderBD('{$LlaveParcial_FirmaSistema}','','','','No','B','core_formulario','pre_script', '{$formulario}','php','PHP'       ,'Iconos','1','<font color=white>Script_PRE</font> Formulario_{$formulario}_(PHP){$TituloPCoder_COMPLEMENTO}');";
                $PCO_EnlaceScriptPOST="javascript:PCOJS_CargarArchivoPCoderBD('{$LlaveParcial_FirmaSistema}','','','','No','B','core_formulario','post_script','{$formulario}','php','PHP'       ,'Iconos','1','<font color=white>Script_POST</font> Formulario_{$formulario}_(PHP){$TituloPCoder_COMPLEMENTO}');";
                $PCO_EnlaceScriptJS  ="javascript:PCOJS_CargarArchivoPCoderBD('{$LlaveParcial_FirmaSistema}','','','','No','B','core_formulario','javascript' ,'{$formulario}','js' ,'JavaScript','Iconos','1','<font color=white>Script_JS</font> Formulario_{$formulario}_(PHP){$TituloPCoder_COMPLEMENTO}');";
                $PCO_EnlaceScriptDOCS  ="javascript:LMQTP=PCOJS_DocumentacionFormulario('{$formulario}',-55);";

				$ComplementoTituloFormulario='
				<div class="pull-right">
                    <a class="btn btn-default btn-xs" data-toggle="modal" href="'.$PCO_EnlaceScriptDOCS.'">
                        <div><i class="fa fa-file-word-o"></i> Docs</div>
                    </a>
                    <a class="btn btn-primary btn-xs" data-toggle="modal" title="'.$MULTILANG_FrmAdvScriptForm.'" href="'.$PCO_EnlaceScriptPRE.'">
                        <div><i class="fa fa-file-code-o"></i> PRE</div>
                    </a>
                    <a class="btn btn-info btn-xs" data-toggle="modal" title="'.$MULTILANG_FrmAdvScriptForm.'" href="'.$PCO_EnlaceScriptPOST.'">
                        <div><i class="fa fa-file-code-o"></i> POST</div>
                    </a>
                    <a class="btn btn-warning btn-xs" data-toggle="modal" title="'.$MULTILANG_FrmAdvScriptForm.'" href="'.$PCO_EnlaceScriptJS.'">
                        <div><i class="fa fa-file-code-o"></i> JS</div>
                    </a>
                    &nbsp;
					<a class="btn btn-default btn-xs" href="javascript:PCOJS_AlternarBarraFlotanteIzquierda();">
						<div><i class="fa fa-cog fa-spin fa-fw"></i> '.$MULTILANG_Configuracion.' / '.$MULTILANG_Agregar.' '.$MULTILANG_Elementos.'</div>
					</a>
				</div>';
            }
        else
            {
                //Determina si el formulario tiene documentacion asociada y muestra el boton
                $TotalDocumentacionElemento=PCO_EjecutarSQL("SELECT COUNT(*) FROM core_documentacion WHERE origen='Formulario' AND detalle_origen='{$formulario}' AND visibilidad='Usuario' ")->fetchColumn();
                if ($TotalDocumentacionElemento!="0")
                    {
                        $PCO_EnlaceScriptDOCS  ="javascript:LMQTP=PCOJS_DocumentacionFormulario('{$formulario}',-56);";
        				$ComplementoTituloFormulario='
        				<div class="pull-right">
                            <a class="btn btn-info btn-xs" data-toggle="modal" href="'.$PCO_EnlaceScriptDOCS.'">
                                <div><i class="fa fa-file-word-o"></i> Docs</div>
                            </a>
        				</div>';                        
                    }
            }

		// Crea ventana si aplica para el form
		if ($en_ventana) PCO_AbrirVentana(PCO_ReemplazarVariablesPHPEnCadena($registro_formulario["titulo"]).$ComplementoTituloFormulario.$ComplementoIdObjetoEnTitulo,$registro_formulario["estilo_ventana"],'',$PCO_BarraHerramientasFormulario);

        //Busca las posibles opciones de menu agregadas al formulario
        $RegistroCantidadMenues=PCO_EjecutarSQL("SELECT COUNT(*) as CantidadMenues FROM ".$TablasCore."menu WHERE formulario_vinculado='$formulario' AND padre=0")->fetch();
        if ($RegistroCantidadMenues["CantidadMenues"]>0)
            {
        		echo '<!-- Boton expansible para menu en dispositivos moviles -->
        			<nav class="navbar navbar-default" style="min-height:30px !important; margin:0px !important; padding:0px !important;"> <!--  navbar-xs navbar-fixed-top  navbar-inverse navbar-fixed-bottom navbar-static-top  -->
    					<div class="navbar-header">
    						<button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#MENU_FORMULARIO_'.$formulario.'" aria-expanded="false">
    						    <i class="fa fa-bars"></i>
    						</button>
    					</div>
            		    <div class="collapse navbar-collapse" id="MENU_FORMULARIO_'.$formulario.'">';
                            $resultado=PCO_EjecutarSQL("SELECT ".$TablasCore."menu.id as id,$ListaCamposSinID_menu FROM ".$TablasCore."menu WHERE formulario_vinculado='$formulario' AND padre=0 ORDER BY peso");
                            $ConteoOpciones=1;
                            while($registro = $resultado->fetch())
                                {
                                    echo '<div style="display:inline !important;" id="MENU_FORMULARIO_OPCION_'.$ConteoOpciones.'">';
                                    PCO_ImprimirOpcionMenu($registro,'formulario');
                                    echo '</div>';
                                    $ConteoOpciones++;
                                }
        		echo '  </div>
        		    </nav>';
            }

		// Muestra ayuda en caso de tenerla
		$imagen_ayuda='fa fa-info-circle fa-5x texto-azul';
		if ($registro_formulario["ayuda_titulo"]!="" || $registro_formulario["ayuda_texto"]!="")
			PCO_Mensaje(PCO_ReemplazarVariablesPHPEnCadena($registro_formulario["ayuda_titulo"]),PCO_ReemplazarVariablesPHPEnCadena($registro_formulario["ayuda_texto"]),'100%',$imagen_ayuda,'alert alert-info alert-dismissible');

		//Inicia el formulario de datos
		echo '<div id="PCO_MarcoImpresion'.$formulario.'">';
		//Si se quiere anular el formulario y su accion cuando se trata de un sub-formulario de consulta
		if (!$anular_form)
			echo'<form id="'.$registro_formulario["id_html"].'" name="'.$registro_formulario["id_html"].'" action="'.$ArchivoCORE.'" method="POST" enctype="multipart/form-data" style="display:inline; height: 0px; border-width: 0px; width: 0px; padding: 0; margin: 0;">
				<input type="Hidden" name="formulario" value="'.$formulario.'">
				<input type="Hidden" name="id_registro_datos" value="'.@$registro_datos_formulario["id"].'">
				<input type="Hidden" name="PCO_FormularioActivo" value="'.$formulario.'">
				<input type="Hidden" name="PCO_Accion" value="PCO_GuardarDatosFormulario">
				<input type="Hidden" name="PCO_ErrorIcono" value="'.@$PCO_ErrorIcono.'">
				<input type="Hidden" name="PCO_ErrorEstilo" value="'.@$PCO_ErrorEstilo.'">
				<input type="Hidden" name="PCO_ErrorTitulo" value="'.@PCO_ReemplazarVariablesPHPEnCadena($PCO_ErrorTitulo).'">
				<input type="Hidden" name="PCO_ErrorDescripcion" value="'.@PCO_ReemplazarVariablesPHPEnCadena($PCO_ErrorDescripcion).'">
                <input type="Hidden" name="Presentar_FullScreen" value="'.@$Presentar_FullScreen.'">
                <input type="Hidden" name="Precarga_EstilosBS" value="'.@$Precarga_EstilosBS.'">
                <input type="Hidden" name="PCO_Objeto" value="">  <!--Requerido si se va a transferir el control a un objeto FRM o INF-->
                <input type="Hidden" name="objeto" value="">      <!--COMPATIBILIDAD: Requerido si se va a transferir el control a un objeto FRM o INF-->
				';

        // Inicio de la generacion de encabezados pestanas
        //Cuenta las pestanas segun los objetos del form y ademas mira si es solo una con valor vacio (sin pestanas)
        $consulta_conteo_pestanas=      PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_formulario_objeto." FROM ".$TablasCore."formulario_objeto WHERE formulario=? AND visible=1 GROUP BY pestana_objeto ORDER BY pestana_objeto","$formulario");
        $conteo_pestanas=0;
        $conteo_pestanas_ocultas=0;
        while($registro_conteo_pestanas = @$consulta_conteo_pestanas->fetch())
            {
                $titulo_pestana_formulario=$registro_conteo_pestanas["pestana_objeto"];
                if ($titulo_pestana_formulario!="PCO_NoVisible" || (PCO_EsAdministrador($_SESSION['PCOSESS_LoginUsuario']) && $formulario>=0)  ||  (PCO_EsAdministrador($_SESSION['PCOSESS_LoginUsuario']) && $formulario<0 && $modo_diseno_formulario==1)   )
                    {
                        $conteo_pestanas++;
                        $ultimo_nombre_pestanas=$registro_conteo_pestanas["pestana_objeto"];
                    }
                //Lleva el conteo de las ocultas en caso que las deba crear aunque solo exista una visible pero se requieran los tab-pane para separar la oculta
                if ($titulo_pestana_formulario=="PCO_NoVisible")
                    $conteo_pestanas_ocultas=1;
            }
        //Presenta barra de navegacion de pestanas si se encuentra al menos una
        if ($conteo_pestanas>0 && ($ultimo_nombre_pestanas!=""))
            {
				//Determina el estilo de las pestanas
				$CadenaEstiloPestanas=""; //Estilo por defecto para aplicar a las pestanas
				if($registro_formulario["estilo_pestanas"]=="")
					$CadenaEstiloPestanas="visibility:hidden; height:0px;"; //Oculta las pestanas

                $consulta_formulario_pestana=   PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_formulario_objeto." FROM ".$TablasCore."formulario_objeto WHERE formulario=? AND visible=1 GROUP BY pestana_objeto ORDER BY pestana_objeto","$formulario");
                echo '<ul class="nav '.$registro_formulario["estilo_pestanas"].' nav-justified oculto_impresion" style="'.$CadenaEstiloPestanas.'">';
                $estado_activa_primera_pestana=' class="active" ';
                $pestana_activa=1;
                while($registro_formulario_pestana = @$consulta_formulario_pestana->fetch())
                    {
                        $titulo_pestana_formulario=PCO_ReemplazarVariablesPHPEnCadena($registro_formulario_pestana["pestana_objeto"]);
                        if ($titulo_pestana_formulario=="") $titulo_pestana_formulario="<i class='fa fa-stack-overflow'></i>";
                        //Presenta la pestana solamente si no es una oculta
                        if ($titulo_pestana_formulario!="PCO_NoVisible" || (PCO_EsAdministrador($_SESSION['PCOSESS_LoginUsuario']) && $formulario>=0)   ||  (PCO_EsAdministrador($_SESSION['PCOSESS_LoginUsuario']) && $formulario<0 && $modo_diseno_formulario==1)   )
                            echo '<li '.$estado_activa_primera_pestana.'  ><a  href="#PCO_Pestana'.$ComplementoPestanas.'Formulario_'.$pestana_activa.'" data-toggle="tab" id="PCO_LinkPestanaFormulario_'.$pestana_activa.'">'.$titulo_pestana_formulario.'</a></li>';
                        //Limpia para las siguientes pestanas
                        $estado_activa_primera_pestana='';
                        $pestana_activa++;
                    }
                echo '</ul>';
            }
        // Fin de la generacion de encabezados pestanas

        //Genera las pestanas con su contenido
        $UltimaClaseColumna="";
        if ($conteo_pestanas>0)
            {
                $consulta_formulario_pestana=   PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_formulario_objeto." FROM ".$TablasCore."formulario_objeto WHERE formulario=? AND visible=1 GROUP BY pestana_objeto ORDER BY pestana_objeto","$formulario");
                $estado_activa_primera_pestana='in active';
                $pestana_activa=1;

                //Inicio de los tab-content
                echo '<div class="tab-content" >';
                while($registro_formulario_pestana = @$consulta_formulario_pestana->fetch())
                    {
                        //Si la pestana es PCO_NoVisible entonces agrega la clase de oculta en impresion
                        $ComplementoClaseOcultaImpresion="";
                        if ($registro_formulario_pestana["pestana_objeto"]=="PCO_NoVisible") $ComplementoClaseOcultaImpresion="oculto_impresion";

                        $titulo_pestana_formulario=$registro_formulario_pestana["pestana_objeto"];
                        //Genera el contenedor de la pestana.  Se considera necesario crear contenedores solo cuando hay mas de una pestana, si hay una solamente entonces no hay que crear el contenedor
                        if ($conteo_pestanas>1 || $conteo_pestanas_ocultas==1)
                        echo '
                        <!-- INICIO de las pestanas No '.$pestana_activa.' -->
                            <div class="tab-pane fade '.$estado_activa_primera_pestana.' '.$ComplementoClaseOcultaImpresion.' " id="PCO_Pestana'.$ComplementoPestanas.'Formulario_'.$pestana_activa.'" >';

                                //Booleana que determina si se debe incluir el javascript de ckeditor
                                $existe_campo_textoformato=0;

                                //DIAGRAMACION DE LA TABLA CON ELEMENTOS DEL FORMULARIO
                                $limite_inferior=-9999; // Peso inferior a tener en cuenta en el query
                                $constante_limite_superior=+9999;
                                $limite_superior=$constante_limite_superior; // Peso superior a tener en cuenta en el query
                                //Busca todos los objetos marcados como fila_unica=1 y agrega un registro mas con el limite superior
                                $consulta_obj_fila_unica=PCO_EjecutarSQL("SELECT id,PCOBD_Peso,visible FROM ".$TablasCore."formulario_objeto WHERE pestana_objeto=? AND formulario=? AND fila_unica='1' AND visible=1 UNION SELECT 0,$limite_superior,0 ORDER BY PCOBD_Peso","$titulo_pestana_formulario$_SeparadorCampos_$formulario");
                                //Define si debe o no dibujar borde de las celdas
                                $estilo_bordes="table-unbordered";
                                $ancho_bordes="border-width: 0px;";
                                if ($registro_formulario["borde_visible"]==1)
									{
										$estilo_bordes="table-bordered";
										$ancho_bordes="border-width: 1px;";
									}

                                $TabIndex_Elemento=1;
                                while ($registro_obj_fila_unica = $consulta_obj_fila_unica->fetch())
                                    {
                                        $limite_superior=$registro_obj_fila_unica["PCOBD_Peso"];
                                        $ultimo_id=$registro_obj_fila_unica["id"];

                                        //Define tipo_maquetacion
                                        if($registro_formulario["tipo_maquetacion"]=="responsive")
                                            {
                                                echo '<div class="row">';
                                            }
                                        //Define tipo_maquetacion
                                        if($registro_formulario["tipo_maquetacion"]=="tradicional")
                                            {
                                                // Inicia la tabla con los campos
                                                echo '
                                                    <div class="table-responsive" style="border-width: 0px; margin-top:0; margin-bottom:0; margin-left:0; margin-right:0; ">
                                                    <table class="table table-responsive '.$estilo_bordes.' table-condensed btn-xs d-flex" style="'.$ancho_bordes.' margin-top:0; margin-bottom:0; margin-left:0; margin-right:0; padding: 0px; border-spacing: 0px; "><tr>';
                                            }

                                        //Recorre todas las comunas definidas para el formulario buscando objetos
                                        for ($cl=1;$cl<=$registro_formulario["columnas"];$cl++)
                                            {
                                                //Busca los elementos de la coumna actual del formulario con PCOBD_Peso menor o igual al PCOBD_Peso del objeto fila_unica de la fila unica_actual pero que no son fila_unica
                                                $consulta_campos=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_formulario_objeto." FROM ".$TablasCore."formulario_objeto WHERE pestana_objeto=? AND formulario=? AND PCOBD_Columna=? AND visible=1 AND PCOBD_Peso >? AND PCOBD_Peso <=? ORDER BY PCOBD_Peso","$titulo_pestana_formulario$_SeparadorCampos_$formulario$_SeparadorCampos_$cl$_SeparadorCampos_$limite_inferior$_SeparadorCampos_$limite_superior");

                                                    //Define tipo_maquetacion JJJ
                                                    if($registro_formulario["tipo_maquetacion"]=="responsive")
                                                        {
                                                            //Busca la clase asociada a la columna. Si no hay utiliza la ultima clase definida
                                                            $ArregloClasesColumnas=explode("|",$registro_formulario["css_columnas"]);
                                                            $ClaseColumna=$ArregloClasesColumnas[$cl-1];
                                                            if ($ClaseColumna!="") $UltimaClaseColumna=$ClaseColumna;
                                                            else $ClaseColumna=$UltimaClaseColumna;
                                                            //echo $ClaseColumna;
                                                            echo '<div class="'.$ClaseColumna.'">'; //col col-xs-3 col-sm-3 col-md-3 col-lg-3
                                                        }
                                                    //Define tipo_maquetacion
                                                    if($registro_formulario["tipo_maquetacion"]=="tradicional")
                                                        {
                                                            //Inicia columna de formulario
                                                            $PCO_AnchoColumnas=round(100 / $registro_formulario["columnas"]);
                                                            echo '<td width="'.$PCO_AnchoColumnas.'%" >';
                                                        }

                                                    // Crea los campos definidos por cada columna de formulario
                                                    while ($registro_campos = $consulta_campos->fetch())
                                                        {
                                                            //Determina si el estilo del objeto debe ser inline o no
                                                            $cadena_modo_inline='';
                                                            if ($registro_campos["modo_inline"])
                                                                $cadena_modo_inline='display:inline;';
                                                            echo '<div style="'.$cadena_modo_inline.'">';

                                                            //Imprime el campo solamente si no es fila unica, si es fila_unica guarda en una variable para uso posterior
                                                            if($registro_campos["fila_unica"]=="0")
                                                                {
                                                                    //Si esta en modo de diseno el formulario agrega elementos extra para la edicion de cada control
                                                                    $ComplementoDisenoElemento='';
                                                                    $ComplementoDisenoMarcoOpciones='';
                                                                    if ($modo_diseno_formulario)
                                                                        {
                                                                            $ComplementoDisenoElemento=PCO_AgregarFuncionesEdicionObjeto($registro_campos,$registro_formulario,"ComplementoDisenoElemento");
                                                                            $ComplementoDisenoMarcoOpciones=PCO_AgregarFuncionesEdicionObjeto($registro_campos,$registro_formulario,"ComplementoDisenoMarcoOpciones");
                                                                        }
                                                                    //Define el estilo del contenedor para el objeto
                                                                    $ClaseCSSContenedor="";
                                                                    if ($registro_campos["clase_contenedor"]!="") $ClaseCSSContenedor=$registro_campos["clase_contenedor"];
                                                                    echo '<div '.$ComplementoDisenoElemento.' id="PCOContenedor_'.$registro_campos["id_html"].'" class="'.$ClaseCSSContenedor.'" > '.$ComplementoDisenoMarcoOpciones;
                                                                    echo '<div id="PCOPre_'.$registro_campos["id_html"].'"></div>';
                                                                    
                                                                    //Agrega etiqueta para colapsar el control si aplica
                                                                    if ($registro_campos["etiqueta_colapsable"]!="") 
                                                                        echo '<details><summary>'.PCO_ReemplazarVariablesPHPEnCadena($registro_campos["etiqueta_colapsable"]).'</summary>';
                                                                    
                                                                    // Formatea cada campo de acuerdo a su tipo
                                                                    // CUIDADO!!! Modificando las lineas de tipo siguientes debe modificar las lineas de tipo un poco mas abajo tambien
                                                                    $tipo_de_objeto=@$registro_campos["tipo"];
                                                                    switch ($tipo_de_objeto) {

                                                                        case 'texto_corto': $objeto_formateado = @PCO_CargarObjetoTextoCorto($registro_campos,@$registro_datos_formulario,$formulario,$en_ventana); break;
                                                                        case 'texto_clave': $objeto_formateado = @PCO_CargarObjetoTextoCorto($registro_campos,@$registro_datos_formulario,$formulario,$en_ventana); break;
                                                                        case 'texto_largo': $objeto_formateado = @PCO_CargarObjetoTextoLargo($registro_campos,@$registro_datos_formulario); break;
                                                                        case 'texto_formato': { $objeto_formateado = @PCO_CargarObjetoTextoFormato($registro_campos,@$registro_datos_formulario,$existe_campo_textoformato); $existe_campo_textoformato=1; } break;
                                                                        case 'area_responsive': $objeto_formateado = @PCO_CargarObjetoAreaResponsive($registro_campos,@$registro_datos_formulario); break;
                                                                        case 'lista_seleccion': $objeto_formateado = @PCO_CargarObjetoListaSeleccion($registro_campos,@$registro_datos_formulario,$formulario,$en_ventana); break;
                                                                        case 'lista_radio': $objeto_formateado = @PCO_CargarObjetoListaRadio($registro_campos,@$registro_datos_formulario,$formulario,$en_ventana); break;
                                                                        case 'casilla_check': $objeto_formateado = @PCO_CargarObjetoCasillaCheck($registro_campos,@$registro_datos_formulario,$formulario,$en_ventana); break;
                                                                        case 'etiqueta': $objeto_formateado = @PCO_CargarObjetoEtiqueta($registro_campos,@$registro_datos_formulario); break;
                                                                        case 'url_iframe': $objeto_formateado = @PCO_CargarObjetoIFrame($registro_campos,@$registro_datos_formulario); break;
                                                                        case 'informe': $informe_formateado=@PCO_CargarInforme($registro_campos["informe_vinculado"],$registro_campos["objeto_en_ventana"],"htm","Informes",1,$registro_campos["anular_acciones"],$registro_campos["anular_piepagina"],$registro_campos["anular_encabezado"]); break;
                                                                        case 'deslizador': $objeto_formateado = @PCO_CargarObjetoDeslizador($registro_campos,@$registro_datos_formulario); break;
                                                                        case 'campo_etiqueta': $objeto_formateado = @PCO_CargarObjetoCampoEtiqueta($registro_campos,@$registro_datos_formulario); break;
                                                                        case 'archivo_adjunto': $objeto_formateado = @PCO_CargarObjetoArchivoAdjunto($registro_campos,@$registro_datos_formulario); break;
                                                                        case 'objeto_canvas': $objeto_formateado = @PCO_CargarObjetoCanvas($registro_campos,@$registro_datos_formulario,$formulario); break;
                                                                        case 'objeto_camara': $objeto_formateado = @PCO_CargarObjetoCamara($registro_campos,@$registro_datos_formulario,$formulario); break;
                                                                        case 'boton_comando': $objeto_formateado = @PCO_CargarObjetoBotonComando($registro_campos,@$registro_datos_formulario,@$registro_formulario);
                                                                    }

                                                                    //Carga SubFormulario solo si no es el mismo actual para evitar ciclos infinitos

                                                                    //Ademas si es subformulario debe consultar en ese registro de ID buscado del form
                                                                    //padre el valor del campo foraneo del form hijo para llamar a buscar form con
                                                                    //el valor de Id correspondiente. Ademas valida si el form existe
                                                                    if ($tipo_de_objeto=="form_consulta" && $registro_campos["formulario_vinculado"]!=$formulario && PCO_ExisteValor($TablasCore."formulario","id",$registro_campos["formulario_vinculado"]))
                                                                        {
                                                                            //Busca la tabla principal del subformulario anidado
                                                                            $PCO_ValorCampoBind=$registro_campos["formulario_vinculado"];
                                                                            if($PCO_ValorCampoBind=="") $PCO_ValorCampoBind="";
                                                                            $consulta_tabla_subform=PCO_EjecutarSQL("SELECT tabla_datos FROM ".$TablasCore."formulario WHERE id=? ","$PCO_ValorCampoBind")->fetch();
                                                                            $PCO_TablaSubform=$consulta_tabla_subform["tabla_datos"];

                                                                            //Determina el valor del campo a vincular en el registro padre (el actual).  Deberia dar el id que se va a buscar
                                                                            $PCO_ValorCampoPadre=@$registro_datos_formulario[$registro_campos["formulario_campo_vinculo"]];
                                                                            //Si no se encuentra el dato o registro entonces mira si vienen desde un boton de busqueda y usa su valor
                                                                            if($PCO_ValorCampoPadre=="" && $PCO_ValorBusquedaBD!="")
                                                                                {
                                                                                    //$PCO_ValorCampoPadre=$PCO_ValorBusquedaBD;
                                                                                }
                                                                            //Si no obtiene ningun valor entonces lo pone en cero para evitar error de sintaxis en Bind de SQL
                                                                            if($PCO_ValorCampoPadre=="") $PCO_ValorCampoPadre=0;
                                                                            $PCO_CampoForaneoSubform=$registro_campos["formulario_campo_foraneo"];
                                                                            //Busca el ID de registro correspondiente en la tabla de datos para llamar con el valor coincidente
                                                                            $consulta_registro_subform=PCO_EjecutarSQL("SELECT $PCO_CampoForaneoSubform FROM $PCO_TablaSubform WHERE $PCO_CampoForaneoSubform=? ","$PCO_ValorCampoPadre")->fetch();

                                                                            $formulario_formateado=@PCO_CargarFormulario($registro_campos["formulario_vinculado"],$registro_campos["objeto_en_ventana"],$registro_campos["formulario_campo_foraneo"],$PCO_ValorCampoPadre,1,0,"Sub");
                                                                        }
                                                                    else
																		{
																			//Presenta mensaje de error al no poder empotrar subformulario
																			if($tipo_de_objeto=="form_consulta")
																				PCO_Mensaje($MULTILANG_ErrorTiempoEjecucion,$MULTILANG_ObjetoNoExiste.'.  FormID: '.$registro_campos["formulario_vinculado"], '', 'fa fa-times fa-5x icon-red texto-blink', 'alert alert-danger alert-dismissible');
																		}

                                                                    //Imprime el objeto siempre y cuando no sea uno preformateado por practico (informes, formularios, etc)
                                                                    if ($registro_campos["tipo"]!="informe" && $registro_campos["tipo"]!="form_consulta")
                                                                        echo $objeto_formateado;

                                                                    //Cierra la etiqueta colapsable en caso de haber abierto una
                                                                    if ($registro_campos["etiqueta_colapsable"]!="") 
                                                                        echo '</details>';
                                                                        
                                                                    echo '<div id="PCOPos_'.$registro_campos["id_html"].'"></div>';
                                                                    echo '</div>'; //Marco PCOContenedor
                                                                }

                                                            //Cierra el marco para el estilo inline del objeto
                                                            echo '</div>';
                                                        }

                                                    //Define tipo_maquetacion
                                                    if($registro_formulario["tipo_maquetacion"]=="responsive")
                                                        {
                                                            echo '</div>'; //Fin class=col
                                                        }
                                                    //Define tipo_maquetacion
                                                    if($registro_formulario["tipo_maquetacion"]=="tradicional")
                                                        {
                                                            echo '</td>'; //Fin columna de formulario
                                                        }
                                            }

                                        //Define tipo_maquetacion
                                        if($registro_formulario["tipo_maquetacion"]=="responsive")
                                            {
                                                echo '</div>'; //Fin class=row
                                            }
                                        //Define tipo_maquetacion
                                        if($registro_formulario["tipo_maquetacion"]=="tradicional")
                                            {
                                                // Finaliza la tabla con los campos
                                                echo '</tr></table>
                                                    </div>';
                                            }

                                        //Busca datos del registro de fila_unica
                                        $consulta_campos=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_formulario_objeto." FROM ".$TablasCore."formulario_objeto WHERE formulario=? AND id=? ","$formulario$_SeparadorCampos_$ultimo_id");
                                        $registro_campos = $consulta_campos->fetch();

                                        //Agrega el campo de fila unica cuando no se trata del agregado de peso 9999
                                        if ($registro_campos["visible"]=="1")
                                            {
                                                //echo '&nbsp;&nbsp;'.$registro_campos["titulo"];
                                                // Formatea cada campo de acuerdo a su tipo
                                                // CUIDADO!!! Modificando las lineas de tipo siguientes debe modificar las lineas de tipo un poco mas arriba tambien
                                                //Si esta en modo de diseno el formulario agrega elementos extra para la edicion de cada control
                                                $ComplementoDisenoElemento='';
                                                $ComplementoDisenoMarcoOpciones='';
                                                if ($modo_diseno_formulario)
                                                    {
                                                        $ComplementoDisenoElemento=PCO_AgregarFuncionesEdicionObjeto($registro_campos,$registro_formulario,"ComplementoDisenoElemento");
                                                        $ComplementoDisenoMarcoOpciones=PCO_AgregarFuncionesEdicionObjeto($registro_campos,$registro_formulario,"ComplementoDisenoMarcoOpciones");
                                                    }

                                                //Define el estilo del contenedor para el objeto
                                                $ClaseCSSContenedor="";
                                                if ($registro_campos["clase_contenedor"]!="") $ClaseCSSContenedor=$registro_campos["clase_contenedor"];

                                                echo '<div '.$ComplementoDisenoElemento.' id="PCOContenedor_'.$registro_campos["id_html"].'" class="'.$ClaseCSSContenedor.'" style="margin-top:0px; margin-bottom:0px; margin-left:0; margin-right:0;  padding: 0px; spacing: 0px;">'.$ComplementoDisenoMarcoOpciones.'';
                                                echo '<div id="PCOPre_'.$registro_campos["id_html"].'"></div>';

                                                //Agrega etiqueta para colapsar el control si aplica
                                                if ($registro_campos["etiqueta_colapsable"]!="") 
                                                    echo '<details><summary>'.PCO_ReemplazarVariablesPHPEnCadena($registro_campos["etiqueta_colapsable"]).'</summary>';
                                                    
                                                //Define tipo_maquetacion
                                                if($registro_formulario["tipo_maquetacion"]=="responsive")
                                                    {
                                                        echo '<div class="row"><div class="col col-xs-12 col-sm-12 col-md-12 col-lg-12">';
                                                    }
                                                //Define tipo_maquetacion
                                                if($registro_formulario["tipo_maquetacion"]=="tradicional")
                                                    {
                                                        echo '<table class="table table-condensed btn-xs '.$estilo_bordes.' d-flex" style="'.$ancho_bordes.' margin-top:0; margin-bottom:0; margin-left:0; margin-right:0;  padding: 0px; border-spacing: 0px; width:100%; "><tr><td>';
                                                    }


                                                $tipo_de_objeto=@$registro_campos["tipo"];
                                                switch ($tipo_de_objeto) {

                                                    case 'texto_corto': $objeto_formateado = PCO_CargarObjetoTextoCorto($registro_campos,@$registro_datos_formulario,$formulario,$en_ventana); break;
                                                    case 'texto_clave': $objeto_formateado = PCO_CargarObjetoTextoCorto($registro_campos,@$registro_datos_formulario,$formulario,$en_ventana); break;
                                                    case 'texto_largo': $objeto_formateado = PCO_CargarObjetoTextoLargo($registro_campos,@$registro_datos_formulario); break;
                                                    case 'texto_formato': { $objeto_formateado = PCO_CargarObjetoTextoFormato($registro_campos,@$registro_datos_formulario,$existe_campo_textoformato); $existe_campo_textoformato=1; } break;
                                                    case 'area_responsive': $objeto_formateado = @PCO_CargarObjetoAreaResponsive($registro_campos,@$registro_datos_formulario); break;
                                                    case 'lista_seleccion': $objeto_formateado = PCO_CargarObjetoListaSeleccion($registro_campos,@$registro_datos_formulario,$formulario,$en_ventana); break;
                                                    case 'lista_radio': $objeto_formateado = PCO_CargarObjetoListaRadio($registro_campos,@$registro_datos_formulario,$formulario,$en_ventana); break;
                                                    case 'casilla_check': $objeto_formateado = @PCO_CargarObjetoCasillaCheck($registro_campos,@$registro_datos_formulario,$formulario,$en_ventana); break;
                                                    case 'etiqueta': $objeto_formateado = PCO_CargarObjetoEtiqueta($registro_campos,@$registro_datos_formulario); break;
                                                    case 'url_iframe': $objeto_formateado = PCO_CargarObjetoIFrame($registro_campos,@$registro_datos_formulario); break;
                                                    case 'informe': $informe_formateado=@PCO_CargarInforme($registro_campos["informe_vinculado"],$registro_campos["objeto_en_ventana"],"htm","Informes",1,$registro_campos["anular_acciones"],$registro_campos["anular_piepagina"],$registro_campos["anular_encabezado"]); break;
                                                    case 'deslizador': $objeto_formateado = @PCO_CargarObjetoDeslizador($registro_campos,@$registro_datos_formulario); break;
                                                    case 'campo_etiqueta': $objeto_formateado = @PCO_CargarObjetoCampoEtiqueta($registro_campos,@$registro_datos_formulario); break;
                                                    case 'archivo_adjunto': $objeto_formateado = @PCO_CargarObjetoArchivoAdjunto($registro_campos,@$registro_datos_formulario); break;
                                                    case 'objeto_canvas': $objeto_formateado = @PCO_CargarObjetoCanvas($registro_campos,@$registro_datos_formulario,$formulario); break;
                                                    case 'objeto_camara': $objeto_formateado = @PCO_CargarObjetoCamara($registro_campos,@$registro_datos_formulario,$formulario); break;
                                                    case 'boton_comando': $objeto_formateado = @PCO_CargarObjetoBotonComando($registro_campos,@$registro_datos_formulario,@$registro_formulario);
                                                }

                                                //Carga SubFormulario solo si no es el mismo actual para evitar ciclos infinitos
                                                //Ademas si es subformulario debe consultar en ese registro de ID buscado del form
                                                //padre el valor del campo foraneo del form hijo para llamar a buscar form con
                                                //el valor de Id correspondiente. Ademas valida si el form existe
                                                if ($tipo_de_objeto=="form_consulta" && $registro_campos["formulario_vinculado"]!=$formulario && PCO_ExisteValor($TablasCore."formulario","id",$registro_campos["formulario_vinculado"]))
                                                    {
                                                        //Busca la tabla principal del subformulario anidado
                                                        $PCO_ValorCampoBind=$registro_campos["formulario_vinculado"];
                                                        if($PCO_ValorCampoBind=="") $PCO_ValorCampoBind="";
                                                        $consulta_tabla_subform=PCO_EjecutarSQL("SELECT tabla_datos FROM ".$TablasCore."formulario WHERE id=? ","$PCO_ValorCampoBind")->fetch();
                                                        $PCO_TablaSubform=$consulta_tabla_subform["tabla_datos"];

                                                        //Determina el valor del campo a vincular en el registro padre (el actual).  Deberia dar el id que se va a buscar
                                                        $PCO_ValorCampoPadre=@$registro_datos_formulario[$registro_campos["formulario_campo_vinculo"]];
                                                        //Si no se encuentra el dato o registro entonces mira si vienen desde un boton de busqueda y usa su valor
                                                        if($PCO_ValorCampoPadre=="" && $PCO_ValorBusquedaBD!="")
                                                            {
                                                                //$PCO_ValorCampoPadre=$PCO_ValorBusquedaBD;
                                                            }
                                                        //Si no obtiene ningun valor entonces lo pone en cero para evitar error de sintaxis en Bind de SQL
                                                        if($PCO_ValorCampoPadre=="") $PCO_ValorCampoPadre=0;
                                                        $PCO_CampoForaneoSubform=$registro_campos["formulario_campo_foraneo"];
                                                        //Busca el ID de registro correspondiente en la tabla de datos para llamar con el valor coincidente
                                                        $consulta_registro_subform=PCO_EjecutarSQL("SELECT $PCO_CampoForaneoSubform FROM $PCO_TablaSubform WHERE $PCO_CampoForaneoSubform=? ","$PCO_ValorCampoPadre")->fetch();

                                                        $formulario_formateado=@PCO_CargarFormulario($registro_campos["formulario_vinculado"],$registro_campos["objeto_en_ventana"],$registro_campos["formulario_campo_foraneo"],$PCO_ValorCampoPadre,1,0,"Sub");
                                                    }
												else
													{
														//Presenta mensaje de error al no poder empotrar subformulario
														if($tipo_de_objeto=="form_consulta")
															PCO_Mensaje($MULTILANG_ErrorTiempoEjecucion,$MULTILANG_ObjetoNoExiste.'.  FormID: '.$registro_campos["formulario_vinculado"], '', 'fa fa-times fa-5x icon-red texto-blink', 'alert alert-danger alert-dismissible');
													}

                                                //Imprime el objeto siempre y cuando no sea uno preformateado por practico (informes, formularios, etc)
                                                if ($registro_campos["tipo"]!="informe" && $registro_campos["tipo"]!="form_consulta")
                                                    echo $objeto_formateado;

                                                //Define tipo_maquetacion
                                                if($registro_formulario["tipo_maquetacion"]=="responsive")
                                                    {
                                                        echo '</div></div>'; //Fin class=row y class=col
                                                    }
                                                //Define tipo_maquetacion
                                                if($registro_formulario["tipo_maquetacion"]=="tradicional")
                                                    {
                                                        echo '</td></tr></table>';
                                                    }

                                                //Cierra la etiqueta colapsable en caso de haber abierto una
                                                if ($registro_campos["etiqueta_colapsable"]!="") 
                                                    echo '</details>';

                                                echo '<div id="PCOPos_'.$registro_campos["id_html"].'"></div>';
                                                echo '</div>'; //Marco PCOContenedor
                                            }

                                        //Actualiza limite inferior para siguiente lista de campos
                                        $limite_inferior=$registro_obj_fila_unica["PCOBD_Peso"];
                                        $TabIndex_Elemento++;
                                    }

                        if ($conteo_pestanas>1  || $conteo_pestanas_ocultas==1)
                        echo '
                            </div>
                        <!-- FIN de las pestanas No '.$pestana_activa.'-->';

                        //Limpia para las siguientes pestanas
                        $estado_activa_primera_pestana='';
                        $pestana_activa++;
                    }
                //Fin de los tab-content
                echo '</div>';
            } //Fin Si conteo pestanas > 0

		echo '</div> <!-- cierra PCO_MarcoImpresion'.$formulario.' -->';

	//Busca los campos definidos como visilbe=0 (o NO) para agregarlos como hidden
	$consulta_ocultos=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_formulario_objeto." FROM ".$TablasCore."formulario_objeto WHERE formulario=? AND visible=0 ","$formulario");
	while ($registro_ocultos = $consulta_ocultos->fetch())
		{
			// Formatea cada campo de acuerdo a su tipo
			$objeto_formateado = @PCO_CargarObjetoOculto($registro_ocultos,$registro_datos_formulario,$formulario,$en_ventana);
			//Imprime el objeto siempre y cuando no sea uno preformateado por practico (informes, formularios, etc)
			if ($registro_campos["tipo"]!="informe" && $registro_campos["tipo"]!="form_consulta" && $registro_campos["tipo"]!="boton_comando")
				echo $objeto_formateado;
		}

	// Si tiene botones agrega barra de estado y los ubica
	$consulta_botones = PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_formulario_boton." FROM ".$TablasCore."formulario_boton WHERE formulario=? AND visible=1 ORDER BY peso","$formulario");

	if($consulta_botones->rowCount()>0 || $PCO_InformeFiltro!="") //Crea la barra incluso si no hay botones en diseno pero se encuentra que el llamado es desde un informe que requiere filtro
		{
			PCO_AbrirBarraEstado();
            echo '<div align="center">';
			while ($registro_botones = $consulta_botones->fetch())
				{
					//Transfiere variables de mensajes de retorno asociadas al boton
					$comando_javascript="";
					if ($registro_botones["retorno_titulo"]!="")
						$comando_javascript="document.".$registro_formulario["id_html"].".PCO_ErrorTitulo.value='".$registro_botones["retorno_titulo"]."'; document.".$registro_formulario["id_html"].".PCO_ErrorDescripcion.value='".$registro_botones["retorno_texto"]."'; document.".$registro_formulario["id_html"].".PCO_ErrorIcono.value='".$registro_botones["retorno_icono"]."'; document.".$registro_formulario["id_html"].".PCO_ErrorEstilo.value='".$registro_botones["retorno_estilo"]."';";

					//Define el tipo de boton de acuerdo al tipo de accion
          switch ($registro_botones["tipo_accion"]) {

                case 'interna_guardar':    $comando_javascript.="PCOJS_ValidarCamposYProcesarFormulario('".$registro_formulario["id_html"]."');";     break;
                case 'interna_limpiar':    $comando_javascript.="document.getElementById('".$registro_formulario["id_html"]."').reset();"; break;
                case 'interna_escritorio': $comando_javascript.="document.PCO_FormVerMenu.submit();"; break;
                case 'interna_actualizar': $comando_javascript.="document.".$registro_formulario["id_html"].".PCO_Accion.value='PCO_ActualizarDatosFormulario'; PCOJS_ValidarCamposYProcesarFormulario('".$registro_formulario["id_html"]."');"; break;
                case 'externa_postcode':   $comando_javascript.="document.".$registro_formulario["id_html"].".PCO_Accion.value='PCO_EjecutarPostAccionForm'; PCOJS_ValidarCamposYProcesarFormulario('".$registro_formulario["id_html"]."'); "; break;
                case 'interna_eliminar':   $comando_javascript.="document.".$registro_formulario["id_html"].".PCO_Accion.value='PCO_EliminarDatosFormulario';document.".$registro_formulario["id_html"].".submit();"; break;
                case 'interna_cargar':     $comando_javascript.="document.".$registro_formulario["id_html"].".PCO_Accion.value='PCO_CargarObjeto';document.".$registro_formulario["id_html"].".PCO_Objeto.value='".$registro_botones["accion_usuario"]."'; PCOJS_SanitizarValoresListaMultiple(); document.".$registro_formulario["id_html"].".submit(); "; break;
                case 'externa_formulario': $comando_javascript.="document.".$registro_formulario["id_html"].".PCO_Accion.value='".$registro_botones["accion_usuario"]."';  PCOJS_SanitizarValoresListaMultiple(); document.".$registro_formulario["id_html"].".submit(); "; break;
                case 'externa_javascript': $comando_javascript.=$registro_botones["accion_usuario"];
          }


                    //Verifica si el registro de botones presenta algun texto de confirmacion y lo antepone al script
                    $cadena_confirmacion_accion_pre="";
                    $cadena_confirmacion_accion_pos="";
					if ($registro_botones["confirmacion_texto"]!="")
						{
							$cadena_confirmacion_accion_pre=" if (confirm('".PCO_ReemplazarVariablesPHPEnCadena($registro_botones["confirmacion_texto"])."')) {";
							$cadena_confirmacion_accion_pos=" } else {} ";
						}

                    //Genera la cadena del enlace
                    $cadena_javascript='href="javascript:  '.$cadena_confirmacion_accion_pre.'  '.@$comando_javascript.'  '.$cadena_confirmacion_accion_pos.'  "';

					//Si no se especifica un estilo para el boton entonces se usa el predeterminado
                    $estilo_basico_boton="btn btn-default";
                    //Si el boton tiene definido un ID lo agrega
                    $CadenaIDHtml='';
                    if ($registro_botones["id_html"]!="") $CadenaIDHtml=' id="'.$registro_botones["id_html"].'" ';
                    echo '<a '.$CadenaIDHtml.' class="'.$estilo_basico_boton.' '.$registro_botones["estilo"].'" '.@$cadena_javascript.'>'.PCO_ReemplazarVariablesPHPEnCadena($registro_botones["titulo"]).'</a>';

                    echo '&nbsp;&nbsp;'; //Agrega espacio temporal entre controles
				}

			if ($PCO_InformeFiltro!="")
				{
					//Si se encuentra que el form viene llamado desde un informe que lo requiere para filtro agrega un boton de retorno al informe automaticamente
					$comando_javascript="document.".$registro_formulario["id_html"].".PCO_Accion.value='PCO_CargarObjeto';document.".$registro_formulario["id_html"].".PCO_Objeto.value='inf:".$PCO_InformeFiltro.":1';document.".$registro_formulario["id_html"].".submit();";
					$cadena_javascript='href="javascript:'.@$comando_javascript.'"';
					echo '<a class="'.$estilo_basico_boton.' btn btn-warning" '.@$cadena_javascript.'>'.$MULTILANG_InfRetornoFormFiltrado.'</a>';
				}

            echo '</div>';
			PCO_CerrarBarraEstado();
		}


	//Cierra todo el formulario
	//Si se quiere anular el formulario y su accion cuando se trata de un sub-formulario de consulta
	if (!$anular_form)
		echo '</form>';

	//Carga todos los eventos asociados a los controles de formulario
	$eventos_controles_formulario=PCO_EjecutarSQL("SELECT ".$TablasCore."evento_objeto.*,".$TablasCore."formulario_objeto.id_html FROM ".$TablasCore."evento_objeto,".$TablasCore."formulario_objeto WHERE ".$TablasCore."evento_objeto.objeto=".$TablasCore."formulario_objeto.id  AND ".$TablasCore."formulario_objeto.formulario=$formulario ");
	while($registro_eventos_definidos = $eventos_controles_formulario->fetch())
		{
		    //Limpia el metodo, asume no conocerlo

            switch ($registro_eventos_definidos["evento"]) {
              //1-Raton
              case 'onclick': $MetodoJQuery="click"; break;
              case 'ondblclick': $MetodoJQuery="dblclick"; break;
              case 'onmousedown': $MetodoJQuery="mousedown"; break;
              case 'onmouseenter': $MetodoJQuery="mouseenter"; break;
              case 'onmouseleave': $MetodoJQuery="mouseleave"; break;
              case 'onmousemove': $MetodoJQuery="mousemove"; break;
              case 'onmouseover': $MetodoJQuery="mouseover"; break;
              case 'onmouseout': $MetodoJQuery="mouseout"; break;
              case 'onmouseup': $MetodoJQuery="mouseup"; break;
              case 'contextmenu': $MetodoJQuery="contextmenu"; break;
              //2-Teclado
              case 'onkeydown': $MetodoJQuery="keydown"; break;
              case 'onkeypress': $MetodoJQuery="keypress"; break;
              case 'onkeyup': $MetodoJQuery="keyup"; break;
              //3-Formularios
              case 'onfocus': $MetodoJQuery="focus"; break;
              case 'onblur': $MetodoJQuery="blur"; break;
              case 'onchange': $MetodoJQuery="change"; break;
              case 'onselect': $MetodoJQuery="select"; break;
              case 'onsubmit': $MetodoJQuery="submit"; break;
              case 'oncut': $MetodoJQuery="reset"; break;
              case 'oncopy': $MetodoJQuery="click"; break;
              case 'onpaste': $MetodoJQuery="click"; break;
              default:
                $MetodoJQuery="";
            }

			//Imprime el script asociado al evento siempre y cuando la funcion sea reconocida
			if ($MetodoJQuery!="")
			    {
					$PCO_FuncionesJSInternasFORM .= '
					    <script language=\'JavaScript\'>
                            $( "#'.$registro_eventos_definidos["id_html"].'" ).on("'.$MetodoJQuery.'",function(PCOJS_Evento) {
                              '.PCO_ReemplazarVariablesPHPEnCadena($registro_eventos_definidos["javascript"]).'
                            });
					    </script>';
			    }
		}

        //Carga las funciones JavaScript asociadas al formulario y llama la funcion FrmAutoRun()
        $JavaScriptFormulario=PCO_ReemplazarVariablesPHPEnCadena($registro_formulario["javascript"]);

        //Minimiza el codigo JavaScript del formulario
        //$JavaScriptFormulario=PCO_Minimizador_OptimizarJS($JavaScriptFormulario);

        //Reemplaza la funcion de FrmAutoRun() del formulario por FrmAutoRun_IDFormulario() para garantizar que es unica
        $NumeroIdFormulario=$registro_formulario["id"];
        if ($NumeroIdFormulario<0) $NumeroIdFormulario="LTZ".($NumeroIdFormulario*-1);
        $JavaScriptFormulario=str_replace("FrmAutoRun()","FrmAutoRun_IDForm".$NumeroIdFormulario."()",$JavaScriptFormulario);
        	$PCO_FuncionesJSInternasFORM .= '<script type="text/javascript">'.$JavaScriptFormulario.'
        		if (typeof FrmAutoRun_IDForm'.$NumeroIdFormulario.' === "function") { FrmAutoRun_IDForm'.$NumeroIdFormulario.'(); }
        		</script>';

        //Busca la lista de campos marcados como obligatorios sobre el form
        $consulta_campos_obligatorios=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_formulario_objeto." FROM ".$TablasCore."formulario_objeto WHERE formulario=? AND obligatorio=1","$formulario");
        $ListaCamposObligatorios="";
        $ListaTitulosObligatorios="";
        while ($registro_campos_obligatorios=$consulta_campos_obligatorios->fetch())
            {
                $ListaCamposObligatorios.="|".$registro_campos_obligatorios["id_html"];
                $ListaTitulosObligatorios.="|".$registro_campos_obligatorios["titulo"];
            }
        $POSTForm_ListaCamposObligatorios.=$ListaCamposObligatorios;
        $POSTForm_ListaTitulosObligatorios.=$ListaTitulosObligatorios;

        if ($en_ventana) PCO_CerrarVentana();
  }


########################################################################
########################################################################
/*
	Function: PCO_GenerarBotonesInforme
	Genera el codigo HTML correspondiente a los botones definidos para cada registro de un informe indicado por su ID

	Variables de entrada:

		informe - ID unico del informe del cual se desea construir el query

	Salida:

		HTML con los botones

	Ver tambien:
		<PCO_CargarInforme>
*/
function PCO_GenerarBotonesInforme($informe,$Ubicacion=0)
	{
		global $ConexionPDO,$ArchivoCORE,$TablasCore,$PCO_ValorBusquedaBD,$PCO_CampoBusquedaBD;
		// Carga variables de sesion por si son comparadas en alguna condicion.  De todas formas pueden ser cargadas por el usuario en el diseno del informe
		global $ListaCamposSinID_informe,$ListaCamposSinID_informe_campos,$ListaCamposSinID_informe_tablas,$ListaCamposSinID_informe_condiciones,$ListaCamposSinID_informe_boton;

		$ComplementoUbicacion=' AND ubicar_principio=0 ';
		if ($Ubicacion==1)
		    $ComplementoUbicacion=' AND ubicar_principio=1 ';

		//Inicializa la cadena de botones vacia
		$cadena_generica_botones='';

		// Busca si el informe tiene acciones (botones), los cuenta y prepara dentro de un arreglo para repetir en cada registro
		$consulta_botones=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_informe_boton." FROM ".$TablasCore."informe_boton WHERE informe=? AND visible=1 $ComplementoUbicacion ORDER BY peso","$informe");
		while($registro_botones=$consulta_botones->fetch())
			{
				$destino_formulario=$registro_botones["destino"];
				$pantalla_completa_formulario=$registro_botones["pantalla_completa"];
				$precargar_estilos_formulario=$registro_botones["precargar_estilos"];
				//Construye una cadena generica con todos los botones para ser reemplazada luego con valores
				if ($registro_botones["tipo_accion"]=="interna_eliminar")
					{
						$valores = explode(".",$registro_botones["accion_usuario"]);
						$tabla_vinculada=@$valores[0];
						$campo_vinculado=@$valores[1];

						//Si solo se indico el campo, sin la tabla, intenta usar solo el campo
						if ($campo_vinculado=="" && $tabla_vinculada!="")
							{
								$campo_vinculado=$valores[0];
								$tabla_vinculada="";
							}

						$comando_javascript="
							document.FRMBASEINFORME.PCO_Accion.value='PCO_EliminarRegistroInforme';
							document.FRMBASEINFORME.tabla.value='".@$tabla_vinculada."';
							document.FRMBASEINFORME.campo.value='".@$campo_vinculado."';
							document.FRMBASEINFORME.valor.value='DELFRMVALVALOR';
							document.FRMBASEINFORME.Precarga_EstilosBS.value='".@$precargar_estilos_formulario."';
							document.FRMBASEINFORME.Presentar_FullScreen.value='".@$pantalla_completa_formulario."';
							document.FRMBASEINFORME.target = '".@$destino_formulario."';
							document.FRMBASEINFORME.submit();";
					}
				if ($registro_botones["tipo_accion"]=="interna_cargar")
					{
						$comando_javascript="
							document.FRMBASEINFORME.PCO_Accion.value='PCO_CargarObjeto';
							document.FRMBASEINFORME.PCO_Objeto.value='frm:".$registro_botones["accion_usuario"].":DETFRMVALBASE';
							document.FRMBASEINFORME.Precarga_EstilosBS.value='".@$precargar_estilos_formulario."';
							document.FRMBASEINFORME.Presentar_FullScreen.value='".@$pantalla_completa_formulario."';
							document.FRMBASEINFORME.target = '".@$destino_formulario."';
							document.FRMBASEINFORME.submit();";
					}
				if ($registro_botones["tipo_accion"]=="interna_cargar_informe")
					{
						$comando_javascript="
							document.FRMBASEINFORME.PCO_Accion.value='PCO_CargarObjeto';
							document.FRMBASEINFORME.PCO_Objeto.value='inf:".$registro_botones["accion_usuario"].":DETFRMVALBASE';
							document.FRMBASEINFORME.Precarga_EstilosBS.value='".@$precargar_estilos_formulario."';
							document.FRMBASEINFORME.Presentar_FullScreen.value='".@$pantalla_completa_formulario."';
							document.FRMBASEINFORME.target = '".@$destino_formulario."';
							document.FRMBASEINFORME.submit();";
					}
				if ($registro_botones["tipo_accion"]=="externa_formulario")
					{
						$comando_javascript="
							document.FRMBASEINFORME.PCO_Tabla.value='".@$tabla_vinculada."';
							document.FRMBASEINFORME.PCO_Campo.value='".@$campo_vinculado."';
							document.FRMBASEINFORME.PCO_Valor.value='DELFRMVALVALOR';
							document.FRMBASEINFORME.PCO_Accion.value='".$registro_botones["accion_usuario"]."';
							document.FRMBASEINFORME.Precarga_EstilosBS.value='".@$precargar_estilos_formulario."';
							document.FRMBASEINFORME.Presentar_FullScreen.value='".@$pantalla_completa_formulario."';
							document.FRMBASEINFORME.target = '".@$destino_formulario."';
							document.FRMBASEINFORME.submit();";
					}
				if ($registro_botones["tipo_accion"]=="externa_javascript")
					{
						$comando_javascript="
							document.FRMBASEINFORME.PCO_Valor.value='DELFRMVALVALOR';  ";
						$comando_javascript.=$registro_botones["accion_usuario"];
					}

				//Verifica si el registro de botones presenta algun texto de confirmacion y lo antepone al script
				$cadena_confirmacion_accion_pre="";
				$cadena_confirmacion_accion_pos="";
				if ($registro_botones["confirmacion_texto"]!="")
					{
						$cadena_confirmacion_accion_pre=" if (confirm('".PCO_ReemplazarVariablesPHPEnCadena($registro_botones["confirmacion_texto"])."')) {";
						$cadena_confirmacion_accion_pos=" } else {} ";
					}

				//Genera la cadena del enlace
				$cadena_javascript='onclick="'.$cadena_confirmacion_accion_pre.'  '.@$comando_javascript.'  '.$cadena_confirmacion_accion_pos.' "';
				//Determina si el boton llevara texto o si el texto se usa como ayuda.  Por defecto siempre se agrega el texto por defecto.
				$Cadena_Imagen="";
				$Cadena_Ayuda="";
				$Cadena_BotonIzq="";
				$Cadena_BotonDer=" ".$registro_botones["titulo"];
				//Determina si debe o no poner un elemento de imagen y si sera imagen con texto o sola
				if ($registro_botones["imagen"]!="")
					{
						$Cadena_Imagen="<i class='fa ".$registro_botones["imagen"]."'></i>";
						$Cadena_BotonIzq="";
						$Cadena_BotonDer="";
						$Cadena_Ayuda='data-toggle="tooltip" data-html="true" data-placement="auto" title="'.PCO_ReemplazarVariablesPHPEnCadena($registro_botones["titulo"]).'"';
					    //Busca si dentro de la imagen se especifico la palabra clave _TEXTOIZQ_ o _TEXTODER_ para agregar ademas el texto
					    if( strrpos ( $registro_botones["imagen"], "_TEXTOIZQ_" )!==false || strrpos ( $registro_botones["imagen"], "_TEXTODER_" )!==false )
					        {
						        $Cadena_Ayuda=''; //En cualquier caso donde se pida imprimir texto se elimina el tooltip
						        $Cadena_Imagen="<i class='fa ".$registro_botones["imagen"]."'></i>";
					            //Si se detecta el texto a la izquierda ajusta las variables para tal impresion
        					    if( strrpos ( $registro_botones["imagen"], "_TEXTOIZQ_" )!==false)
						            $Cadena_BotonIzq=$registro_botones["titulo"]." ";
					            //Si se detecta el texto a la derecha ajusta las variables para tal impresion
        					    if( strrpos ( $registro_botones["imagen"], "_TEXTODER_" )!==false)
						            $Cadena_BotonDer=" ".$registro_botones["titulo"];
					        }
					}
                $Cadena_BotonIzq=PCO_ReemplazarVariablesPHPEnCadena($Cadena_BotonIzq);
                $Cadena_BotonDer=PCO_ReemplazarVariablesPHPEnCadena($Cadena_BotonDer);
				@$cadena_generica_botones.='<button type="button" class="'.$registro_botones["estilo"].'" '.$Cadena_Ayuda.' '.$cadena_javascript.'>'.$Cadena_BotonIzq.$Cadena_Imagen.$Cadena_BotonDer.'</button>&nbsp;';
			}
		return $cadena_generica_botones;
	}


########################################################################
########################################################################
/*
	Function: PCO_DeterminarCamposOcultos
	Devuelve la lista de campos establecidos como ocultos para un informe determinado

	Variables de entrada:

		informe - ID unico del informe del cual se desea conocer los campos ocultos

	Salida:

		Arreglo con la lista de campos ocultos

	Ver tambien:
		<PCO_CargarInforme>
*/
function PCO_DeterminarCamposOcultos($informe)
	{
		global $TablasCore;
		// Carga variables de definicion de tablas
		global $ListaCamposSinID_informe_campos;

		//Busca los CAMPOS definidos para el informe
		$consulta_campos=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_informe_campos." FROM ".$TablasCore."informe_campos WHERE informe=? ORDER BY peso","$informe");

		$PCO_ColumnasOcultas=array();
		while ($registro_campos = $consulta_campos->fetch())
			{
				//Si tiene alias definido lo agrega
				$posfijo_campo="";
				if ($registro_campos["valor_alias"]!="") $posfijo_campo=" as ".$registro_campos["valor_alias"];
				//Agrega al arreglo con los campos marcados como ocultos
				if ($registro_campos["visible"]==0)
					{
						$PCO_ColumnasOcultas[]=$registro_campos["valor_campo"].$posfijo_campo;
						//Lleva el campo oculto despues del punto
						$PCO_PartesCampo=explode(".",$registro_campos["valor_campo"].$posfijo_campo);
						@$PCO_ColumnasOcultas[]=$PCO_PartesCampo[1];
						//Lleva el campo oculto si es un alias
						$PCO_PartesCampo=explode(" as ",$registro_campos["valor_campo"].$posfijo_campo);
						$PCO_ColumnasOcultas[]=$PCO_PartesCampo[1];
					}
			}
		return $PCO_ColumnasOcultas;
	}


########################################################################
########################################################################
/*
	Function: PCO_ConstruirConsultaInforme
	Genera el codigo SQL correspondiente a informe especifico por ID, es la consulta cruda de los datos para ser aplicada posteriormente a otra operacion

	Variables de entrada:

		informe - ID unico del informe del cual se desea construir el query
		evitar_campos_ocultos - Determina si los campos ocultos son agregados o no dentro del query.  Util cuando no se desean dentro de informes exportados.

	Salida:

		SQL con el query requerido por el informe

	Ver tambien:
		<PCO_CargarInforme>
*/
function PCO_ConstruirConsultaInforme($informe,$evitar_campos_ocultos=0)
	{
		global $ConexionPDO,$ArchivoCORE,$TablasCore,$PCO_ValorBusquedaBD,$PCO_CampoBusquedaBD;
		// Carga variables de sesion por si son comparadas en alguna condicion.  De todas formas pueden ser cargadas por el usuario en el diseno del informe
		global $PCOSESS_LoginUsuario,$Nombre_usuario,$Descripcion_usuario,$Nivel_usuario,$Correo_usuario,$LlaveDePasoUsuario,$PCO_FechaOperacion;
		// Carga variables de definicion de tablas
		global $ListaCamposSinID_informe,$ListaCamposSinID_informe_campos,$ListaCamposSinID_informe_tablas,$ListaCamposSinID_informe_condiciones,$ListaCamposSinID_informe_boton;

		//Si se desea evitar los campos ocultos entonces los busca
		if ($evitar_campos_ocultos==1)
			$PCO_ColumnasOcultas=PCO_DeterminarCamposOcultos($informe);

			// Inicia CONSTRUCCION DE CONSULTA DINAMICA
			$numero_columnas=0;
			//Busca los CAMPOS definidos para el informe
			$consulta="SELECT ";
			$consulta_campos=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_informe_campos." FROM ".$TablasCore."informe_campos WHERE informe=? ORDER BY peso,id","$informe");

			while ($registro_campos = $consulta_campos->fetch())
				{
					//Si tiene alias definido lo agrega
					$posfijo_campo="";
					if ($registro_campos["valor_alias"]!="") $posfijo_campo=" as ".$registro_campos["valor_alias"];

					$OrigenValorCampo=$registro_campos["valor_campo"];
					//Evalua casos donde se tienen variables PHP escapadas por llaves.  Ej  "%{$Variable}%" si fuera para una operacion cualquiera sobre el campo.
                    $OrigenValorCampo=PCO_ReemplazarVariablesPHPEnCadena($OrigenValorCampo);
					$nombre_campo=$OrigenValorCampo.$posfijo_campo;
					
					//Compatibilidad PHP 8+.  Si no recibe nada lo convierte a array para garantizar el tipo en in_array
					if (gettype($PCO_ColumnasOcultas)!="array")
					    $PCO_ColumnasOcultas=array();

					//Agrega el campo a la consulta si no se encuentra en el arreglo de ocultos o no se quieren evitar esos campos
					if (@!in_array($nombre_campo,$PCO_ColumnasOcultas) || $evitar_campos_ocultos==0)
						$consulta.=$nombre_campo.",";
				}

			// Elimina la ultima coma en el listado de campos
			$consulta=substr($consulta, 0, strlen($consulta)-1);

			//Busca las TABLAS definidas para el informe
			$consulta.=" FROM ";
			$consulta_tablas=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_informe_tablas." FROM ".$TablasCore."informe_tablas WHERE informe=? ","$informe");
			while ($registro_tablas = $consulta_tablas->fetch())
				{
					//Si tiene alias definido lo agrega
					$posfijo_tabla="";
					if ($registro_tablas["valor_alias"]!="") $posfijo_tabla=" as ".PCO_ReemplazarVariablesPHPEnCadena($registro_tablas["valor_alias"]);
					//Agrega tabla a la consulta
					$consulta.=PCO_ReemplazarVariablesPHPEnCadena($registro_tablas["valor_tabla"]).$posfijo_tabla.",";
				}
			// Elimina la ultima coma en el listado de tablas
			$consulta=substr($consulta, 0, strlen($consulta)-1);

			// Busca las CONDICIONES para el informe
			$consulta.=" WHERE ";
			$consulta_condiciones=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_informe_condiciones." FROM ".$TablasCore."informe_condiciones WHERE informe=? ORDER BY peso,id","$informe");
			$hay_condiciones=0;
			while ($registro_condiciones = $consulta_condiciones->fetch())
				{
					//Agrega condicion a la consulta
					$valor_izquierdo=$registro_condiciones["valor_izq"];
					$valor_derecho=$registro_condiciones["valor_der"];
					//Evalua casos donde se tienen variables PHP escapadas por llaves.  Ej  "%{$Variable}%" si fuera para un LIKE, por ejemplo.
                    $valor_izquierdo=PCO_ReemplazarVariablesPHPEnCadena($valor_izquierdo);
                    $valor_derecho=PCO_ReemplazarVariablesPHPEnCadena($valor_derecho);

					$consulta.=" ".$valor_izquierdo." ".$registro_condiciones["operador"]." ".$valor_derecho." ";
					$hay_condiciones=1;
				}
			if (!$hay_condiciones)
			$consulta.=" 1 ";

			//Busca si debe ser ordenado o agrupado
			$registro_informe=PCO_EjecutarSQL("SELECT agrupamiento,ordenamiento FROM ".$TablasCore."informe WHERE id=? ","$informe")->fetch();
			if (@$registro_informe["agrupamiento"]!="")
				{
					$campoagrupa=$registro_informe["agrupamiento"];
					$consulta.= " GROUP BY $campoagrupa";
				}

			if (@$registro_informe["ordenamiento"]!="")
				{
					$campoorden=$registro_informe["ordenamiento"];
					$consulta.= " ORDER BY $campoorden";
				}

		return $consulta;
	}


########################################################################
########################################################################
/*
	Function: PCO_GenerarEtiquetasConsulta
	Genera una lista separadas por coma con las etiqeutas asociadas a un query SQL

	Variables de entrada:

		ConsultaSQL - La consulta en SQL que generara las etiquetas
		informe - Si se recibe un ID de informe lo usa para conoecr sus columnas ocultas

	Salida:

		* Variable de tipo arreglo con los Resultados para ColumnasVisibles, NumerosColumnasOcultas y NumeroColumnas

	Ver tambien:
		<PCO_CargarInforme>
*/
function PCO_GenerarEtiquetasConsulta($ConsultaSQL,$informe)
	{
		global $ConexionPDO,$ArchivoCORE,$TablasCore,$PCO_ValorBusquedaBD,$PCO_CampoBusquedaBD;
		// Carga variables de sesion por si son comparadas en alguna condicion.  De todas formas pueden ser cargadas por el usuario en el diseno del informe
		global $ListaCamposSinID_informe,$ListaCamposSinID_informe_campos,$ListaCamposSinID_informe_tablas,$ListaCamposSinID_informe_condiciones,$ListaCamposSinID_informe_boton;

        $PCO_ColumnasVisibles=array();
        $PCO_NumerosColumnasOcultas=array();

		// Busca datos del informe
        if ($informe!="")
        	$registro_informe=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_informe." FROM ".$TablasCore."informe WHERE id=? ","$informe")->fetch();

        //Si encuentra que el informe usa conexion alterna accesa la variable de conexion como global
        if($registro_informe["conexion_origen_datos"]!="")
    		global ${$registro_informe["conexion_origen_datos"]};

		//Averigua cuales columnas estan definidas como ocultas
		if ($informe!="")
			$ColumnasOcultas=PCO_DeterminarCamposOcultos($informe);

		//Si se recibe un query sigue adelante
		if ($ConsultaSQL!="")
			{
				// Imprime encabezados de columna si encuentra al menos un registro
                //Si el informe usa una conexion externa usa su configuracion
                if($registro_informe["conexion_origen_datos"]!="")
                    $resultado_columnas=@PCO_EjecutarSQL($ConsultaSQL,"",${$registro_informe["conexion_origen_datos"]},1); //${$registro_informe["conexion_origen_datos"]}
                else
                    $resultado_columnas=@PCO_EjecutarSQL($ConsultaSQL);

				//Procesa resultados solo si es diferente de 1 que es el valor retornado cuando hay errores evitando el fatal error del fetch(), rowCount() y demas metodos
				if ($resultado_columnas!="1")
					$ConteoRegistros=$resultado_columnas->rowCount();

				//Si se tienen registros para mirar las columnas las agrega
				if ($ConteoRegistros>0)
					{
                        $numero_columnas=0;
                        foreach($resultado_columnas->fetch(PDO::FETCH_ASSOC) as $key=>$val)
                            {
                                //Imprime el encabezado siempre y cuando no se trate de un campo que se desea ocultar
                                if (!in_array($key,$ColumnasOcultas))
									{
										$PCO_ColumnasVisibles[]=$key;
									}
								else
									{
										//Agrega la columna al indice de columnas ocultas para no mostrarla luego
										$PCO_NumerosColumnasOcultas[]=$numero_columnas;
									}
								$numero_columnas++;
                            }
                    }
			}
		@$Resultados[]=array("ColumnasVisibles" => $PCO_ColumnasVisibles, "NumerosColumnasOcultas"=>$PCO_NumerosColumnasOcultas	,"NumeroColumnas" => $numero_columnas);
		return $Resultados;
	}


########################################################################
########################################################################
/*
	Function: PCO_CamposRealesInforme
	Retorna un arreglo con nombres de campos completos, sus nombres reales en base de datos y los nombres de las tablas correspondientes

	Variables de entrada:

		informe - ID de informe lo usa para conocer todas sus columnas

	Salida:

		* Variable de tipo arreglo con los Resultados

	Ver tambien:
		<PCO_CargarInforme>
*/
function PCO_CamposRealesInforme($informe)
	{
		global $ConexionPDO,$ArchivoCORE,$TablasCore;
		global $ListaCamposSinID_informe,$ListaCamposSinID_informe_campos,$ListaCamposSinID_informe_tablas;

		// Busca datos del informe
        if ($informe!="")
            {
        		$consulta_informe=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_informe." FROM ".$TablasCore."informe WHERE id=? ","$informe");
        		$registro_informe=$consulta_informe->fetch();

        		if ($registro_informe["conexion_origen_datos"]!="")
        		    global ${$registro_informe["conexion_origen_datos"]};
            }

			//Busca los CAMPOS definidos para el informe y sus TABLAS correspondientes
			$ListaCampos_NombreCompleto=array();	//Nombre completo del campo
			$ListaCampos_NombreSimple=array();		//Lado izquierdo solamente cuando se cuenta con Alias
			$ListaTablas_NombreSimple=array();		//Nombre de la tabla de donde sale el campo
			$ListaCampos_PermitirEdicion=array();	//Guarda los estados de edicion en linea para el campo
			$consulta_campos=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_informe_campos." FROM ".$TablasCore."informe_campos WHERE informe=? ORDER BY peso,id","$informe");
			while ($registro_campos = $consulta_campos->fetch())
				{
					//Si tiene alias definido lo agrega
					$posfijo_campo="";
					if ($registro_campos["valor_alias"]!="") $posfijo_campo=" as ".$registro_campos["valor_alias"];
					$nombre_campo=$registro_campos["valor_campo"].$posfijo_campo;

					//Agrega el campo a la lista de nombres completos
					$ListaCampos_NombreCompleto[]=$nombre_campo;

					//Agrega el estado de edicion o no para el campo
					$ListaCampos_PermitirEdicion[]=$registro_campos["editable"];

					//Establece el nombre del campo simple (el real en base de datos)
						//Elimina la posibilidad de un alias " as " tomando la primera parte solamente
						$PartesListaCampos_NombreCompleto=explode(" as ",$nombre_campo);
						$nombre_campo_simple=$PartesListaCampos_NombreCompleto[0];
						//Elimina la posibilidad de un punto " . " indicando la tabla
						if (strpos($nombre_campo_simple,"."))
							{
								$PartesListaCampos_NombreCompleto=explode(".",$nombre_campo_simple);
								$nombre_campo_simple=$PartesListaCampos_NombreCompleto[1];
							}

					//Agrega el campo a la lista de nombres simples
					$ListaCampos_NombreSimple[]=$nombre_campo_simple;

					//Determina la tabla a la que pertenece el campo
					//Se verifica inicialmente si el campo ya indica la tabla para evitar ambiguedades en consultas de varias tablas
					$PartesListaCampos_NombreCompleto=explode(" as ",$nombre_campo);
					$nombre_campo_simple=$PartesListaCampos_NombreCompleto[0];
					//Si el campo tiene puntos indica la tabla, sino la buscamos
					if (strpos($nombre_campo_simple,"."))
						{
							$PartesListaCampos_NombreCompleto=explode(".",$nombre_campo_simple);
							$nombre_tabla_simple=$PartesListaCampos_NombreCompleto[0];
							$ListaTablas_NombreSimple[]=$nombre_tabla_simple;
						}
					else
						{
							$nombre_tabla_simple="";
							//Busca en las TABLAS definidas para el informe
							$consulta_tablas=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_informe_tablas." FROM ".$TablasCore."informe_tablas WHERE informe=? ","$informe");
							while ($registro_tablas = $consulta_tablas->fetch())
								{
									$tabla_actual=$registro_tablas["valor_tabla"];
									//Si la tabla tiene alias lo ignora
									if (strpos($tabla_actual," as "))
										{
											$PartesTablaActual=explode(" as ",$tabla_actual);
											$tabla_actual=$PartesTablaActual[0];
										}
									//Si no se ha encontrado la tabla entra a comparar frente a la actual
									if ($nombre_tabla_simple=="")
										{
                                            //Si el informe usa una conexion externa usa su configuracion
                                            if($registro_informe["conexion_origen_datos"]!="")
                                                {
                            						if (@PCO_ExisteCampoTabla($nombre_campo_simple,$tabla_actual,${$registro_informe["conexion_origen_datos"]},$registro_informe["motorbd"],$registro_informe["basedatos"]))
                            							$nombre_tabla_simple=$tabla_actual;
                                                }
                                            else
                                                {
                            						if (PCO_ExisteCampoTabla($nombre_campo_simple,$tabla_actual))
                            							$nombre_tabla_simple=$tabla_actual;
                                                }
										}
								}
							$ListaTablas_NombreSimple[]=$nombre_tabla_simple;
						}
				}

		@$Resultados[]=array("ListaCampos_NombreCompleto" => $ListaCampos_NombreCompleto, "ListaCampos_NombreSimple"=>$ListaCampos_NombreSimple	,"ListaTablas_NombreSimple" => $ListaTablas_NombreSimple, "ListaCampos_PermitirEdicion" => $ListaCampos_PermitirEdicion);
		return $Resultados;
	}


########################################################################
########################################################################
/*
	Function: PCO_CargarInforme
	Genera el codigo HTML correspondiente a un informe de la aplicacion y hace los llamados necesarios para la diagramacion por pantalla de los diferentes objetos que lo componen.

	Variables de entrada:

		informe - ID unico del informe que se desea cargar
		en_ventana - Indica si el informe debe ser cargado en una ventana o directamente sobre el escritorio de aplicacion
		formato - Determina el formato en el cual es generado el informe como HTM o XLS (Alpha)
		estilo - Determina el estilo CSS utilizado para presentar el informe, debe existir dentro de las hojas de estilo de la plantilla
		embebido - Determina si el informe es presentado dentro de otro objeto o no, como por ejemplo un formulario

	(start code)
		SELECT * FROM ".$TablasCore."informe WHERE id='$informe'
		SELECT * FROM ".$TablasCore."informe_campos WHERE informe='$informe'
		SELECT * FROM ".$TablasCore."informe_tablas WHERE informe='$informe'
		SELECT * FROM ".$TablasCore."informe_condiciones WHERE informe='$informe' ORDER BY peso
	(end)

	Salida:

		HTML, CSS y Javascript asociado al formulario

	Ver tambien:
		<PCO_CargarFormulario> | <PCO_ConstruirConsultaInforme>
*/
    //Funcion para compatibilidad hacia atras.  Desaparecera en la version 18.9
    function cargar_informe($informe,$en_ventana=1,$formato="htm",$estilo="Informes",$embebido=0)
    { echo "ERROR: Llamado a funcion obsoleta del framework cargar_informe().  En su lugar utilice PCO_CargarInforme() "; }
function PCO_CargarInforme($informe,$en_ventana=1,$formato="htm",$estilo="Informes",$embebido=0,$anular_acciones=0,$anular_piepagina=0,$anular_encabezado=0,$SQLPuro="")
	{
		global $ConexionPDO,$ArchivoCORE,$TablasCore,$Nombre_Aplicacion,$PCO_ValorBusquedaBD,$PCO_CampoBusquedaBD;
		// Carga variables de sesion por si son comparadas en alguna condicion.  De todas formas pueden ser cargadas por el usuario en el diseno del informe
		global $PCOSESS_LoginUsuario,$Nombre_usuario,$Descripcion_usuario,$Nivel_usuario,$Correo_usuario,$LlaveDePasoUsuario,$PCO_FechaOperacion;
		// Carga variables de definicion de tablas
		global $ListaCamposSinID_replicasbd,$ListaCamposSinID_informe,$ListaCamposSinID_informe_campos,$ListaCamposSinID_informe_tablas,$ListaCamposSinID_informe_condiciones,$ListaCamposSinID_informe_boton;
		global $MULTILANG_Editar,$MULTILANG_Informes,$MULTILANG_Exportar,$MULTILANG_TotalRegistros,$MULTILANG_ContacteAdmin,$MULTILANG_ObjetoNoExiste,$MULTILANG_ErrorTiempoEjecucion,$MULTILANG_Informes,$MULTILANG_IrEscritorio,$MULTILANG_ErrorDatos,$MULTILANG_InfErrTamano,$MULTILANG_MonCommSQL;
		global $IdiomaPredeterminado;
        global $PCO_InformesListaColumnasDT,$PCO_InformesRecuperacionAJAX,$PCO_InformesIdCache,$PCO_InformesDataTable,$PCO_InformesDataTablePaginaciones,$PCO_InformesDataTableTotales,$PCO_InformesDataTableFormatoTotales,$PCO_InformesDataTableExrpotaCLP,$PCO_InformesDataTableExrpotaCSV,$PCO_InformesDataTableExrpotaXLS,$PCO_InformesDataTableExrpotaPDF,$PCO_InformesDataTableDefineCOLS,$PCO_InformesDataTable_pane_activado,$PCO_InformesDataTable_pane_cascada,$PCO_InformesDataTable_pane_colapsado,$PCO_InformesDataTable_pane_columnas,$PCO_InformesDataTable_pane_subtotalesrelativos,$PCO_InformesDataTable_pane_conteos,$PCO_InformesDataTable_pane_controles,$PCO_InformesDataTable_pane_control_colapsar,$PCO_InformesDataTable_pane_control_ordenar;
        global $ModoDepuracion,$ModoDesarrolladorPractico;
        global $PCO_InformesGraficosSinDatos,$PCOVAR_ConteoRegistrosUltimoInforme;
        global $PCO_FuncionesJSInternasFORM;
        
        //Determina si el usuario es un disenador de aplicacion para mostrar el ID de objeto a manera informativa y un boton de salto a edicion
        $BotonSaltoEdicion='
                    <a class="btn btn-default btn-xs" href="index.php?PCO_Accion=PCO_EditarInforme&informe='.$informe.'">
                        <div><i class="fa fa-pencil-square"></i> '.$MULTILANG_Editar.' '.$MULTILANG_Informes.' <i>[ID='.$informe.']</i></div>
                    </a>';

        if ($SQLPuro=="")
            {
        		if (PCO_EsAdministrador($_SESSION['PCOSESS_LoginUsuario']) && $informe>=0)
        		    $ComplementoIdObjetoEnTitulo="  $BotonSaltoEdicion";

        		// Busca datos del informe
        		$consulta_informe=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_informe." FROM ".$TablasCore."informe WHERE id=? ","$informe");
        		$registro_informe=$consulta_informe->fetch();
        		$Identificador_informe=$registro_informe["id"];

        		//Carga cualquier script PRE para el informe
        		if ($registro_informe["pre_script"]!="")
        		    {
        		        //Evalua si el codigo ya inicia con <?php y sino lo agrega
        		        $ComplementoInicioScript="";
        		        if (substr(trim($registro_informe["pre_script"]),0,5)!='<?php')
        		            $ComplementoInicioScript="<?php\n";
        		        PCO_EvaluarCodigo($ComplementoInicioScript.$registro_informe["pre_script"],1,"Detalles: PRE-Code Rep ID=".$informe);
        		    }

        		//Prepara script POST para el informe (se carga mas abajo pero deja la cadena lista)
        		if ($registro_informe["post_script"]!="")
        		    {
        		        //Evalua si el codigo ya inicia con <?php y sino lo agrega
        		        $ComplementoInicioScript="";
        		        if (substr(trim($registro_informe["post_script"]),0,5)!='<?php')
        		            $ComplementoInicioScript="<?php\n";
        		        $CadenaPOSTScriptPHP=$ComplementoInicioScript.$registro_informe["post_script"];
        		    }

        		//Prepara JavaSCRIPT para el informe (se carga mas abajo pero deja la cadena lista)
        		if (trim($registro_informe["javascript"])!="")
        		    {
                        $JavaScriptInforme=PCO_ReemplazarVariablesPHPEnCadena(trim($registro_informe["javascript"]));
        		    }
            }

        //Determina si se deben ocultar elementos por banderas o porque el informe asi lo obliga
        $ComplementoAnulacionPiePagina='';
        if ($anular_piepagina==1 || $registro_informe["ocultar_piepagina"]==1) $ComplementoAnulacionPiePagina=' style="display:none; visibility:hidden;" ';
        $ComplementoAnulacionEncabezado='';
        if ($anular_encabezado==1 || $registro_informe["ocultar_encabezado"]==1) $ComplementoAnulacionEncabezado=' style="display:none; visibility:hidden;" ';
        if ($anular_acciones==0 && $registro_informe["anular_acciones"]==1) $anular_acciones=1;

        if ($SQLPuro=="")
            {
                //Si el informe usa una conexion externa busca su configuracion
                if($registro_informe["conexion_origen_datos"]!="")
                    {
        		        $registro_conexiones=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_replicasbd." FROM ".$TablasCore."replicasbd WHERE nombre='".$registro_informe["conexion_origen_datos"]."' ")->fetch();
                    	global ${$registro_conexiones["nombre"]};
                    	$NombreConexionExtra=${$registro_conexiones["nombre"]};
                    }
        		//Si no encuentra informe presenta error
        		if ($registro_informe["id"]=="") PCO_Mensaje($MULTILANG_ErrorTiempoEjecucion,$MULTILANG_ObjetoNoExiste." ".$MULTILANG_ContacteAdmin."<br>(".$MULTILANG_Informes." $informe)", '', 'fa fa-times fa-5x icon-red texto-blink', 'alert alert-danger alert-dismissible');
            }

		//Identifica si el informe requiere un formulario de filtrado previo
		if ($registro_informe["formulario_filtrado"]!="")
			{
				//Determina si solicita el informe desde el formulario de filtrado apropiado, sino redirecciona a este
				global $PCO_FormularioActivo;
				if ($registro_informe["formulario_filtrado"]!=$PCO_FormularioActivo)
					{
						echo '<form name="precarga_form_filtro" action="'.$ArchivoCORE.'" method="POST" target="_self">
							<input type="Hidden" name="PCO_Accion" value="PCO_CargarObjeto">
							<input type="Hidden" name="PCO_InformeFiltro" value="'.$registro_informe["id"].'">
							<input type="Hidden" name="PCO_Objeto" value="frm:'.$registro_informe["formulario_filtrado"].':1">
							<input type="Hidden" name="Presentar_FullScreen" value="'.@$Presentar_FullScreen.'">
							<input type="Hidden" name="Precarga_EstilosBS" value="'.@$Precarga_EstilosBS.'">
							</form>
						<script type="" language="JavaScript"> document.precarga_form_filtro.submit();  </script>';
						die();
					}
			}

		//Si hay variables de filtro definidas busca su valor en el contexto global
		if($registro_informe["variables_filtro"]!="")
			{
				$arreglo_variables_filtro = @explode(",",$registro_informe["variables_filtro"]);
				//Busca y convierte cada variable recibida en global
				foreach ($arreglo_variables_filtro as $nombre_variable_filtro)
					{
						//if (isset(${$nombre_variable_filtro}))  // {Deprecated}
							global ${$nombre_variable_filtro};
					}
			}

		//Si no hay SQL explicito entonces Genera la consulta en SQL para el informe a partir de los parametros
		if (strlen($registro_informe["consulta_sql"])<5)
		    {
		        if ($SQLPuro=="")
    		        $consulta=PCO_ConstruirConsultaInforme($informe,0); //Construye query del informe sin evitar campos ocultos (0)
		        else
		            $consulta=PCO_ReemplazarVariablesPHPEnCadena($SQLPuro);
		    }
		else
		    $consulta=PCO_ReemplazarVariablesPHPEnCadena($registro_informe["consulta_sql"]);

		// Si el informe tiene formato_final = T (tabla de datos)
		if ($registro_informe["formato_final"]=="T" || $SQLPuro!="")
			{
				$SalidaFinalInforme='';
				if ($en_ventana)
					{
						//Cuando es embebido (=1) no imprime el boton de retorno pues se asume dentro de un formulario
						if (!$embebido)
							echo '<div align=center id="PCOContenedor_BotonEscritorio"><button type="Button" onclick="document.PCO_FormVerMenu.submit()" class="btn btn-warning"><i class="fa fa-home fa-fw"></i> '.$MULTILANG_IrEscritorio.'</button></div><br>';

						$TituloVentanaInforme=PCO_ReemplazarVariablesPHPEnCadena($registro_informe["titulo"]);
						//Define si requiere o no boton de exportacion en la barra de titulo
						if ($registro_informe["genera_pdf"]!='N' && $embebido!=1)
							{
							    //Formato nativo
    				            if ($registro_informe["genera_pdf"]=='S' || $registro_informe["genera_pdf"]=='A')
                                    {
        								$TituloVentanaInforme='
        								<a class="btn btn-primary btn-xs pull-right" data-toggle="modal" href="#myModalEXPORTACION">
        									<div><i class="fa fa-floppy-o fa-fw"></i> '.$MULTILANG_Exportar.'</div>
        								</a>'.$TituloVentanaInforme;
                                    }
							}

						//Define si requiere o no boton de exportacion en la barra de titulo
					    //Formato CSV por AJAX - Solo genera el marco, el boton se agrega luego cuando se conozca el ID de la cache de informe (mas abajo)
			            if ($registro_informe["genera_pdf"]=='C' || $registro_informe["genera_pdf"]=='A')
                            {
								$TituloVentanaInforme='<div id="PCO_MarcoBotonCSVInforme'.$informe.'" class="pull-right" style="margin-left:5px;"></div>'.$TituloVentanaInforme;
                            }

						//Carga la ventana con el informe
						PCO_AbrirVentana($TituloVentanaInforme.$ComplementoIdObjetoEnTitulo,'panel panel-info',$registro_informe["ancho"]);

						//Agrega la descripcion del informe en caso de contar con ella
						if ($registro_informe["descripcion"]!='')
							{
								 PCO_Mensaje('<i class="fa fa-flag fa-fw"></i>',PCO_ReemplazarVariablesPHPEnCadena($registro_informe["descripcion"]), '', '', 'alert alert-success alert-dismissible');
							}
					}

				// Si se ha definido un tamano fijo entonces crea el marco
				if ($registro_informe["ancho"]!="" && $registro_informe["alto"]!="")
					echo '<DIV style="DISPLAY: block; OVERFLOW: auto; POSITION: relative; WIDTH: '.$registro_informe["ancho"].' !important; HEIGHT: '.$registro_informe["alto"].' !important">';

				//Genera enlaces a las opciones de descarga
				if (($registro_informe["genera_pdf"]=='S' || $registro_informe["genera_pdf"]=='A')  && $embebido!=1)
					include_once("core/marco_export.php");

					//DEPRECATED echo '	<html>		<body leftmargin="0" topmargin="0" rightmargin="0" bottommargin="0" marginwidth="0" marginheight="0" style="font-size: 12px; font-family: Arial, Verdana, Tahoma;">';

                    //Agrega titulo o encabezado si esta definido
                    if ( $registro_informe["encabezado_html"] != '' )
                        $SalidaFinalInforme.= '<div id="titulo-informe-ID'.$registro_informe["id"].'">'.PCO_ReemplazarVariablesPHPEnCadena($registro_informe["encabezado_html"]).'</div>';

                    //Agrega clases para convertir la tabla a responsive si aplica
                    $ComplementoResponsiveTabla='';
                    if ( $registro_informe["tabla_responsive"] == 'S' )
                        $ComplementoResponsiveTabla= 'responsive nowrap';

					$SalidaFinalInforme.= '<!--<div class="table-responsive">-->
											<table width="100%" class="btn-xs table table-condensed table-hover order-column table-striped table-unbordered  '.$ComplementoResponsiveTabla.'  '.$estilo.' d-flex" id="TablaInforme_'.$registro_informe["id"].'"><thead id="PCO_EncabezadosInforme_'.$registro_informe["id"].'" '.$ComplementoAnulacionEncabezado.'>';

					//Busca si tiene acciones (botones) para cada registro y los genera
					if (!$anular_acciones)
					    {
    					    $cadena_generica_botones_principio=PCO_GenerarBotonesInforme($informe,1);
    					    $cadena_generica_botones=PCO_GenerarBotonesInforme($informe);
					    }
					else
					    {
					        $cadena_generica_botones_principio='';
					        $cadena_generica_botones="";
					    }

					//Si el informe tiene botones al comienzo entonces agrega columna adicional
					if ($cadena_generica_botones_principio!="")
						{
							$SalidaFinalInforme.= '<th></th>';
						}

					//Determina si el informe tiene o no campos ocultos
					$PCO_ColumnasOcultas=PCO_DeterminarCamposOcultos($informe);

					//Obtiene ColumnasVisibles, NumerosColumnasOcultas, NumeroColumnas dentro de EtiquetasConsulta
					$EtiquetasConsulta=PCO_GenerarEtiquetasConsulta($consulta,$informe); //Enviar el informe para que se determinen tambien sus columnas ocultas

					//Genera HTML con las columnas
                    //Busca los campos definidos en el informe como visibles y luego determina si el campo tiene o no titulo arbitrario
        			$ListaCampos_TitutloArbitrario=array();
        			$consulta_titulosarbitrarios=PCO_EjecutarSQL("SELECT id,".$ListaCamposSinID_informe_campos." FROM ".$TablasCore."informe_campos WHERE informe=? AND visible=1 ORDER BY peso,id","$informe");
        			while ($registro_titulosarbitrarios = $consulta_titulosarbitrarios->fetch())
        					$ListaCampos_TitutloArbitrario[]=$registro_titulosarbitrarios["titulo_arbitrario"];
				    $ConteoPosicionColumna=0;   //Utilizado para conocer la columna actual y luego buscar si tiene titulo arbitrario
					$ListaColumnasInforme="";   //Acumula las columnas para ser usadas luego en los DataTables (si aplica)
					foreach($EtiquetasConsulta[0]["ColumnasVisibles"] as $EtiquetaColumna)
					    {
					        $TituloFinalColumna=$EtiquetaColumna;
					        //Si la columna actual tiene un titulo arbitrario definido entonces lo agrega
					        if (@$ListaCampos_TitutloArbitrario[$ConteoPosicionColumna]!="")
                                $TituloFinalColumna=PCO_ReemplazarVariablesPHPEnCadena($ListaCampos_TitutloArbitrario[$ConteoPosicionColumna]);
						    $SalidaFinalInforme.= '<th>'.$TituloFinalColumna.'</th>';
						    $ListaColumnasInforme.=$TituloFinalColumna.',';
						    $ConteoPosicionColumna++;
					    }
					$ListaColumnasInforme=substr($ListaColumnasInforme, 0, -1);//Elimina la coma sobrante del informe
					//Si el informe tiene botones al final entonces agrega columna adicional
					if ($cadena_generica_botones!="")
						{
							$SalidaFinalInforme.= '<th></th>';
						}
					$SalidaFinalInforme.= '</tr></thead><tbody>';

					//Busca los campos y tablas reales del informe para construir luego los ID unicos
					$CamposReales=PCO_CamposRealesInforme($informe);

					// Imprime registros del resultado
					$numero_filas=0;

                    //Si el informe usa una conexion externa usa su configuracion
                    if($registro_informe["conexion_origen_datos"]!="")
                        $consulta_ejecucion=PCO_EjecutarSQL($consulta,"",${$registro_conexiones["nombre"]});
                    else
                        $consulta_ejecucion=PCO_EjecutarSQL($consulta);
                        
                    //Asigna el total dde registros a variable global para posible uso fuera de la funcion
                    $PCOVAR_ConteoRegistrosUltimoInforme=$consulta_ejecucion->rowCount();

                    //Lleva informe a la cache siempre y cuando no sea un informe interno del framework
                    $IdCacheInformes=0;
                    PCO_EjecutarSQLUnaria("INSERT INTO {$TablasCore}informe_cache (informe,usuario,conexion,script_sql,columnas) VALUES('{$informe}','{$PCOSESS_LoginUsuario}','{$NombreConexionExtra}',?,'{$ListaColumnasInforme}') ","{$consulta}");
                    $IdCacheInformes=PCO_ObtenerUltimoIDInsertado();

                    //Ahora que se tiene una cache, determina si se requiere boton de exportacion CSV por AJAX y lo agrega
		            if ($registro_informe["genera_pdf"]=='C' || $registro_informe["genera_pdf"]=='A')
                        {
                            echo "<script language='JavaScript'>
                                $('#PCO_MarcoBotonCSVInforme{$informe}').html('<a class=\"btn btn-success btn-xs pull-right\" href=\"core/ajax.php?PCO_Accion=PCO_ExportacionQueryCacheCSV&amp;IdRegistro_CacheSQL={$IdCacheInformes}\"> <i class=\"fa fa-file-excel-o fa-fw\"></i> {$MULTILANG_Exportar} CSV </a>');
                            </script>";
                        }

					//Si el informe va a soportar datatable entonces lo agrega a las tablas que deben ser convertidas en el pageonload
					if ($registro_informe["soporte_datatable"]=="S")
					    {
						    @$PCO_InformesDataTable.="TablaInforme_".$registro_informe["id"]."|";
						    @$PCO_InformesDataTablePaginaciones.=$registro_informe["tamano_paginacion"]."|"; //Agrega tamano predefinido para la tabla
						    @$PCO_InformesDataTableTotales.=$registro_informe["subtotales_columna"]."|";
						    @$PCO_InformesDataTableFormatoTotales.=$registro_informe["subtotales_formato"]."|";
						    @$PCO_InformesDataTableExrpotaCLP.=$registro_informe["exportar_dtclp"]."|";
						    @$PCO_InformesDataTableExrpotaCSV.=$registro_informe["exportar_dtcsv"]."|";
						    @$PCO_InformesDataTableExrpotaXLS.=$registro_informe["exportar_dtxls"]."|";
						    @$PCO_InformesDataTableExrpotaPDF.=$registro_informe["exportar_dtpdf"]."|";
						    @$PCO_InformesDataTableDefineCOLS.=$registro_informe["definir_cols"]."|";
            	            @$PCO_InformesIdCache.=$IdCacheInformes."|";
                    	    @$PCO_InformesListaColumnasDT.=$ListaColumnasInforme."|";
						    @$PCO_InformesDataTable_pane_activado.=$registro_informe["pane_activado"]."|";
						    @$PCO_InformesDataTable_pane_cascada.=$registro_informe["pane_cascada"]."|";
						    @$PCO_InformesDataTable_pane_colapsado.=$registro_informe["pane_colapsado"]."|";
						    @$PCO_InformesDataTable_pane_columnas.=$registro_informe["pane_columnas"]."|";
						    @$PCO_InformesDataTable_pane_subtotalesrelativos.=$registro_informe["pane_subtotalesrelativos"]."|";
						    @$PCO_InformesDataTable_pane_conteos.=$registro_informe["pane_conteos"]."|";
						    @$PCO_InformesDataTable_pane_controles.=$registro_informe["pane_controles"]."|";
						    @$PCO_InformesDataTable_pane_control_colapsar.=$registro_informe["pane_control_colapsar"]."|";
						    @$PCO_InformesDataTable_pane_control_ordenar.=$registro_informe["pane_control_ordenar"]."|";
					    }

                    if ($registro_informe["usar_ajax"]==0)
                        {
                            //Define banderas para determinar si el informe se recupera por AJAX o no posteriormente en marco_abajo
                    	    if ($registro_informe["soporte_datatable"]=="S")
                    	        $PCO_InformesRecuperacionAJAX.="0"."|";
        
        					//Procesa resultados solo si es diferente de 1 que es el valor retornado cuando hay errores evitando el fatal error del fetch(), rowCount() y demas metodos
        					while($consulta_ejecucion!="1" && $registro_datos_informe=$consulta_ejecucion->fetch())
        						{
        							$SalidaFinalInforme.= '<tr>';
        
        							//Si el informe tiene botones al comienzo los agrega
        							if ($cadena_generica_botones_principio!="")
        								{
        									//Transforma la cadena generica con los datos especificos del registro, toma por ahora el primer campo (OCULTO O NO)
        									$cadena_botones_registro=str_replace("DELFRMVALVALOR",$registro_datos_informe[0],$cadena_generica_botones_principio);
        									$cadena_botones_registro=str_replace("DETFRMVALBASE",$registro_datos_informe[0],$cadena_botones_registro);
        									//Muestra los botones preparados para el registro
        									$SalidaFinalInforme.= '<td>'.$cadena_botones_registro.'</td>';
        								}
        
        							for ($i=0;$i<$EtiquetasConsulta[0]["NumeroColumnas"];$i++)
        								{
        									//Si no hay definidos numeros de columnas ocultas crea el arreglo vacio para compatibilidad PHP 8+
        									if (@!isset($EtiquetasConsulta[0]["NumerosColumnasOcultas"]))
        									    $EtiquetasConsulta[0]["NumerosColumnasOcultas"]=array();
        									
        									//Muestra la columna solo si no se trata de una de las ocultas
        									if (@!in_array($i,$EtiquetasConsulta[0]["NumerosColumnasOcultas"]))
        										{
        											$ValorCampoIdentificador=$registro_datos_informe[0]; //Toma por ahora el primer campo (OCULTO O NO)
        											$Nombre_CampoLlave=@$CamposReales[0]["ListaCampos_NombreSimple"][0]; //Toma por ahora el primer campo (OCULTO O NO)
        											$Nombre_CampoEditable=@$CamposReales[0]["ListaCampos_NombreSimple"][$i];
        											$Nombre_TablaEditable=@$CamposReales[0]["ListaTablas_NombreSimple"][$i];
        											$IdentificadorDeCampoEditable="$Nombre_TablaEditable:$Nombre_CampoEditable:$Nombre_CampoLlave:$ValorCampoIdentificador";
        
        											//Determina la activacion o no de la cadena de edicion del campo
        											$CadenaActivadora_Edicion="";
        											if (@$CamposReales[0]["ListaCampos_PermitirEdicion"][$i]==1)
        												$CadenaActivadora_Edicion=' id="'.$IdentificadorDeCampoEditable.'" contenteditable="true" ';
        
        											$ValorVisibleFinal=$registro_datos_informe[$i];
        											if ($ModoDesarrolladorPractico==1) $ValorVisibleFinal=PCO_ReemplazarVariablesPHPEnCadena($ValorVisibleFinal);
        
        											$SalidaFinalInforme.= '
        												<td '.$CadenaActivadora_Edicion.'>'.$ValorVisibleFinal.'</td>';
        										}
        								}
        
        							//Si el informe tiene botones al final los agrega
        							if ($cadena_generica_botones!="")
        								{
        									//Transforma la cadena generica con los datos especificos del registro, toma por ahora el primer campo (OCULTO O NO)
        									$cadena_botones_registro=str_replace("DELFRMVALVALOR",$registro_datos_informe[0],$cadena_generica_botones);
        									$cadena_botones_registro=str_replace("DETFRMVALBASE",$registro_datos_informe[0],$cadena_botones_registro);
        									//Muestra los botones preparados para el registro
        									$SalidaFinalInforme.= '<td>'.$cadena_botones_registro.'</td>';
        								}
        
        							$SalidaFinalInforme.= '</tr>';
        							$numero_filas++;
        						}
                        }
                    else
                        {
                            //Define banderas para determinar si el informe se recupera por AJAX o no posteriormente en marco_abajo
                    	    if ($registro_informe["soporte_datatable"]=="S")
                    	        $PCO_InformesRecuperacionAJAX.="1"."|";
                        }

					$SalidaFinalInforme.= '</tbody>';

					//Si se desea tabla responsive oculta el pie de pagina (libreria datatables no soporta responsive con tfooter ni recupareacion ajax con tfooter)
			        if ($registro_informe["tabla_responsive"] == 'N' &&  $registro_informe["usar_ajax"]=="0")
			            {
        					$SalidaFinalInforme.= '<tfoot id="PCO_PiePaginaInforme_'.$registro_informe["id"].'" '.$ComplementoAnulacionPiePagina.'>';
        					//Cuando es embebido (=1) no agrega los totales de registro
        					//if (!$embebido)
        					$CantidadColumnasSpan=$ConteoPosicionColumna-1;
        					@$SalidaFinalInforme.= '
        						<tr>
        						    <th colspan='.$CantidadColumnasSpan.'>
        							    <b>'.$MULTILANG_TotalRegistros.': </b>'.$numero_filas.'
        						    </th>
        						</tr>';
        					//Cierra pie de pagina, tabla y marco responsive para la tabla
        					$SalidaFinalInforme.= '</tfoot>';
			            }
					
					$SalidaFinalInforme.= '
							</table>
							<!--</div>-->';
				// DEPRECATED $SalidaFinalInforme.= '</body></html>';

				//Imprime el HTML generado para el informe
				echo $SalidaFinalInforme;

				// Si se ha definido un tamano fijo entonces cierra el marco
				if ($registro_informe["ancho"]!="" && $registro_informe["alto"]!="")
					echo '</DIV>';

			} // Fin si informe es T (tabla)

/*
		//Verifica si es un informe grafico sin dimensiones
		if ($registro_informe["formato_final"]=="G" && ( $registro_informe["ancho"]=="" || $registro_informe["alto"]=="" ))
			{
				echo '<form name="cancelarXTamano" action="'.$ArchivoCORE.'" method="POST">
					<input type="Hidden" name="PCO_Accion" value="PCO_VerMenu">
					<input type="Hidden" name="PCO_ErrorTitulo" value="'.$MULTILANG_ErrorDatos.'">
					<input type="Hidden" name="PCO_ErrorDescripcion" value="'.$MULTILANG_InfErrTamano.'">
					</form>
					<script type="" language="JavaScript"> document.cancelarXTamano.submit();  </script>';
			}
*/
		// Si el informe tiene formato_final = G (grafico)
		if ($registro_informe["formato_final"]=="G")
			{
				// Si se ha definido un tamano fijo entonces crea el marco
				if ($registro_informe["ancho"]!="" && $registro_informe["alto"]!="" && $registro_informe["ancho"]!="0" && $registro_informe["alto"]!="0")
					echo '<DIV style="DISPLAY: block; OVERFLOW: no; POSITION: relative; WIDTH: '.$registro_informe["ancho"].' !important; HEIGHT: '.$registro_informe["alto"].' !important">';

				//Consulta el formato de grafico y datos de series para ponerlo en los campos
				//Dado por: Tipo|Nombre1!NombreN|Etiqueta1!EtiquetaN|Valor1!ValorN|
				$formato_base=explode("|",$registro_informe["formato_grafico"]);
				$tipo_grafico=$formato_base[0];
				$lista_nombre_series=explode("!",$formato_base[1]);
				$lista_etiqueta_series=explode("!",$formato_base[2]);
				$lista_valor_series=explode("!",$formato_base[3]);
	            //Carga detalles extendidos para el formato de grafico y los corrige en el caso de graficos viejos
	            $barra_apilada=$formato_base[4];    if ($barra_apilada=="") $barra_apilada="false";
	            $ocultar_grilla=$formato_base[5];   if ($ocultar_grilla=="") $ocultar_grilla="false";
	            $ocultar_ejes=$formato_base[6];     if ($ocultar_ejes=="") $ocultar_ejes="false";
	            $unidades_pre=$formato_base[7];     if ($unidades_pre=="") $unidades_pre="";
	            $unidades_pos=$formato_base[8];     if ($unidades_pos=="") $unidades_pos="";
	            $barras_horizontales="false";  //Asume barras verticales por defecto
				if ($tipo_grafico=="barrah")  $barras_horizontales="true";
	            $tipo_grafico_circular="donut";  //Asume barras verticales por defecto
				if ($tipo_grafico=="torta" || $tipo_grafico=="tortap")  $tipo_grafico_circular="pie";
	            $presentar_porcentaje="false";  //Asume que el grafico no es con porcentajes en tortas
				if ($tipo_grafico=="donap" || $tipo_grafico=="tortap")  $presentar_porcentaje="true";

				$presentar_datalabels="false";  //Asume que no se presentan las etiquetas con valores de datos
				$cadenaubicacion_datalabels="";
				if($formato_base[9]!="false" && $formato_base[9]!="") $presentar_datalabels="true";
				if($formato_base[9]=="true_outside") $cadenaubicacion_datalabels="dataLabelsPosition: 'outside',";
				if($formato_base[9]=="true_inside") $cadenaubicacion_datalabels="dataLabelsPosition: 'inside',";

                $cadena_arreglo_colores="";
				if($formato_base[10]!="") $cadena_arreglo_colores="colors: ".$formato_base[10].",";

				//Elimina los nombres de tabla en caso de tener punto y usa los alias si los tiene
				for ($i=0;$i<5;$i++)
					{
						//Elimina nombres de tabla encontrando el punto y seleccionando siguiente palabra
						if (strpos($lista_etiqueta_series[$i], "."))
							{
								$tmp=explode(".",$lista_etiqueta_series[$i]);
								$lista_etiqueta_series[$i]=$tmp[1];
							}
						if (strpos($lista_valor_series[$i], "."))
							{
								$tmp=explode(".",$lista_valor_series[$i]);
								$lista_valor_series[$i]=$tmp[1];
							}
						// Prefiere los alias sobre los nombres de campo cuando encuentra un AS
						if (strpos($lista_etiqueta_series[$i], " AS "))
							{
								$tmp=explode(" AS ",$lista_etiqueta_series[$i]);
								$lista_etiqueta_series[$i]=$tmp[1];
							}
						if (strpos($lista_valor_series[$i], " AS "))
							{
								$tmp=explode(" AS ",$lista_valor_series[$i]);
								$lista_valor_series[$i]=$tmp[1];
							}
					}
				$nombre_serie_1=preg_replace('~[^a-zA-Z0-9_]~', '', str_replace ( " " , "_", $lista_nombre_series[0] ) );
				$nombre_serie_2=preg_replace('~[^a-zA-Z0-9_]~', '', str_replace ( " " , "_", $lista_nombre_series[1] ) );
				$nombre_serie_3=preg_replace('~[^a-zA-Z0-9_]~', '', str_replace ( " " , "_", $lista_nombre_series[2] ) );
				$nombre_serie_4=preg_replace('~[^a-zA-Z0-9_]~', '', str_replace ( " " , "_", $lista_nombre_series[3] ) );
				$nombre_serie_5=preg_replace('~[^a-zA-Z0-9_]~', '', str_replace ( " " , "_", $lista_nombre_series[4] ) );
				$campo_etiqueta_serie_1=$lista_etiqueta_series[0];
				$campo_etiqueta_serie_2=$lista_etiqueta_series[1];
				$campo_etiqueta_serie_3=$lista_etiqueta_series[2];
				$campo_etiqueta_serie_4=$lista_etiqueta_series[3];
				$campo_etiqueta_serie_5=$lista_etiqueta_series[4];
				$campo_valor_serie_1=$lista_valor_series[0];
				$campo_valor_serie_2=$lista_valor_series[1];
				$campo_valor_serie_3=$lista_valor_series[2];
				$campo_valor_serie_4=$lista_valor_series[3];
				$campo_valor_serie_5=$lista_valor_series[4];
				// CREA OBJETO SEGUN TIPO DE GRAFICO
				$TipoObjetoGraficoMorris     = "Morris.Area";  //Por defecto define tipo Area para cualquiera de los definidos sin compatibilidad conocida
				if ($tipo_grafico=="area")
                    $TipoObjetoGraficoMorris = "Morris.Area";
				if ($tipo_grafico=="barra" || $tipo_grafico=="barrah" || $tipo_grafico=="barrav" || $tipo_grafico=="barrah_multiples" || $tipo_grafico=="barrav_multiples")
					$TipoObjetoGraficoMorris = "Morris.Bar";
				if ($tipo_grafico=="linea" || $tipo_grafico=="linea_multiples")
					$TipoObjetoGraficoMorris = "Morris.Line";
				if ($tipo_grafico=="dona"  || $tipo_grafico=="donap" || $tipo_grafico=="torta" || $tipo_grafico=="tortap")
					$TipoObjetoGraficoMorris = "Morris.Donut";

				//Define la cadena de llaves para el grafico
				$CadenaLlaves="'$nombre_serie_1'";                //'Operaciones','Usuarios','UsoAPI'
				if ($nombre_serie_2!="") $CadenaLlaves.=",'$nombre_serie_2'";
				if ($nombre_serie_3!="") $CadenaLlaves.=",'$nombre_serie_3'";
				if ($nombre_serie_4!="") $CadenaLlaves.=",'$nombre_serie_4'";
				if ($nombre_serie_5!="") $CadenaLlaves.=",'$nombre_serie_5'";

				//Define la cadena de etiquetas para el grafico
				$CadenaEtiquetas="'$nombre_serie_1'";     //'Operaciones','Usuarios','UsoAPI'
				if ($nombre_serie_2!="") $CadenaEtiquetas.=",'$nombre_serie_2'";
				if ($nombre_serie_3!="") $CadenaEtiquetas.=",'$nombre_serie_3'";
				if ($nombre_serie_4!="") $CadenaEtiquetas.=",'$nombre_serie_4'";
				if ($nombre_serie_5!="") $CadenaEtiquetas.=",'$nombre_serie_5'";
            ?>
            <?php
                //Determina si se debe o no crear cadena para el tooltipo con titulo del informe
                $CadenaComplementoToolTipTitulo="";
                if ( $registro_informe["tooltip_titulo"] == 'S' )
                    $CadenaComplementoToolTipTitulo='title="'.PCO_ReemplazarVariablesPHPEnCadena($registro_informe["titulo"]).'" data-toggle="tooltip"';

                //Agrega titulo o encabezado si esta definido
                if ( $registro_informe["encabezado_html"] != '' )
                    echo '<div id="titulo-informe-ID'.$registro_informe["id"].'">'.$registro_informe["encabezado_html"].'</div>';
            ?>
                <div <?php echo $CadenaComplementoToolTipTitulo; ?> id="marco-informe-grafico-ID<?php echo $registro_informe["id"]; ?>" style="height: auto !important;"></div>
                <script language="JavaScript">
                    //Genera el codigo Morris para el grafico
                    $(function() {
                        <?php echo $TipoObjetoGraficoMorris; ?>({
                            //Nombre del marco que tiene el grafico
                            element: 'marco-informe-grafico-ID<?php echo $registro_informe["id"]; ?>',
                            data: [
                            <?php
                                //Inicia la generacion del arreglo con los datos
                                //Si el informe usa una conexion externa usa su configuracion
                                if($registro_informe["conexion_origen_datos"]!="")
                                    $resultado_consulta=PCO_EjecutarSQL($consulta,"",${$registro_conexiones["nombre"]});
                                else
                                    $resultado_consulta=PCO_EjecutarSQL($consulta);

                                $cadena_datos="";
                                while ($registro_consulta = $resultado_consulta->fetch())
                                    {
                                        //Crea series de datos para los graficos de Barra, Linea o area que utilizan los mismos parametros
                                        if ($TipoObjetoGraficoMorris!="Morris.Donut")
                                            {
                                                $cadena_datos.= "
                                                    {";
                                                //Agrega datos al arreglo del grafico segun las series disponibles
        								        if ($nombre_serie_1 != "")
        								            {
        								                $NombreVisibleCampo=$registro_consulta[$campo_etiqueta_serie_1];
        								                $ValorVisibleCampo=$registro_consulta[$campo_valor_serie_1];
                                                        $cadena_datos.= "
                                                        ".$nombre_serie_1.": ".$ValorVisibleCampo.",
                                                        etiqueta_ejex: '$NombreVisibleCampo'";
        								            }
        								        if ($nombre_serie_2 != "")
        								            {
        								                $NombreVisibleCampo=$registro_consulta[$campo_etiqueta_serie_2];
        								                $ValorVisibleCampo=$registro_consulta[$campo_valor_serie_2];
                                                        $cadena_datos.= ",
                                                        ".$nombre_serie_2.": ".$ValorVisibleCampo;
        								            }
        								        if ($nombre_serie_3 != "")
        								            {
        								                $NombreVisibleCampo=$registro_consulta[$campo_etiqueta_serie_3];
        								                $ValorVisibleCampo=$registro_consulta[$campo_valor_serie_3];
                                                        $cadena_datos.= ",
                                                        ".$nombre_serie_3.": ".$ValorVisibleCampo;
        								            }
        								        if ($nombre_serie_4 != "")
        								            {
        								                $NombreVisibleCampo=$registro_consulta[$campo_etiqueta_serie_4];
        								                $ValorVisibleCampo=$registro_consulta[$campo_valor_serie_4];
                                                        $cadena_datos.= ",
                                                        ".$nombre_serie_4.": ".$ValorVisibleCampo;
        								            }
        								        if ($nombre_serie_5 != "")
        								            {
        								                $NombreVisibleCampo=$registro_consulta[$campo_etiqueta_serie_5];
        								                $ValorVisibleCampo=$registro_consulta[$campo_valor_serie_5];
                                                        $cadena_datos.= ",
                                                        ".$nombre_serie_5.": ".$ValorVisibleCampo;
        								            }
                                                $cadena_datos.= "
                                                    },";
                                            }
                                        //Crea series de datos para graficos tipo dona
                                        if ($TipoObjetoGraficoMorris=="Morris.Donut")
                                            {
                                                $cadena_datos.= "
                                                    {";
        								                $NombreVisibleCampo=$registro_consulta[$campo_etiqueta_serie_1];
        								                $ValorVisibleCampo=$registro_consulta[$campo_valor_serie_1];
                                                        $cadena_datos.= "
                                                        label: '".$NombreVisibleCampo."', value: ".$ValorVisibleCampo;
                                                $cadena_datos.= "
                                                    },";
                                            }
                                    }
                                $cadena_datos = substr($cadena_datos, 0, -1);
                                if ($cadena_datos!="")
                                    echo $cadena_datos;
                                if ($cadena_datos=="")
                                    $PCO_InformesGraficosSinDatos.='marco-informe-grafico-ID'.$registro_informe["id"].'|'; //Si no tiene datos lo lleva al arreglo para cambiar luego su valor html y evitar el NaN
                            ?>
                            ],
                            xkey: ['etiqueta_ejex'],
                            ykeys: [<?php echo $CadenaLlaves; ?>],
                            labels: [<?php echo $CadenaEtiquetas; ?>],
                            pointSize: 2,
                            hideHover: 'auto',
                            resize: true,
                            stacked: <?php echo $barra_apilada; ?>,
                            preUnits: '<?php echo $unidades_pre; ?>',
                            postUnits: '<?php echo $unidades_pos; ?>',
                            grid: <?php echo $ocultar_grilla; ?>,
                            horizontal: <?php echo $barras_horizontales; ?>,
                            <?php echo $cadena_arreglo_colores; ?>

                            dataLabels: <?php echo $presentar_datalabels; ?>,
                            <?php echo $cadenaubicacion_datalabels; ?>  // EJ: dataLabelsPosition: 'outside', //inside

                            showPercentage: <?php echo $presentar_porcentaje; ?>,
                            donutType: '<?php echo $tipo_grafico_circular; ?>',
                            <?php
                                //Agrega las unidades para los tipos de grafico Donut
                                if ($TipoObjetoGraficoMorris=="Morris.Donut")
                                    echo "formatter: function (value, data) { return '$unidades_pre'+ (value) + '$unidades_pos'; },";
                            ?>
                            axes: <?php echo $ocultar_ejes; ?>
                        });
                    });
                </script>
            <?php
			// Si se ha definido un tamano fijo entonces cierra el marco
			if ($registro_informe["ancho"]!="" && $registro_informe["alto"]!="" && $registro_informe["ancho"]!="0" && $registro_informe["alto"]!="0")
				echo '</DIV>';

			} // Fin si informe es G (grafico)

		if ($en_ventana) PCO_CerrarVentana();

        //Si el usuario es admin le muestra el query generador.
        if (PCO_EsAdministrador(@$PCOSESS_LoginUsuario) && $ModoDepuracion)
            PCO_Mensaje($MULTILANG_MonCommSQL, $consulta, '', 'fa fa-fw fa-2x fa-database', 'alert alert-info alert-dismissible ');

		//Ejecuta script POST para el informe
		if ($CadenaPOSTScriptPHP!="")
		    {
		        PCO_EvaluarCodigo($CadenaPOSTScriptPHP,1,"Detalles: POST-Code Rep ID=".$informe);
		    }

		//Ejecuta script POST para el informe llevandolo a la misma cadena de formularios que se agrega en marco_abajo
		if ($JavaScriptInforme!="")
		    {
        	    $PCO_FuncionesJSInternasFORM .= '<script type="text/javascript">
        	    '.$JavaScriptInforme.'
        		</script>';
        	}
	}