	//############################################################################################
	// ### Class C_Document

	var IdcDocumentTagsCBMenu = null;

	class C_Document
	{
		constructor ()
		{
			this.Mode  				= -1;
			this.Initialized 		= false;
			this.Type				= "";
			this.Folder				= "";
			this.Filename			= "";
			this.CallbackFct 		= "";
			this.OKCallbackFct 		= "";
			this.ErrorCallbackFct 	= "";


			let nbItems = $('.c_document').length;

			this.Ident 	= "Idc_C_DocumentDlg_" + nbItems;

			let tmp = '';
					
			tmp += '<div id="'+this.Ident+'"  class="c_document modal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true" style="z-index: 10000 !important;">';
			tmp += 		'<div class="modal-dialog modal-dialog-centered" role="document" style="resize: true;">';
			tmp += 			'<div class="modal-content">';
							
			tmp += 				'<div class="modal-header p-3 pb-3 pt-3 border-bottom bg-light">';
			tmp += 					'<h5 id="'+this.Ident+'_DlgCaption" class="fw-bold mb-0"></h5>';
			tmp += 					'<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close" onclick="$(\'#'+this.Ident+'\').modal(\'hide\')"></button>';
			tmp += 				'</div>';
										
			tmp += 				'<div class="modal-body w-100 pb-0">';
			tmp += 					'<div class="container p-0 m-0">';
					
			tmp += 						'<div class="row m-0 p-0 w-100">';
			tmp += 							'<div class="col p-0 col-md-auto">';
			tmp += 								'<div class="m-0 p-0 pt-1 ps-0 pe-1 mb-2" data-langkey="Date :" ></div>';
			tmp += 								'<div class="m-0 p-0 pt-1 ps-0 pe-1 mb-2" data-langkey="Valid until :"></div>';
			tmp += 								'<div id="'+this.Ident+'_NameRowLabel" class="collapse m-0 p-0 pt-3 pb-2 w-100">';
			tmp += 									'<div class="m-0 p-0 pt-1 ps-0 pe-1 mb-2" data-langkey="Name :"></div>';
			tmp +=								'</div>';
			tmp += 								'<div class="m-0 p-0 pt-1 ps-0 pe-1 mb-2" data-langkey="Label :"></div>';
			tmp += 								'<div class="m-0 p-0 pt-2 ps-0 pe-1 mb-2" data-langkey="Tag auto-audit :"></div>';
			tmp += 							'</div>';
			tmp += 							'<div class="col m-0 p-0">';
			tmp += 								'<input type="test" id="'+this.Ident+'_Date" class="form-control form-control-sm m-0 p-0 ps-2 mb-1" autocomplete="off" size="8" placeholder="jj/mm/aaaa">';
			tmp += 								'<input type="text" id="'+this.Ident+'_ValidUntil" class="form-control form-control-sm m-0 ps-2 mb-1" autocomplete="off" size="8" placeholder="jj/mm/aaaa">';
			tmp += 								'<div id="'+this.Ident+'_NameRowInput" class="collapse m-0 p-0 pt-3 pb-2 w-100">';
			tmp += 									'<input type="text" id="'+this.Ident+'_Name" class="form-control form-control-sm m-0 p-0 ps-2 mb-1">';
			tmp +=								'</div>';
			tmp += 								'<input type="text" id="'+this.Ident+'_Label" class="form-control form-control-sm m-0 p-0 ps-2 mb-1">';
			tmp +=								'<div class="row m-0 p-0 pt-1">';
			// tmp +=									'<label class="form-label m-0 p-0 pb-1 fw-bold" data-langkey="Tags :"></label>';
			tmp +=									'<div id="'+this.Ident+'_TagsContainer" class="m-0 p-0 mb-1"></div>';
			tmp +=								'</div>';	
								
			// tmp += 								'<div id="IdcERDTagsListContainer" class="m-0 p-0 mb-1"></div>';
			tmp += 							'</div>';
			tmp += 						'</div>';
						
			tmp += 						'<div class="row m-0 p-0 w-100">';
			tmp += 							'<div class="col m-0 p-0">';
			tmp += 								'<label for="'+this.Ident+'_Comment" class="form-label m-0 p-0" data-langkey="Comment :"></label>';
			tmp += 								'<textarea class="form-control m-0 p-0 ps-2 mb-1" id="'+this.Ident+'_Comment" rows="3"></textarea>';
			tmp += 							'</div>';
			tmp += 						'</div>';
						
			tmp +=						'<fieldset class="ximeo_fieldset mb-1 mt-2 m-0">';
			tmp +=							'<legend class="ximeo_fieldset" data-langkey="Document :"></legend>';
			
			tmp += 							'<div class="row m-0 p-0 w-100">';
			tmp += 								'<div class="m-0 p-0 pt-1 ps-0 pe-1 mb-2" data-langkey="Extern document :"></div>';
			tmp += 								'<input type="text" id="'+this.Ident+'_ExternLink" class="form-control form-control-sm m-0 p-0 ps-2 mb-1" data-langkey_placeholder="Link to document">';
			tmp += 							'</div>';

			tmp += 							'<div id="'+this.Ident+'_FileRow" class="collapse m-0 p-0 pt-3 pb-2 w-100">';
			tmp += 							'<div class="row m-0 p-0 pt-3 w-100">';
			tmp += 								'<div class="m-0 p-0">';
			tmp += 									'<label for="'+this.Ident+'_File" class="form-label m-0 p-0 pb-2" data-langkey="File :"></label>';
			tmp += 									'<input class="form-control m-0" type="file" id="'+this.Ident+'_File" readonly>';
			tmp += 								'</div>';
			tmp += 							'</div>';
			tmp += 							'</div>';

			tmp += 							'<div id="'+this.Ident+'_ProgressRow" class="collapse m-0 p-0 pt-3 pb-2 w-100">';
			tmp += 							'<div class="row m-0 p-0 pt-3 pb-2 w-100">';
			tmp +=								'<div class="col">';
			tmp +=									'<button id="'+this.Ident+'_Abort" class="btn btn-primary text-center pt-0 pb-0 ps-2 pe-2" style="background-color: #2F83B0" >';
			tmp +=	 								'<img src="'+eoDACS.ServerFolder+'/eoDACS/SubFW/bmp/validate_white.png" class="imgclickable float-start me-2" style="width: 18px; vertical-align: middle;">';
			tmp += 									'<span data-langkey="Abort">Abort</span>';
			tmp += 									'</button>';
			tmp +=								'</div>';
			tmp +=								'<div class="col">';
			tmp +=									'<progress id="'+this.Ident+'_Progress">';
			tmp += 									'</progress>';
			tmp +=								'</div>';
			tmp +=								'<div class="col">';
			tmp +=									'<output id="'+this.Ident+'_Output">';
			tmp += 									'</output>';
			tmp +=								'</div>';
			tmp +=							'</div>';
			tmp +=							'</div>';
			tmp +=						'</fieldset>';
					
			tmp += 					'</div>';
			tmp += 					'<div class="modal-footer mt-3">';
			tmp += 						'<button class="btn btn-primary text-center pt-0 pb-0 ps-2 pe-2" style="background-color: #2F83B0" onclick="C_DocumentValidate(\''+this.Ident+'\')">';
			tmp += 							'<img src="'+eoDACS.ServerFolder+'/eoDACS/SubFW/bmp/validate_white.png" class="imgclickable float-start me-2" style="width: 18px; vertical-align: middle;">';
			tmp += 							'<span data-langkey="Validate">Validate</span>';
			tmp += 						'</button>';
			tmp += 						'<button class="btn btn-secondary text-center ms-4 pt-0 pb-0 ps-2 pe-2" style="background-color: #2F83B0" onclick="$(\'#'+this.Ident+'\').modal(\'hide\')">';
			tmp += 							'<img src="'+eoDACS.ServerFolder+'/eoDACS/SubFW/Bmp/close_white.png" class="imgclickable float-start me-2" style="width: 18px; vertical-align: middle;">';
			tmp += 							'<span data-langkey="Cancel">Cancel</span>';
			tmp += 						'</button>';
			tmp += 					'</div>';
			tmp += 				'</div>';
			tmp += 			'</div>';
			tmp += 		'</div>';
			tmp += 	'</div>';
					
			$('body').append (tmp);

			IdcDocumentTagsCBMenu = new C_CheckboxMenu ( this.Ident+'_TagsContainer', this.Ident+'_TagsCB', Translate("Click here to select tags") );
			// IdcExamsListTagsCBMenu.CallbackFct = ExamsListTagsChanged;

			$( '#'+this.Ident ).data ( 'CDObj', this );
		}

		InitTags ( type )
		{
			let cbElem = IdcDocumentTagsCBMenu;

			cbElem.ClearAll ();

			let lastSeparator = "";
		
			var xhra= getxhr();
			
			xhra.onloadend = function f()
			{
				if ( xhra.readyState == 4 && xhra.status == 200 )  
				{
					let reponse		= clean(xhra.responseXML.documentElement);
					let tags	 	= reponse.getElementsByTagName ( 'tag' );
				
					for ( let i=0; i<tags.length; i++ )
					{
						let id			= tags.item (i).getAttribute ( "id" 	);
						let name		= tags.item (i).getAttribute ( "name" 	);
																	
						cbElem.AddItem ( -1, id, name );
					}
				}
			};

			let url = eoDACS.ServerFolder + "/eoQUAL/SubFW/database/common/get_bquaad_tag.php";
			xhra.open ('GET', url, false );
			xhra.send ();
		}

		Show ( mode, data )		// mode 0 : Add, mode 1 : Edit, mode 2 : Add version
		{
			if ( this.Initialized == false )
			{
				$( '#' + this.Ident + '_Date' ).datepicker();
				$( '#' + this.Ident + '_Date' ).datepicker( "option", "dateFormat", "dd/mm/yy" );

				$( '#' + this.Ident + '_ValidUntil' ).datepicker();
				$( '#' + this.Ident + '_ValidUntil' ).datepicker( "option", "dateFormat", "dd/mm/yy" );

				this.Initialized = true;
			}

			this.InitTags ( data.Type );

			let cbElem = IdcDocumentTagsCBMenu;

			let loadData = this.LoadData.bind ( this );

			switch ( mode )
			{
				case 0: 	// Add
					this.Mode = 0;
					$( '#' + this.Ident ).data ('ext_id', data.ExtID );
					$( '#' + this.Ident + '_NameRowLabel' ).addClass ( 'show' );
					$( '#' + this.Ident + '_NameRowInput' ).addClass ( 'show' );
					$( '#' + this.Ident + '_FileRow' ).addClass ( 'show' );
					$( '#' + this.Ident + '_Name' ).val ( '' );
					$( '#' + this.Ident + '_Label' ).val ( '' );
					$( '#' + this.Ident + '_Comment' ).val ( '' );
					$( '#' + this.Ident + '_Date' ).val ( GetCurrentDate (eoDACS.CurrentLanguage) );
					$( '#' + this.Ident + '_ValidUntil' ).val ( '' );
					cbElem.UnselectAll ();
					break;

				case 1: 	// Edit
					this.Mode = 1;
					$( '#' + this.Ident + '_NameRowLabel' ).addClass ( 'show' );
					$( '#' + this.Ident + '_NameRowInput' ).addClass ( 'show' );
					$( '#' + this.Ident + '_FileRow' ).removeClass ( 'show' );
					$( '#' + this.Ident ).data ( 'id', data.ID );
					loadData ( data.Type, data.ID );
					break;

				case 2: 	// Add version
					this.Mode = 2;
					$( '#' + this.Ident ).data ( 'id', data.ID );
					$( '#' + this.Ident ).data ('ext_id', data.ExtID );
					$( '#' + this.Ident + '_NameRowLabel' ).removeClass ( 'show' );
					$( '#' + this.Ident + '_NameRowInput' ).removeClass ( 'show' );
					$( '#' + this.Ident + '_FileRow' ).addClass ( 'show' );
					$( '#' + this.Ident + '_Name' ).val ( '' );
					$( '#' + this.Ident + '_Label' ).val ( '' );
					$( '#' + this.Ident + '_Comment' ).val ( '' );
					$( '#' + this.Ident + '_Date' ).val ( GetCurrentDate (eoDACS.CurrentLanguage) );
					$( '#' + this.Ident + '_ValidUntil' ).val ( '' );
					cbElem.UnselectAll ();
					break;
			}
			
			$( '#' + this.Ident+'_DlgCaption' ).text ( data.Caption );
			this.Type  				= data.Type;
			this.Folder				= data.Folder;
			this.CallbackFct 		= (data.CallbackFct != undefined)? 		data.CallbackFct 		: "";
			this.OKCallbackFct 		= (data.OKCallbackFct != undefined)? 	data.OKCallbackFct 		: "";
			this.ErrorCallbackFct 	= (data.ErrorCallbackFct != undefined)? data.ErrorCallbackFct 	: "";

				

			$('#'+this.Ident+'').modal('show');
		}

		Add ( data )
		{
			this.Show ( 0, data );
		}

		Edit ( data )
		{
			this.Show ( 1, data );
		}

		AddVersion ( data )
		{
			this.Show ( 2, data );
		}

		OnLoadDataOK ( data )
		{
			let cbElem = IdcDocumentTagsCBMenu;

			$( '#' + this.Ident + '_Name' ).val ( data.name );
			$( '#' + this.Ident + '_Label' ).val ( data.label );
			$( '#' + this.Ident + '_Comment' ).val ( data.comment );
			$( '#' + this.Ident + '_Date' ).val ( data.create_date );
			$( '#' + this.Ident + '_ValidUntil' ).val ( data.valid_until_date );
			
			let tagsArray = data.bquaad_tag_list.split(',');
			cbElem.SelectElementIdent2 ( tagsArray );
		}

		LoadData ( type, id )
		{
			let onLoadDataOK = this.OnLoadDataOK.bind(this);
			var request = $.ajax ({
        		url: 		eoDACS.ServerFolder + "/eoDACS/SubFW/database/common/db_form_document_load.php",
        		type: 		"post",
        		dataType: 	"json",
        		data: 		{id: id}
    			}
    		)
			.done ( onLoadDataOK )
    		.fail ();
		}


		Close ()
		{
			$('#'+this.Ident+'').modal('hide');
		}

		Validate ()
		{
			let file 		= $('#'+this.Ident +'_File').get(0).files[0];

			let uploadFile  = this.UploadFile.bind(this);
			let saveForm	= this.SaveForm.bind(this);

			switch ( this.Mode )
			{
				case 0:  	// Add
					uploadFile ( this.Folder, file );
					break;

				case 1:  	// Edit
					saveForm ();
					break;

				case 2:  	// New version
					uploadFile ( this.Folder, file );
					break;
			}
		}

		SaveForm ( uploaded_filename )
		{
			let saveFail 	= this.SaveFail.bind(this);
			let saveOK 		= this.SaveOK.bind(this);

			let cbMenu = IdcDocumentTagsCBMenu;
			let type  		= this.Type;
			let date 		= $( '#' + this.Ident + '_Date' ).val ();
			let validUntil	= $( '#' + this.Ident + '_ValidUntil' ).val ();
			let name		= $( '#' + this.Ident + '_Name' ).val ();
			let label		= $( '#' + this.Ident + '_Label' ).val ();
			let comment		= $( '#' + this.Ident + '_Comment' ).val ();
			let extern_link	= $( '#' + this.Ident + '_ExternLink' ).val ();
			let tags 		= cbMenu.GetSelection2 ().toString();
			let filename  	= this.Filename;

			if ( this.CallbackFct != "" )
			{
				let values = { 	'Date': 				date,
								'ValidUntil': 			validUntil,
								'Name': 				name,
								'Label': 				label,
								'Comment': 				comment,
								'Filename':	 			filename,
								'UploadedFilename':	 	uploaded_filename,
								'Tags': 				tags	};

				this.CallbackFct ( values );
			}
			else
			{
				let data 		= {};
				let toProcess 	= false;

				switch ( this.Mode )
				{
					case 0:  	// Add
						{
							let id = $('#' + this.Ident ).data ('ext_id');

							// let row_id = '1';
							let row_id = id;

    						data [id+'_!nativeeditor_status'] 	= 'inserted';
    						data [id+'_documentmode']			= 'newdocument';
    						data [id+'_ext_id']					= id;
    						data [id+'_document_type']			= type;
    						data [id+'_name']					= name;
    						data [id+'_create_date']			= date;
    						data [id+'_valid_until_date']		= validUntil;
    						data [id+'_label']					= label;
    						data [id+'_comment']				= comment;
    						data [id+'_uploaded_by']			= G_USE_ID;
    						data [id+'_revision']				= 1;
    						data [id+'_devicedocumentfile_r_0']	= filename;
    						data [id+'_devicedocumentfile_s_0'] = uploaded_filename;
    						data [id+'_bquaad_tag']				= tags;
    						data ['ids']						= row_id;

    						toProcess = true;
    					}
    					break;

    				case 1: 	// Edit
    					{
							let id = $('#' + this.Ident ).data ('id');

    						data [id+'_!nativeeditor_status'] 	= 'updated';
    						data [id+'_create_date']			= date;
    						data [id+'_valid_until_date']		= validUntil;
    						data [id+'_name']					= name;
    						data [id+'_label']					= label;
    						data [id+'_comment']				= comment;
    						data [id+'_extern_link']			= extern_link;
    						data [id+'_bquaad_tag']				= tags;

    						data ['ids']						= id;

    						toProcess = true;
    					}
    					break;

    				case 2:  	// Add version
						{
							let ext_id 	= $('#' + this.Ident ).data ('ext_id');
							let id 		= $('#' + this.Ident ).data ('id');

							data [id+'_!nativeeditor_status'] 	= 'inserted';
							data [id+'_document_type']			= type;
							data [id+'_ext_id']					= ext_id;
							// data [id+'_name']					= name;
							data [id+'_label']					= label;
							data [id+'_comment']				= comment;
							data [id+'_uploaded_by']			= G_USE_ID;
							data [id+'_create_date']			= date;
							data [id+'_valid_until_date']		= validUntil;
							data [id+'_extern_link']			= extern_link;
							data [id+'_devicedocumentfile_r_0']	= filename;
    						data [id+'_devicedocumentfile_s_0'] = uploaded_filename;
    						data [id+'_documentparent']			= id;			
    						data [id+'_bquaad_tag']				= tags;
	   						data ['ids']						= id;

    						toProcess = true;
    					}
    					break;
    			}
    			if ( toProcess == true )
    			{
					var request = $.ajax ({
        				url: eoDACS.ServerFolder + "/eoDACS/SubFW/database/common/document.php",
        				type: "post",
        				dataType: "json",
        				data: data
    					}
    				)
    				.done ( saveOK )
    				.fail ( saveFail );
    			}
			}
			
			// $('#'+this.Ident+'').modal('hide');
		}

		SaveOK ( data )
		{
			this.Close ();
			
			if ( this.OKCallbackFct != "" )
				this.OKCallbackFct ( data );
		}

		SaveFail ()
		{
			if ( this.ErrorCallbackFct != "" )
				this.ErrorCallbackFct ();
		}

		UploadEnded ( uploaded_filename )
		{
			$( '#' + this.Ident + '_ProgressRow' ).removeClass ( 'show' );

			this.SaveForm ( uploaded_filename );
		}


		UploadError ()
		{
		}

		UploadFile ( folder, fileToUpload )
		{
			$( '#' + this.Ident + '_ProgressRow' ).addClass ( 'show' );
			
			this.Filename = fileToUpload.name;

			let uploadError = this.UploadError.bind(this);
			let uploadEnded = this.UploadEnded.bind(this);

  			const progressBar 	= document.getElementById ( this.Ident+"_Progress" );
  			const log 			= document.getElementById ( this.Ident+"_Output" );
  			const abortButton 	= document.getElementById ( this.Ident+"_Abort" );

   			const xhr = new XMLHttpRequest();
   			xhr.timeout 		= 20000; // 20 seconds
   			xhr.responseType	= "text";
   			
   			xhr.onreadystatechange = function() 
   			{
   				if ( xhr.readyState==4 )
    			{
    				if ( xhr.status == 200 )
    				{
    					let res = JSON.parse ( xhr.responseText ).result;

        				if ( res == 'OK' )
        				{
        					log.textContent = "Upload finished.";
        					uploadEnded ( JSON.parse ( xhr.responseText ).filename );
        				}
        				else
        				{
        					log.textContent = "Upload error.";
        					uploadError ();
        				}
        			}
        			else
        			{
        				log.textContent = "Upload error.";
        				uploadError ();
        			}
    			}
			};
			

   			
   			// Link abort button
   			abortButton.addEventListener (
     			"click",
      			() => {
        			xhr.abort();
      			},
      			{ once: true },
    		);

    		// When the upload starts, we display the progress bar
    		xhr.upload.addEventListener("loadstart", (event) => {
      			progressBar.classList.add("visible");
      			progressBar.value = 0;
      			progressBar.max = event.total;
      			log.textContent = "Uploading (0%)…";
      			abortButton.disabled = false;
    		});

    		// Each time a progress event is received, we update the bar
    		xhr.upload.addEventListener("progress", (event) => {
      			progressBar.value = event.loaded;
      			log.textContent = `Uploading (${(
        		(event.loaded / event.total) *
        		100
      			).toFixed(2)}%)…`;
    		});

    		/*
    		xhr.upload.addEventListener("loadend", (event) => {
    			progressBar.classList.remove("visible");
      			if (event.loaded !== 0) 
      			{
        			log.textContent = "Upload finished.";
        			this.UploadEnded ();
      			}
      			abortButton.disabled = true;
    		});

    		xhr.upload.addEventListener("error", (event) => {
    				log.textContent = "Upload finished.";
        			this.UploadError ();      			
    		});
    		*/

    		function errorAction(event) 
    		{
      			progressBar.classList.remove("visible");
      			log.textContent = `Upload failed: ${event.type}`;

      			this.UploadError ();
    		}
    		// xhr.upload.addEventListener("error", errorAction);
    		xhr.upload.addEventListener("abort", errorAction);
    		xhr.upload.addEventListener("timeout", errorAction);
    		

    		// Build the payload
    		const fileData = new FormData();
    		fileData.append ( "file", fileToUpload );
    		fileData.append ( 'folder', folder );

    		// Theoretically, event listeners could be set after the open() call
    		// but browsers are buggy here
    		xhr.open("POST", eoDACS.ServerFolder + "/eoQUAL/SubFW/html/UploadFile.php", true);

    		// Note that the event listener must be set before sending (as it is a preflighted request)
    		xhr.send(fileData);
  		}
	}

	function C_DocumentValidate ( ident )
	{
		let cdObj = $('#'+ident).data ('CDObj');

		cdObj.Validate ();
	}


	

	//############################################################################################
	// ### Class C_DocumentDT

	var DT_DocumentDlg = null;

	function CDShortcut ( origine )
	{
		let version = parseInt(origine);
		if ( version > 1 )
			return '<img class=\"C_DocumentDT_Histo imgclickable  pe-2\" title=\"'+Translate ( 'Previous versions' )+'\" src=\"'+eoDACS.ServerFolder+'/eoDACS/SubFW/bmp/counter_back_blue.png\" style=\"height: 18px; width: auto;\"></img><img class=\"C_DocumentDT_AddVersion imgclickable  pe-2\" title=\"'+Translate ( 'Add' )+'\" src=\"'+eoDACS.ServerFolder+'/eoDACS/SubFW/bmp/add_blue.png\" style=\"height: 18px; width: auto;\"></img><img class=\"C_DocumentDT_Edit imgclickable  pe-2\" title=\"'+Translate ( 'Edit' )+'\" src=\"'+eoDACS.ServerFolder+'/eoDACS/SubFW/bmp/edit_blue.png\" style=\"height: 18px; width: auto;\"></img><img class=\"C_DocumentDT_View imgclickable  pe-2\" title=\"'+Translate ( 'View' )+'\" src=\"'+eoDACS.ServerFolder+'/eoDACS/SubFW/bmp/view_blue_48.png\" style=\"height: 18px; width: auto;\"></img>';
		else
			return '<img class=\"C_DocumentDT_NoHisto imgclickable  pe-2\" title=\"'+Translate ( 'No previous versions' )+'\" src=\"'+eoDACS.ServerFolder+'/eoDACS/SubFW/bmp/counter_back_gray.png\" style=\"height: 18px; width: auto;\" disable></img><img class=\"C_DocumentDT_AddVersion imgclickable  pe-2\" title=\"'+Translate ( 'Add' )+'\" src=\"'+eoDACS.ServerFolder+'/eoDACS/SubFW/bmp/add_blue.png\" style=\"height: 18px; width: auto;\"></img><img class=\"C_DocumentDT_Edit imgclickable  pe-2\" title=\"'+Translate ( 'Edit' )+'\" src=\"'+eoDACS.ServerFolder+'/eoDACS/SubFW/bmp/edit_blue.png\" style=\"height: 18px; width: auto;\"></img><img class=\"C_DocumentDT_View imgclickable  pe-2\" title=\"'+Translate ( 'View' )+'\" src=\"'+eoDACS.ServerFolder+'/eoDACS/SubFW/bmp/view_blue_48.png\" style=\"height: 18px; width: auto;\"></img>';
	}

	class C_DocumentDT
	{
		constructor ( ident )
		{
			if ( DT_DocumentDlg == null )
				DT_DocumentDlg = new C_Document ();

			// External data
			this.Ident				= ident;
			this.OneOnly			= false;
			this.Caption			= "";
			this.Container			= "";
			this.DocType			= "";
			this.ExtID  			= -1;


			// Local data
			this.DocDT 				= null;
			this.Initialized 		= false;
		
			this.DocDT = new C_DataTable ();
			this.DocDT.DataSrcType			= 0;
			this.DocDT.Ident 				= this.Ident +'_DT';
			this.DocDT.Container 			= this.Ident + '_DTContainer';
			this.DocDT.DataSrc 				= eoDACS.ServerFolder+'/eoDACS/SubFW/database/common/GetDTRealDocuments.php';
			this.DocDT.DataFct				= this.DTGetData.bind(this);
			this.DocDT.SetColReorder 	( true );

			// this.DocDT.AddColumn ( 'Shortcuts',				'',		 					0, true,   0, 	 100, false, '', 	'<img class=\"C_DocumentDT_Histo imgclickable  pe-2\" title=\"'+Translate ( 'Previous versions' )+'\" src=\"SubFW/bmp/counter_back_blue.png\" style=\"height: 18px; width: auto;\"></img><img class=\"C_DocumentDT_AddVersion imgclickable  pe-2\" title=\"'+Translate ( 'Add' )+'\" src=\"SubFW/bmp/add_blue.png\" style=\"height: 18px; width: auto;\"></img><img class=\"C_DocumentDT_Edit imgclickable  pe-2\" title=\"'+Translate ( 'Edit' )+'\" src=\"SubFW/bmp/edit_blue.png\" style=\"height: 18px; width: auto;\"></img><img class=\"C_DocumentDT_View imgclickable  pe-2\" title=\"'+Translate ( 'View' )+'\" src=\"SubFW/bmp/view_blue_48.png\" style=\"height: 18px; width: auto;\"></img>' );
			this.DocDT.AddColumn ( 'Shortcuts',				'shortcut',		 					0, true,   0, 	 110, false, '', 	'', CDShortcut );
			this.DocDT.AddColumn ( 'id',					'id',	 					1, false,  1,  '10%', false, '',	'' );
			this.DocDT.AddColumn ( 'doc_master_id',			'doc_master_id',			1, false,  2,  '10%', false, '',	'' );
			this.DocDT.AddColumn ( 'doc_master_groupid',	'doc_master_groupid',		1, false,  3,  '10%', true,  '', 	'' );
			this.DocDT.AddColumn ( 'Rev.',					'revision',	 				1, true,   4,  '10%', true,  '',	'' );
			this.DocDT.AddColumn ( 'Label',					'label', 					1, true,   5,  '10%', true,  '', 	'' );
			this.DocDT.AddColumn ( 'Date',					'date',						1, true,   6,  '10%', true,  '', 	'' );
			this.DocDT.AddColumn ( 'Author',				'author',					1, true,   7,  '10%', true,  '', 	'' );
			this.DocDT.AddColumn ( 'Name',					'name',						1, true,   8,  '10%', true,  '', 	'' );
			this.DocDT.AddColumn ( 'Comment',				'comment',					1, true,   9,  '10%', true,  '', 	'' );
			this.DocDT.AddColumn ( 'Valid until',			'valid_until_date',			1, true,  10,  '10%', true,  '', 	'' );
		}

		Create ( mode )		// Mode : 0 = couleur application, arrondi, pading 2.   Mode : 1 = couleur gris, pas d'arrondi, padding 0.
		{
			mode = ( mode == undefined )? 0 : mode;
			let tmp = "";

			let onAddDocument 		= this.OnAddDocument.bind (this)
			let onDeleteDocument 	= this.OnDeleteDocument.bind (this)

			if ( mode == 0 )
			{
				tmp += '<div id="'+this.Ident+'_Div" class="c_documentdt d-flex flex-column h-100 p-2">';
				tmp += 		'<div class="row m-0">';
				tmp +=			'<div class="ximeo_caption w-100 text-white ps-2 pe-2 pt-2 pb-2">';
			}
			else
			{
				tmp += '<div id="'+this.Ident+'_Div" class="c_documentdt d-flex flex-column h-100 p-0 border">';
				tmp += 		'<div class="row m-0">';
				tmp += 				'<div class="w-100 m-0 ps-2 pe-2 pt-1 pb-1 border-bottom ximeo_bg-dark-3 text-white" >';
			}
			tmp +=				'<div class="row w-100 m-0 p-0">';
			tmp +=					'<div class="col-auto m-0 p-0">';
			tmp +=						'<span data-langkey="'+this.Caption+'"></span>';
			tmp +=					'</div>';
			tmp +=					'<div class="col m-0 p-0">';
			tmp +=						'<div class="d-flex flex-row-reverse w-100 h-100 m-0 p-0">';
			tmp +=							'<div class="col-md-auto h-100 m-0 p-0">';
			tmp +=								'<img id="'+this.Ident+'_DeleteButton" src="'+eoDACS.ServerFolder+'/eoDACS/SubFW/bmp/trash_white.png" data-langkey_title="Delete" class="imgclickable ximeo_bmp">';
			tmp +=							'</div>';
			tmp +=							'<div class="col-md-auto h-100 m-0 p-0 ps-2 pe-2">';
			tmp +=								'<img id="'+this.Ident+'_AddButton" src="'+eoDACS.ServerFolder+'/eoDACS/SubFW/bmp/add_white.png" data-langkey_title="Add" class="imgclickable ximeo_bmp">';
			tmp +=							'</div>';
			tmp +=						'</div>';
			tmp +=					'</div>';
			tmp +=				'</div>';
			tmp +=			'</div>';
			tmp +=		'</div>';
			tmp +=		'<div class="row flex-grow-1 m-0 bg-warning">';
			tmp +=			'<div id="'+this.Ident+'_DTContainer" class="col w-100 h-100 m-0 p-0 ps-2 pe-2 bg-white">';
			tmp +=			'</div>';
			tmp +=		'</div>';
			tmp +=	'</div>';


			document.getElementById ( this.Container ).innerHTML = tmp;

			document.getElementById ( this.Ident + '_AddButton' 	).addEventListener ( "click", onAddDocument 	);
			document.getElementById ( this.Ident + '_DeleteButton' 	).addEventListener ( "click", onDeleteDocument 	);

			if ( this.OneOnly == true )
				this.DocDT.OnSelectChangedFct	= this.DTSelectChanged.bind(this);

			this.DocDT.Create ();

			let dtProperties = this.DTProperties.bind (this);

			let C_DocumentDTListMenu = [
			{
				header: ''
			},
			{	
				img: eoDACS.ServerFolder+'/eoDACS/SubFW/bmp/setup_1_blue.png',
				text: 'Grid properties...',
				action: function(e, selector) { dtProperties (); }
			}
			];

			context.attach ( '#' + this.DocDT.Ident, C_DocumentDTListMenu );
			this.DocDT.SetRowToSelect('first_row');

			let onHistoDocument = this.OnHistoDocument.bind ( this );
			let onAddVersion 	= this.OnAddVersion.bind ( this );
			let onEditDocument 	= this.OnEditDocument.bind ( this );
			let onViewDocument 	= this.OnViewDocument.bind ( this );

			$('#'+this.Ident +'_DT'+' tbody').on('click', '.C_DocumentDT_Histo', function () 
			{
				let tr = $(this).closest('tr');
					
				onHistoDocument ( tr );
			} );	

			let ident = this.Ident;
			$('#'+this.Ident +'_DT'+' tbody').on('click', '.C_DocumentDT_AddVersion', function () 
			{
				let row = $(this).closest('tr');
				let id = $('#'+ident +'_DT').DataTable().row( row ).data().id;
					
				onAddVersion ( id );
			} );	

			$('#'+this.Ident +'_DT'+' tbody').on('click', '.C_DocumentDT_Edit', function () 
			{
				let row = $(this).closest('tr');
				let id = $('#'+ident +'_DT').DataTable().row( row ).data().id;
					
				onEditDocument ( id );
			} );	

			$('#'+this.Ident +'_DT'+' tbody').on('click', '.C_DocumentDT_View', function () 
			{
				let row = $(this).closest('tr');
				let id 			= $('#'+ident +'_DT').DataTable().row( row ).data().id;
				let label 		= $('#'+ident +'_DT').DataTable().row( row ).data().label;
				let name 		= $('#'+ident +'_DT').DataTable().row( row ).data().name;
				let revision	= $('#'+ident +'_DT').DataTable().row( row ).data().revision;
					
				onViewDocument ( id, label, name, revision );
			} );	
		}

		DTSelectChanged ( rowsIdx )
		{
			let ident = '#'+this.Ident+"_AddButton";

			if ( this.DocDT.GetRowNumber () > 0 )	
				$( ident ).hide ();
			else
				$( ident ).show ();
		}

		LoadUserCfg ( use_id )
		{
			this.DocDT.LoadUserCfg ( use_id );
		}

		DTProperties ()
		{
			this.DocDT.Properties ();
		}

		DTGetData ( d ) 
		{
			d.ext_id 		= this.ExtID;
			d.doctype		= this.DocType;
			d.versioning	= 0;
					
			return $.extend( {}, d );
		}

		FillSubDT ( d ) 
		{
			// `d` is the original data object for the row

			let onViewHistoDocument 	= this.OnViewHistoDocument.bind ( this );

			let div = $('<div/>')
				.addClass( 'loading' )
				.text( 'Loading...' );
			
			let xhra= getxhr();
			
			xhra.onloadend = function f()
			{
				if ( xhra.readyState == 4 && xhra.status == 200 )  
				{
					let ret = "";
					ret += "<div class=\"m-2 p-2 border bg-light\">";
					ret += "<div class=\"row m-0 p-2 ps-0 pt-0\">";
					ret += Translate("Previous versions");
					ret += "</div>";
					ret += "<div class=\"row m-0 p-0\">";
					ret += "<table id=\"IdcTable001\" class='SubTable m-0 p-0 border-bottom w-100'>";
					ret += 	"<thead class=\"border-bottom\" style=\"border-color: #067fb8 !important;\">";
					ret += 		"<tr>";
					ret +=			"<th class='border-end' style='width:20px'></th>";
					ret +=			"<th class='border-end p-0 ps-2 fw-normal'>ID</th>";
					ret +=			"<th class='border-end p-0 ps-2 fw-normal' style='width:50px'>Rev.</th>";
					ret +=			"<th class='border-end p-0 ps-2 fw-normal' style='width:80px'>Date</th>";
					ret += 			"<th class='border-end p-0 ps-2 fw-normal' style='width:140px'>Label</th>";
					ret += 			"<th class='border-end p-0 ps-2 fw-normal'>"+Translate('Comment')+"</th>";
					ret += 		"</tr>";
					ret += 	"</thead>";
					ret += 	"<tbody class='SubTable'>";
							
					let reponse 		= clean(xhra.responseXML.documentElement);
					let documents		 	= reponse.getElementsByTagName ( 'document' );
					for ( var i=0; i<documents.length; i++ )
					{	
						let revision		= documents.item (i).getAttribute ( "revision" );

						if ( revision != d.revision )
						{
							let id 				= documents.item (i).getAttribute ( "id" );
							let label			= documents.item (i).getAttribute ( "label" );
							let comment			= documents.item (i).getAttribute ( "comment" );
							let creation_date	= documents.item (i).getAttribute ( "creation_date" );
					
							ret +=		"<tr>";

							ret +=			"<td class='border-end'><img class=\"C_DocumentDT_Sub_Histo imgclickable  pe-2\" title='"+Translate('View')+"' src=\"SubFW/bmp/view_blue_48.png\" style=\"height: 18px; width: auto;\" data-id=\""+id+"\"></img></td>";
							ret +=			"<td class='border-end p-0 ps-2'>"+id+"</td>";
							ret +=			"<td class='border-end p-0 ps-2'>"+revision+"</td>";
							ret +=			"<td class='border-end p-0 ps-2'>"+creation_date+"</td>";
							ret +=			"<td class='border-end p-0 ps-2'>"+label+"</td>";
							ret +=			"<td class='border-end p-0 ps-2'>"+comment+"</td>";
																	
							ret +=		"</tr>";
						}
					}
					
					ret +=		"</tbody>";
					ret +=	"</table>";
					ret += "</div>";
					ret += "</div>";
				
					div
						.html( ret )
						.removeClass( 'loading' );

					let elements = document.getElementsByClassName ( 'C_DocumentDT_Sub_Histo' );
					for ( let i=0; i<elements.length; i++ )
						elements [i].addEventListener ( "click", function (event) { onViewHistoDocument (event); } 	);
				}
			};

			let url = "SubFW/database/common/get_document_versions.php?doc_master_id="+d.doc_master_id;
			
			xhra.open ('GET', url, true );
			xhra.send ();
		
			return div;
		}

		Refresh ()
		{
			this.DocDT.Refresh ();
		}

		// ##########################################################################""
		// ### Add document

		AddDocumentOKCallback ( data )
		{
			this.DocDT.Refresh ();
			this.DocDT.SetRowToSelect ( 'id', data.tid );
		}

		AddDocumentErrorCallback ( data )
		{
		}

		OnAddDocument ()
		{
			let data = {};
			data.Type 				= this.DocType;
			data.Caption			= Translate ( "New document" );
			data.Folder				= this.DocType;
			data.ExtID  			= this.ExtID;
			data.OKCallbackFct 		= this.AddDocumentOKCallback.bind(this);
			data.ErrorCallbackFct 	= this.AddDocumentErrorCallback.bind(this);

			DT_DocumentDlg.Add ( data );
		}


		// ##########################################################################""
		// ### Delete document

		OnDeleteDocument ()
		{
			let data = {};
			data.RequestURL		= eoDACS.ServerFolder + "/eoDACS/SubFW/database/common/delete_document.php";
			data.RequestData	= "id";
			data.DTColIdent		= "id";
			data.NoSelectedMsg 	= Translate ( "No document selected !!!" );
			data.ConfirmMsg 	= Translate ( "Delete selected document ?" );
			data.ErrorMsg 		= Translate ( "Unable to delete document !!!" );

			this.DocDT.DeleteSelectedRow ( data );
		}

	
		// ##########################################################################""
		// ### Version histo

		OnHistoDocument ( tr )
		{
			let row = $('#'+this.Ident+'_DT').DataTable ().row ( tr );
 
			if ( row.child.isShown() ) 
			{
				row.child.hide ();
				tr.removeClass ( 'shown' );
			} 
			else 
			{
				row.child ( this.FillSubDT ( row.data() ) ).show ();
				tr.addClass ( 'shown' );
			}
		}

	
		// ##########################################################################""
		// ### Edit document

		OnEditDocument ( id )
		{
			let data = {};
			data.Type  				= this.DocType;
			data.Caption			= Translate ( "Edit document" );
			data.ID  				= id;
			data.OKCallbackFct 		= this.AddDocumentOKCallback.bind(this);
			data.ErrorCallbackFct 	= this.AddDocumentErrorCallback.bind(this);
		
			DT_DocumentDlg.Edit ( data );
		}

	
		// ##########################################################################""
		// ### View document

		OnViewDocument ( id, label, name, revision )
		{
			let caption = name + " - revision " + revision;
			DocumentViewerShow ( caption );
		
			let url = eoDACS.ServerAddress + eoDACS.ServerFolder + "/PDFViewer/eoQUALPDFViewer.php?docid="+id;
		
			document.getElementById ( 'IdcDocumentViewerFrame' ).src = url;
		}

	
		// ##########################################################################""
		// ### Add version

		OnAddVersion ( id )
		{
			let data = {};
			data.Type  			= this.DocType;
			data.Folder			= this.DocType;
			data.Caption		= Translate ( "New version" );
			data.ID  			= id;
			data.ExtID  		= this.ExtID;
			data.OKCallbackFct  = this.AddDocumentOKCallback.bind(this);
		
			DT_DocumentDlg.AddVersion ( data );
		}

		// ##########################################################################""
		// ### View document from histo

		OnViewHistoDocument ( el )
		{
			let id = el.target.getAttribute('data-id');

			this.OnViewDocument ( id );
		}
	}
