class DocumentGeneratorController {
	constructor(values) {
		this.ajax = values.ajax;
		this.typeColors = values.typeColors;
		this.fontSize = values.fontSize;
		this.fontName = values.fontName;
		this.isPerf = values.isPerf;
		this.colorsRGB = values.colorsRGB;
		this.colorsHex = values.colorsHex;
		this.poll = values.poll;
		this.idPoll = values.idPoll;
		this.namePoll = values.namePoll;
		this.question = values.question;
		this.questionOrder = values.questionOrder;
		this.columnName = values.columnName;
		this.title = values.title;
		this.answersChart = values.answersChart;
		this.answersData = values.answersData;
		this.wordCloud = values.wordCloud;
		this.wordCloudURL = values.wordCloudURL;
		this.primaryColor = values.primaryColor;
		this.secundaryColor = values.secundaryColor;
		this.data = values.data;
		this.language = values.language;
		this.iChart = values.iChart;
		this.QuestQuantity = values.QuestQuantity;
		this.arrayPpt = values.arrayPpt;
		this.dataPpt = values.dataPpt;
		this.wcPpt = values.wcPpt;
		this.questionsPpt = values.questionsPpt;
		this.user = values.user;
		this.reports = values.reports;
		this.timestamp = values.timestamp;
		this.errorsReports = values.errorsReports;
		this.numPregPerf = values.numPregPerf;
		this.preguntaSQ = values.preguntaSQ;
		this.excelDataOpt = values.excelDataOpt;
		this.participantsNumber = values.participantsNumber;
		this.splitCharacter = values.splitCharacter;
		this.idReport = '';
		this.abort = false;
		this.questionIdOut = values.questionIdOut;
		this.genderData = [];
		this.passNSEGraph = true;
		this.numberWordsWordcloud = values.numberWordsWordcloud;
		this.idmision = values.idmision;
		this.project = values.project;
	}

	start() {
		let self = this;

		self.executeReports();
	}

	executeReports() {
		let self = this;

		self.ajax = false;
		$('#show-generating-reports').css('visibility', 'visible');
		let idReport = Math.floor(Date.now() / 1000);
		self.idReport = idReport;
		let report = {
			name: self.namePoll,
			id: idReport,
			title: pf.const.language.RSC1379,
			subtitle: pf.const.language.RSC49,
			cancelButton: true
		}
		CardGeneratorController.addNotification(report);

		$(`#cancelDowload${self.idReport}`).off().on('click', (e)=>{
			e.preventDefault();
			self.cancelAjax();
		});

		setTimeout(function() {
			self.generateDocument();
		}, 500);
	}

	execSocialTools() {
		let self = this;

		let token = sessionStorage['STCMBackEnd:token'];
		let reqLabel = 'execSocialTools' + self.idReport;
		let reqName = 'execSocialTools';

		let form = new FormData();
		form.append('action', reqName);
		form.append('token', token);

		let reqData = {
			url: stcm.const.serverAPI,
			method: 'POST',
			timeout: stcm.const.AJAX_TIMEOUT,
			processData: false,
			mimeType: 'application/x-www-form-urlencoded',
			contentType: false,
			data: form
		};

		pf.ajax.request(reqLabel, reqData);
		$(document).off(reqLabel);
		$(document).on(reqLabel, function(event, response) {
			if(response.status === 'OK') {
				let resp = JSON.parse(response.resData.response);
				if(resp.status === 'OK') {
					self.generateDocument();
				} else if(!self.abort) {
					let errorTitle = pf.const.language.RSC61;
					let errorContent = pf.const.language.RSC498;
					pf.utils.showInfoDialog(errorTitle, errorContent);
					if(resp.result == 'Not authorized') {
						pf.ajax.setWindowLocationIndex();
					}
				}
			} else if(!self.abort) {
				let errorTitle = pf.const.language.RSC61;
				let errorContent = response.result;
				pf.utils.showInfoDialog(errorTitle, errorContent);
			}
		});
	}

	generateDocument() {
		let self = this;

		let token = sessionStorage['STCMBackEnd:token'];
		let idTenant = sessionStorage['STCMBackEnd:idTenant'];
		let survey = self.idPoll;
		let reqName = 'generateWord';
		let reqLabel = 'generateWord' + self.idReport;
		this.reqLabel = reqLabel;

		let form = new FormData();
		form.append('action', reqName);
		form.append('token', token);
		form.append('idTenant', idTenant);
		form.append('colorsRGB', self.colorsRGB);
		form.append('colorsHex', self.colorsHex);
		form.append('survey', survey);
		form.append('namePoll', self.namePoll);
		form.append('user', self.user);
		form.append('typeColors', self.typeColors);
		form.append('isPerf', self.isPerf);
		form.append('timestamp', self.timestamp);
		form.append('questionIdOut', self.questionIdOut);
		form.append('param4', self.numPregPerf);
		form.append('idmision', self.idmision);
		form.append('project', self.project);

		if(self.reports.word || (!self.reports.ppt && self.reports.wc)) {
			// RSC50: 	Paso 1 de 3
			// RSC58: Procesando datos...
			let steps = pf.const.language.RSC50 + '<br>' + pf.const.language.RSC58;

			$(`#downloadCardTitle_${self.idReport}`).html(pf.const.language.RSC547 + ' ' + pf.const.language.RSC536 + ' - ' + self.namePoll);
			$(`#downloadCardText_${self.idReport}`).html(steps);

			let reqData = {
				url: stcm.const.serverAPI,
				method: 'POST',
				timeout: stcm.const.AJAX_TIMEOUT_REPORTS,
				processData: false,
				mimeType: 'application/x-www-form-urlencoded',
				contentType: false,
				data: form
			};

			pf.ajax.request(reqLabel, reqData);
			$(document).off(reqLabel);

			$(document).on(reqLabel, function(event, response) {
				try {
					if(response.status === 'OK') {
						let resp = JSON.parse(response.resData.response);
						//make sure the survey is not empty
						if(resp.status == 'OK') {
							self.generalCharts = resp.resume;
							// RSC51: Paso 2 de 3
							// RSC52: Generando gráficas...
							let steps = pf.const.language.RSC51 + '<br>' + pf.const.language.RSC52;

							$(`#downloadCardText_${self.idReport}`).html(steps);

							if(resp.perf) {
								self.generatePpt();
							} else {
								let imagesWC = [];
								let i = 0;
								function searchWC(i) {
									if(!self.ajax) {
										if(resp.wordCloud[i] == 'yes') {
											let parmb = '';

											if(resp.result[i].data[0]) {
												parmb = resp.result[i].data[0].question;
											} else {
												parmb = 0;
											}

											// Palabras (1) o frases (2)
											let wordsOrPhrases = 2;

											if(resp.result[i].data[0].tipoPregunta == 'S' || resp.result[i].data[0].tipoPregunta == 'Q') {
												wordsOrPhrases = 1;
											}

											// Ruta WordCloud
											let src = self.wordCloudURL + '/?a=' + self.idPoll + '&b=' + parmb + '&c=&d=&e=&f=&g=' + self.primaryColor + '&h=' + self.secundaryColor + '&i=' + wordsOrPhrases + '&j=' + self.numberWordsWordcloud + '&k=&l=&m=&n=&o=';
											window.addEventListener('message', loadWordCloud);
											function loadWordCloud(event) {
												let url_base64jp = event.data;
												imagesWC.push(url_base64jp);
												window.removeEventListener('message', loadWordCloud);
												i++;
												if(i < resp.wordCloud.length) {
													searchWC(i);
												} else {
													self.endWordCloud(resp, imagesWC);
												}
											}
											$('#result_word_cloud').attr('src', src);
										} else {
											if(resp.wordCloud[i] == 'image') {
												imagesWC.push('image');
											} else {
												imagesWC.push('no');
											}

											i++;
											if(i < resp.wordCloud.length) {
												searchWC(i);
											} else {
												self.endWordCloud(resp, imagesWC);
											}
										}
										return true;
									}
								}
								searchWC(i);
							}
						} else {
							//encuesta no válida
							self.emptySurveyException();
						}
					} else if(!self.ajax && !self.abort) {
						self.errorsReports.word = true;
						self.generatePpt();
					}
				} catch(e) {
					if(!self.abort) {
						self.errorsReports.word = true;
						self.generatePpt();
					}
				}
			});
		} else {
			self.generatePpt();
		}
	}

	endWordCloud(data, wc) {
		let self = this;

		let wcString = '[';
		for(let i = 0; i < wc.length; i++) {
			wcString += '"' + wc[i] + '\",';
		}
		wcString = wcString.substring(0, wcString.length - 1);
		wcString += ']';
		let token = sessionStorage['STCMBackEnd:token'];
		let idTenant = sessionStorage['STCMBackEnd:idTenant'];
		let reqName = 'printWord';
		let reqLabel = 'printWord' + self.idReport;
		this.reqLabel = reqLabel;

		let form = new FormData();
		form.append('action', reqName);
		form.append('token', token);
		form.append('idTenant', idTenant);
		form.append('wordCloud', wcString);
		form.append('questions', JSON.stringify(data.questions));
		form.append('data', JSON.stringify(data.result));
		form.append('colorsRGB', self.colorsRGB);
		form.append('colorsHex', self.colorsHex);
		form.append('user', self.user);
		form.append('typeColors', self.typeColors);
		form.append('generalCharts', JSON.stringify(self.generalCharts));
		form.append('timestamp', JSON.stringify(self.timestamp));
		form.append('isWc', self.reports.wc);
		form.append('isWord', self.reports.word);

		// RSC53: Paso 3 de 3
		// RSC54: Generando documento...
		let steps = pf.const.language.RSC53 + '<br>' + pf.const.language.RSC54;

		$(`#downloadCardText_${self.idReport}`).html(steps);

		let reqData = {
			url: stcm.const.serverAPI,
			method: 'POST',
			timeout: stcm.const.AJAX_TIMEOUT_REPORTS,
			processData: false,
			mimeType: 'application/x-www-form-urlencoded',
			contentType: false,
			data: form
		};

		pf.ajax.request(reqLabel, reqData);
		$(document).off(reqLabel);
		$(document).on(reqLabel, function(event, response) {
			try {
				let resp = JSON.parse(response.resData.response);
				if(resp.status === 'OK') {
					self.generatePpt();
				} else if(!self.abort) {
					self.errorsReports.word = true;
					self.generatePpt();
				}
			} catch(e) {
				if(!self.abort) {
					self.errorsReports.word = true;
					self.generatePpt();
				}
			}
		});
	}

	cancelAjax(deleteNotification = true) {
		let self = this;

		self.ajax = true;
		self.abort = true;
		pf.ajax.abortRequest(this.reqLabel);
		if(deleteNotification) {
			CardGeneratorController.deleteNotification(this.idReport);
		}
	}

	generateExcel() {
		let self = this;

		if(self.reports.excel) {
			let token = sessionStorage['STCMBackEnd:token'];
			let survey = self.idPoll;
			let reqName = 'generateExcel';
			let reqLabel = 'generateExcel' + self.idReport;
			this.reqLabel = reqLabel;
			let steps = pf.const.language.RSC534 + '<br>' + pf.const.language.RSC533 + '...';

			$(`#downloadCardText_${self.idReport}`).html(steps);
			$(`#downloadCardTitle_${self.idReport}`).html(pf.const.language.RSC547 + ' ' + pf.const.language.RSC540 + ' - '+self.namePoll);

			let headersExcel = '';
			if(self.numPregPerf < 4) {
				/*
					RSC1436 = Rotación
					RSC123 = Nombre
					RSC999 = Folio
					RSC564 = Estado
					RSC601 = Región ABI
					RSC607 = Ciudad
					RSC565 = Edad
					RSC1917 = Rango de edad
					RSC151 = Género
					RSC1948 = Segmentación
					RSC560 = Asesor
					RSC126 = Activo
					RSC572 = Validación
				*/
				headersExcel = pf.const.language.RSC1436 + ',' + pf.const.language.RSC123 + ',' + pf.const.language.RSC999 + ',' + pf.const.language.RSC564 + ',' + pf.const.language.RSC601 + ',' + pf.const.language.RSC607 + ',' + pf.const.language.RSC565 + ',' + pf.const.language.RSC1917 + ',' + pf.const.language.RSC151 + ',' + pf.const.language.RSC1948 + ',' + pf.const.language.RSC560 + ',' + pf.const.language.RSC126 + ',' + pf.const.language.RSC572;
			} else {
				/*
					RSC1436 = Rotación
					RSC123 = Nombre
					RSC999 = Folio
					RSC564 = Estado
					RSC601 = Región ABI
					RSC607 = Ciudad
					RSC565 = Edad
					RSC1917 = Rango de edad
					RSC151 = Género
					RSC598 = NSE
					RSC1990 = Rango NSE
					RSC1948 = Segmentación
					RSC560 = Asesor
					RSC126 = Activo
					RSC572 = Validación
				*/
				headersExcel = pf.const.language.RSC1436 + ',' + pf.const.language.RSC123 + ',' + pf.const.language.RSC999 + ',' + pf.const.language.RSC564 + ',' + pf.const.language.RSC601 + ',' + pf.const.language.RSC607 + ',' + pf.const.language.RSC565 + ',' + pf.const.language.RSC1917 + ',' + pf.const.language.RSC151 + ',' + pf.const.language.RSC598 + ',' + pf.const.language.RSC1990 + ',' + pf.const.language.RSC1948 + ',' + pf.const.language.RSC560 + ',' + pf.const.language.RSC126 + ',' + pf.const.language.RSC572;
			}

			if(sessionStorage['STCMBackEnd:Consumer'] == 1) {
				headersExcel += ',' + pf.const.language.RSC1899; // Consumidor
			}

			let nameWOSlash = self.namePoll.replace(/\//g, '-');

			let parent_qid = '0';
			if(self.columnName != '') {
				let questionArray = self.columnName.split('X');
				parent_qid = questionArray[questionArray.length - 1];
			}

			let form = new FormData();
			form.append('action', reqName);
			form.append('token', token);
			form.append('survey', survey);
			form.append('numPreguntasPerfilacionEnAnalyticMostreo', self.numPregPerf);
			form.append('user', self.user);
			form.append('name', nameWOSlash);
			form.append('timestamp', self.timestamp);
			form.append('excelDataOpt', self.excelDataOpt);
			form.append('headersExcel', headersExcel);
			form.append('parent_qid', parent_qid);
			form.append('questionIdOut', self.questionIdOut);
			form.append('consumo', sessionStorage['STCMBackEnd:Consumer']);
			form.append('idmision', self.idmision);
			form.append('project', self.project);

			let reqData = {
				url: stcm.const.serverAPI,
				method: 'POST',
				timeout: stcm.const.AJAX_TIMEOUT_REPORTS,
				processData: false,
				mimeType: 'application/x-www-form-urlencoded',
				contentType: false,
				data: form
			};

			pf.ajax.request(reqLabel, reqData);
			$(document).off(reqLabel);
			$(document).on(reqLabel, function(event, response) {
				try {
					let resp = JSON.parse(response.resData.response);
					if(resp.status == 'KO') {
						self.errorsReports.excel = true;
					} else {
						self.errorsReports.excel = false;
					}
					if(!self.abort) {
						self.generateImages();
					}
				} catch(e) {
					if(!self.abort) {
						self.errorsReports.excel = true;
						self.generateImages();
					}
				}
			});
		} else {
			self.generateImages();
		}
	}

	generateImages() {
		let self = this;

		if(self.reports.images) {
			let token = sessionStorage['STCMBackEnd:token'];
			let idTenant = sessionStorage['STCMBackEnd:idTenant'];
			let reqName = 'getImagesSurvey';
			let reqLabel = 'getImagesSurvey' + self.idReport;
			this.reqLabel = reqLabel;
			let steps = pf.const.language.RSC534 + '<br>' + pf.const.language.RSC535 + '...';

			$(`#downloadCardText_${self.idReport}`).html(steps);
			$(`#downloadCardTitle_${self.idReport}`).html(pf.const.language.RSC547 + ' ' + pf.const.language.RSC544 + ' - '+self.namePoll);

			let form = new FormData();
			form.append('action', reqName);
			form.append('token', token);
			form.append('idTenant', idTenant);
			form.append('timestamp', self.timestamp);
			form.append('survey', self.idPoll);
			form.append('user', self.user);
			form.append('idmision', self.idmision);
			form.append('project', self.project);

			let reqData = {
				url: stcm.const.serverAPI,
				method: 'POST',
				timeout: stcm.const.AJAX_TIMEOUT_REPORTS,
				processData: false,
				mimeType: 'application/x-www-form-urlencoded',
				contentType: false,
				data: form
			};

			pf.ajax.request(reqLabel, reqData);
			$(document).off(reqLabel);
			$(document).on(reqLabel, function(event, response) {
				try {
					if(response.status === 'OK') {
						let resp = JSON.parse(response.resData.response);
						if(resp.status == 'OK') {
							self.finishReports();
						} else if(!self.abort) {
							self.errorsReports.noImages = true;
							self.finishReports();
						}
					} else if(!self.abort) {
						self.errorsReports.images = true;
						self.finishReports();
					}
				} catch(e) {
					if(!self.abort) {
						self.errorsReports.images = true;
						self.finishReports();
					}
				}
			});
		} else {
			self.finishReports();
		}
	}

	finishReports() {
		let self = this;

		let content = pf.const.language.RSC1380;
		let useBootstrap = true;

		if(self.errorsReports.word || self.errorsReports.ppt || self.errorsReports.excel || self.errorsReports.images) {
			content += '<p>' + pf.const.language.RSC546 + ':</p><ul>';
			useBootstrap = false;
		}
		if(self.errorsReports.word) {
			content += '<li>' + pf.const.language.RSC536 + '</li>';
		}
		if(self.errorsReports.ppt) {
			content += '<li>' + pf.const.language.RSC538 + '</li>';
		}
		if(self.errorsReports.excel) {
			content += '<li>' + pf.const.language.RSC540 + '</li>';
		}
		if(self.errorsReports.ppt && self.errorsReports.word) {
			content += '<li>' + pf.const.language.RSC542 + '</li>';
		}
		if(self.errorsReports.noImages) {
			content += '<li>' + pf.const.language.RSC1502 + '</li>';
		}
		if(self.errorsReports.images) {
			content += '<li>' + pf.const.language.RSC544 + '</li>';
		}
		if(self.errorsReports.word || self.errorsReports.ppt || self.errorsReports.excel || self.errorsReports.images) {
			content += '</ul>';
		}

		removeLoader();
		if(!self.ajax) {
			$(`#downloadCardTitle_${self.idReport}`).html(pf.const.language.RSC55 + ' - ' + self.namePoll);
			$(`#downloadCardText_${self.idReport}`).html(content);
			$(`#${self.idReport}`).find('#statusIcon').html(stcmbackend.svg.checkCircleWithoutColor);

			$(`#${self.idReport}`).removeClass('runningReport');
			if(self.reports.images && !self.reports.excel && !self.reports.ppt && !self.reports.wc && !self.reports.word && self.errorsReports.noImages) {
				$(`#${self.idReport}`).find(`#buttonWrapper${self.idReport}`).html(
					`<button id="cancelGeneratedReport" type="button" class="btn new-style-cancel">${pf.const.language.RSC57}</button>`
				);
			} else {
				$(`#${self.idReport}`).find(`#buttonWrapper${self.idReport}`).html(`
					<button id="cancelGeneratedReport" type="button" class="btn new-style-cancel">${pf.const.language.RSC57}</button>
					<button id="dowloadGeneratedReport" type="button" class="btn new-style-accept">${pf.const.language.RSC56}</button>
				`);
			}

			CardGeneratorController.updateIcon();
			CardGeneratorController.showOnScreenNotification(self.idReport,pf.const.language.RSC55, 'check-circle');

			$(`#${self.idReport}`).find('#dowloadGeneratedReport').off().on('click', ()=>{
				let url = stcm.const.downloads + self.user + '/' + self.timestamp + '_Analitics_Mostreo.zip';
				$('#dowloadIframe').attr('src', url);
				CardGeneratorController.deleteNotification(this.idReport);

				setTimeout(function() {
					self.deleteFiles();
				}, 1000 * 60);
			});
			$(`#${this.idReport}`).find('#cancelGeneratedReport').off().on('click', ()=>{
				self.deleteFiles();
				CardGeneratorController.deleteNotification(this.idReport);
			});
		}
	}

	generatePpt() {
		let self = this;

		if(self.reports.ppt) {
			let token = sessionStorage['STCMBackEnd:token'];
			let idTenant = sessionStorage['STCMBackEnd:idTenant'];
			let survey = self.idPoll;
			let reqName = 'requestAllGraphs';
			let reqLabel = 'requestAllGraphs' + self.idReport;
			this.reqLabel = reqLabel;

			// RSC50: 	Paso 1 de 3
			// RSC58: Procesando datos...
			let steps = pf.const.language.RSC50 + '<br>' + pf.const.language.RSC58;

			$(`#downloadCardText_${self.idReport}`).html(steps);
			$(`#downloadCardTitle_${self.idReport}`).html(pf.const.language.RSC547 + ' ' + pf.const.language.RSC538);

			let form = new FormData();
			form.append('action', reqName);
			form.append('token', token);
			form.append('idTenant', idTenant);
			form.append('colorsRGB', self.colorsRGB);
			form.append('colorsHex', self.colorsHex);
			form.append('survey', survey);
			form.append('isPerf', self.isPerf);
			form.append('param4', self.numPregPerf);
			form.append('questionIdOut', self.questionIdOut);
			form.append('namePoll', self.namePoll);
			form.append('idmision', self.idmision);
			form.append('project', self.project);

			let reqData = {
				url: stcm.const.serverAPI,
				method: 'POST',
				timeout: stcm.const.AJAX_TIMEOUT_REPORTS,
				processData: false,
				mimeType: 'application/x-www-form-urlencoded',
				contentType: false,
				data: form
			};

			pf.ajax.request(reqLabel, reqData);
			$(document).off(reqLabel);

			$(document).on(reqLabel, function(event, response) {
				try {
					if(response.status === 'OK') {
						let resp = JSON.parse(response.resData.response);
						self.dataPpt = resp.result;
						self.wcPpt = resp.wordCloud;
						self.questionsPpt = resp.questions;
						if(resp.perf) {
							let images = [];

							function printChart(i) {
								if(!self.ajax) {
									// Crear graficas
									let ctx;
									let quantity = resp.result[i].answers.labels.length;
									let gradient = [];
									if(self.typeColors == 1) {
										if(quantity == 2) {
											gradient = self.colorsHex;
										} else {
											gradient = generateColors(self.colorsHex[0], self.colorsHex[1], quantity);
										}
									} else {
										gradient = arrayColors(self.colorsHex, quantity);
									}
									let options = JSON.parse(resp.result[i].answers.options);

									self.answersData = resp.result[i];
									if(!$.isEmptyObject(self.answersChart)) {
										self.answersChart.destroy();
									}
									resp.result[i].answers.datasets.backgroundColor = gradient;
									ctx = document.getElementById('result_graph_ppt').getContext('2d');

									resp.result[i].answers.datasets.backgroundColor = gradient;

									options['tooltips'] = {
										enabled: false
									};

									options['plugins'] = {
										datalabels: {
											color: 'black',
											font: {
												weight: 'bold',
												size: self.fontSize
											},
											anchor: 'end',
											align: 'end',
											formatter(value, context) {
												return value;
											}
										}
									};
									options.maintainAspectRatio = true;
									options.responsive = false;
									Chart.defaults.global.defaultFontSize = self.fontSize;
									Chart.defaults.global.defaultFontFamily = self.fontName;

									self.chart = new Chart(ctx, {
										// The type of chart we want to create
										type: resp.result[i].answers.type,
										// The data for our dataset
										data: {
											labels: resp.result[i].answers.labels,
											datasets: [resp.result[i].answers.datasets]
										},
										// Configuration options go here
										options: options
									});
									setTimeout(function() {
										let url_base64jp = document.getElementById('result_graph_ppt').toDataURL('image/jpg');
										self.chart.destroy();

										images.push(url_base64jp);

										i++;

										if(i == (resp.result.length)) {
											self.returnPptDataPerf(images);
										} else {
											printChart(i);
										}
									}, 1000);
								}
							}

							let i = 0;
							printChart(i);
						} else {
							let resume = resp.resume;
							resp = resp.result;
							self.dataPpt = resp;
							let resultFinal = '';
							self.QuestQuantity = resp.length;
							self.iChart = 0;
							self.arrayPpt = [];

							// Número total de participantes
							let participants = [];
							let pSize = resp.length;
							for(let i = 0; i < pSize; i++) {
								let sSize = resp[i].data.length;
								for(let j = 0; j < sSize; j++) {
									if(participants.indexOf(resp[i].data[j].user) == -1) {
										participants.push(resp[i].data[j].user);
									}
								}
							}
							self.participantsNumber = participants.length;

							//Crear graficas generales
							function totalChart(type, labels, data, title, i) {
								//Seleccion colores
								let quantity = labels.length;
								let gradient = [];
								if(quantity == 2) {
									gradient = self.colorsHex;
								} else {
									if(self.typeColors == 1) {
										gradient = generateColors(self.colorsHex[0], self.colorsHex[1], quantity);
									} else {
										gradient = arrayColors(self.colorsHex, quantity);
									}
								}

								let participants = pf.const.language.RSC443 + ': ' + self.participantsNumber;

								//Definir options
								let options = null;

								if(i == 1 || i == 4) {
									options = {
										animation: {
											duration: 0
										},
										responsive: true,
										maintainAspectRatio: true,
										responsive: false,
										legend: {
											position: 'right',
											onClick: false
										},
										title: {
											display: true,
											text: [title, participants],
											fontSize: self.fontSize,
										},
										plugins: {
											datalabels: {
												color: 'black',
												font: {
													weight: 'bold',
													size: self.fontSize
												},
												clamp: true,
												formatter(value, context) {
													return value;
												}
											}
										}
									};

									// Crear grafica
									let ctx = $('#result_graph_ppt');
									self.chart = new Chart(ctx, {
										// The type of chart we want to create
										type: type,
										// The data for our dataset
										data: {
											datasets: [{
												data: data,
												backgroundColor: gradient
											}],
											labels: labels,
										},
										// Configuration options go here
										options: options
									});
								} else if(i == 5) {
									/* 
										Aclaración: Dado a que no se pueden crear las charts y guardarlas inmediatamente 
										(además que el fetch de los .json funciona de forma asíncrona), los canvas con las imágenes 
										de los mapas, se crean al momento de cargar una encuesta desde muestreo (muestreo_controller.js). 
									*/

									/* Recoge los canvas creados en muestreo y los añades a las charts generales */
									$('#result_graph_ppt_aux canvas').each(function() {
										let ctx = $(this).attr('id');
										let url_base64jp = document.getElementById(ctx).toDataURL('image/jpg');
										self.generalCharts.push(url_base64jp);
										self.chart.destroy();
									});
								} else {
									if(self.passNSEGraph) {
										let displayX = true;
										let displayY = false;
										if(i == 3) {
											displayX = false;
											displayY = true;
										}
										let participants = pf.const.language.RSC443 + ': ' + self.participantsNumber;
										options = {
											animation: {
												duration: 0
											},
											responsive: false,
											maintainAspectRatio: true,
											legend: {
												display: false,
												onClick: false
											},
											scales: {
												xAxes: [{
													ticks: {
														fontSize: 36,
														display: displayX,
														autoSkip: false,
														beginAtZero: true
													},
													gridLines: {
														display: false
													}
												}],
												yAxes: [{
													display: displayY,
													ticks: {
														fontSize: 24,
														beginAtZero: true
													},
													gridLines: {
														display: false
													}
												}]
											},
											title: {
												display: true,
												text: title,
												fontSize: 36,
												padding: 26
											},
											plugins: {
												datalabels: {
													color: 'black',
													font: {
														weight: 'bold',
														size: 24
													},
													//clamp: true,
													anchor: 'end',
													align: 'end',
													formatter(value, context) {
														return value;
													}
												}
											}
										};

										Chart.defaults.global.defaultFontSize = self.fontSize;
										Chart.defaults.global.defaultFontFamily = self.fontName;
										Chart.defaults.global.defaultFontColor = '#000';

										// Ancho del contenedor de la gráfica
										let divParentWidth = 1280;
										// Número de columnas de la gráfica
										let nColumns = quantity;
										// Ancho del contenedor entre el número de columnas
										let maxwidth = Math.floor(parseInt(divParentWidth) / nColumns);
										// Ancho de la columna entre el tamaño de la fuente
										let maxwidthFont = Math.ceil(maxwidth / self.fontSize) + 2;

										// Etiquetas del eje X
										let xLabels = labels;
										// Comprobación de la primera palabra de los labes para ejecutar formato horizontal o diagonal
										let controlH = true;
										let xSize = xLabels.length;
										for(let i = 0; i < xSize; i++) {
											if(xLabels[i] == null || xLabels[i] == undefined) {
												continue;
											}

											let words = xLabels[i].toString().split(' ');
											let wSize = words.length;
											for(let j = 0; j < wSize; j++) {
												if(words[j].length > maxwidthFont) {
													controlH = false;
													break;
												}
											}
											if(!controlH) {
												break;
											}
										}

										if(controlH && options.scales != undefined) {
											options.scales.xAxes[0].ticks['minRotation'] = 0;
											options.scales.xAxes[0].ticks['maxRotation'] = 0;

											options.scales.xAxes[0].ticks['callback'] = function(value, index, values) {
												let formmatedvalue = formatLabel(value, maxwidthFont);
												return formmatedvalue;
											}
										}

										// Ancho de columnas
										options.scales.xAxes[0]['barPercentage'] = 0.5;

										// Crear grafica
										let ctx = $('#result_graph_ppt');
										self.chart = new Chart(ctx, {
											// The type of chart we want to create
											type: type,
											// The data for our dataset
											data: {
												datasets: [{
													data: data,
													backgroundColor: gradient
												}],
												labels: labels,
											},
											// Configuration options go here
											options: options
										});
									}
								}

								setTimeout(function() {
									if(self.chart != undefined) {
										if(i != 5) {
											let url_base64jp = document.getElementById('result_graph_ppt').toDataURL('image/jpg');
											self.generalCharts.push(url_base64jp);	
										}
										self.chart.destroy();
									}

									let n = i + 1;
									let nse = false;

									if(n == 2) {
										totalChart('bar',resume.ageRange.labels, resume.ageRange.value , 'Edad', n);
									} else if(n == 3) {
										totalChart('horizontalBar', resume.states.labels, resume.states.value, '', n); // Estados - (Título introducido en el ppt directamente)
									} else if(n == 4) {
										if(self.numPregPerf >= 4) {
											nse = true;
											self.passNSEGraph = true;
											totalChart('pie', resume.nse.labels, resume.nse.value, pf.const.language.RSC1000 + ' (%)', n);
										} else {
											// En caso de que no se cree NSE Chart
											self.passNSEGraph = false;
											n++;
											let url_base64jp = 'emptyNSE';
											self.generalCharts.push(url_base64jp);
											totalChart('pie', resume.nse.labels, resume.nse.value, 'empty', n);
										}
									} else if(n == 5) {
										totalChart('bar', resume.states.labels, resume.states.value, 'Mapa de Estados', n);
									} else {
										self.graphsPpt(resp, self.QuestQuantity);
									}
								}, 1000);
							}

							self.generalCharts = [];
							self.genderData = resume.gender.value;
							totalChart('pie', resume.gender.labels, resume.gender.value, 'Género', 1);
						}
					} else if(self.ajax && !self.abort) {
						self.errorsReports.ppt = true;
						self.generateExcel();
					}
				} catch(e) {
					if(!self.abort) {
						self.errorsReports.ppt = true;
						self.generateExcel();
					}
				}
			});
		} else {
			self.generateExcel();
		}
	}

	// Gráfica para .ppt 
	graphsPpt(object, QuestQuantity) {
		let self = this;

		try {
			// RSC51: Paso 2 de 3
			// RSC52: Generando gráficas...
			let steps = pf.const.language.RSC51 + '<br>' + pf.const.language.RSC52;
			$(`#downloadCardText_${self.idReport}`).html(steps);

			let idPpt = '';
			if(object[self.iChart].data.length > 0) {
				idPpt = object[self.iChart].data[0].question;
			}

			let pptJson = {
				id: idPpt,
				data: {
					imgAnswer: '',
					imgGender: '',
					imgAge: '',
					imgStates: '',
					imgNSE: '',
					imgStates2: ''
				}
			};

			function recursiveGraphPpt(object, n) {
				if(!self.ajax) {
					let graph = '';
					let url_base64jpWC = '';

					let dataObject = '';
					switch(n) {
						case 0:
							dataObject = object[self.iChart].answers;
							break;
						case 1:
							dataObject = object[self.iChart].gender;
							break;
						case 2:
							dataObject = object[self.iChart].age;
							break;
						case 3:
							dataObject = object[self.iChart].states;
							break;
						case 4:
							dataObject = object[self.iChart].nse;
							break;
						case 5:
							dataObject = object[self.iChart].states2;
							break;
					}

					// Número de participantes por pregunta
					let participants = [];
					let participantsNumber = 0;
					let pSize = object[self.iChart].data.length;
					for(let i = 0; i < pSize; i++) {
						if(participants.indexOf(object[self.iChart].data[i].user) == -1) {
							participants.push(object[self.iChart].data[i].user);
						}
					}
					participantsNumber = participants.length;

					if(self.wcPpt[self.iChart] === 'yes') {
						// WORDCLOUD
						// Los valores de survey y answer los recogerá de los atributos
					} else {
						// GRÁFICA
						let data = dataObject;
						if(typeof data.options === 'string') {
							data.options = JSON.parse(data.options);
						}

						let quantity = data.labels.length;
						let gradient = [];
						if(quantity == 2) {
							gradient = self.colorsHex;
						} else {
							if(self.typeColors == 1) {
								gradient = generateColors(self.colorsHex[0], self.colorsHex[1], quantity);
							} else {
								gradient = arrayColors(self.colorsHex, quantity);
							}
						}

						let titleText = pf.const.language.RSC150 + ' (%)';
						let participants = pf.const.language.RSC443 + ': ' + participantsNumber;

						let ctx = document.getElementById('result_graph_ppt').getContext('2d');
						switch(n) {
							case 0:
								// ANSWERS
								data.datasets.backgroundColor = gradient;
								data.options.title.display = true;
								data.options.title.fontSize = self.fontSize;
								data.options.title.text = [titleText, participants];
								data.options.title.padding = 26;
								data.options.animation.duration = 0;
								break;
							case 1:
								// GENDER
								data.datasets.backgroundColor = self.colorsHex;
								data.options.title.display = true;
								data.options.title.text = pf.const.language.RSC151 + ' (%)';
								data.options.title.padding = 26;
								data.options.animation.duration = 0;
								break;
							case 2:
								// AGE
								data.datasets.backgroundColor = gradient;
								data.options.title.display = true;
								data.options.title.text = pf.const.language.RSC152 + ' (%)';
								data.options.title.padding = 26;
								data.options.animation.duration = 0;
								break;
							case 3:
								// STATES
								data.datasets.backgroundColor = gradient;
								data.options.title.display = true;
								data.options.title.text = pf.const.language.RSC153 + ' (%)';
								data.options.title.padding = 26;
								data.options.animation.duration = 0;
								break;
							case 4:
								// NSE
								data.datasets.backgroundColor = gradient;
								data.options.title.display = true;
								data.options.title.text = pf.const.language.RSC1000 + ' (%)';
								data.options.title.padding = 26;
								data.options.animation.duration = 0;
								break;
							case 5:
								// STATES 2
								data.datasets.backgroundColor = gradient;
								data.options.title.display = true;
								data.options.title.text = pf.const.language.RSC153 + ' (%)';
								data.options.title.padding = 26;
								data.options.animation.duration = 0;
								break;
							default:
								break;
						}

						data.options['tooltips'] = {
							enabled: false
						};

						data.options['plugins'] = {
							datalabels: {
								color: 'black',
								font: {
									weight: 'bold',
									size: self.fontSize
								},
								anchor: 'end',
								align: 'end',
								formatter(value, context) {
									return value;
								}
							}
						};
						data.options.maintainAspectRatio = true;
						data.options.responsive = true;
						Chart.defaults.global.defaultFontSize = self.fontSize;
						Chart.defaults.global.defaultFontFamily = self.fontName;
						Chart.defaults.global.defaultFontColor = '#000';

						// Ancho del contenedor de la gráfica
						let divParentWidth = 1280;
						// Número de columnas de la gráfica
						let nColumns = quantity;
						// Ancho del contenedor entre el número de columnas
						let maxwidth = Math.floor(parseInt(divParentWidth) / nColumns);
						// Ancho de la columna entre el tamaño de la fuente
						let maxwidthFont = Math.ceil(maxwidth / self.fontSize) + 2;

						// Etiquetas del eje X
						let xLabels = data.labels;
						// Comprobación de la primera palabra de los labes para ejecutar formato horizontal o diagonal
						let controlH = true;
						let xSize = xLabels.length;
						for(let i = 0; i < xSize; i++) {
							if(xLabels[i] == null || xLabels[i] == undefined) {
								continue;
							}

							// Utilización de caracter de corte si lo hay
							if(self.splitCharacter != '') {
								let indexCut = xLabels[i].toString().indexOf(self.splitCharacter);
								if(indexCut != -1) {
									xLabels[i] = xLabels[i].toString().slice(0, indexCut);
								}
							}

							let words = xLabels[i].toString().split(' ');
							let wSize = words.length;
							for(let j = 0; j < wSize; j++) {
								if(words[j].length > maxwidthFont) {
									controlH = false;
									break;
								}
							}
						}

						if(controlH && data.options.scales != undefined) {
							data.options.scales.xAxes[0].ticks['minRotation'] = 0;
							data.options.scales.xAxes[0].ticks['maxRotation'] = 0;

							data.options.scales.xAxes[0].ticks['callback'] = function(value, index, values) {
								let formmatedvalue = formatLabel(value, maxwidthFont);
								return formmatedvalue;
							}
						}

						// Ancho de columnas
						if(data.options.scales != undefined) {
							data.options.scales.xAxes[0]['barPercentage'] = 0.5;
						}

						self.chart = new Chart(ctx, {
							// The type of chart we want to create
							type: data.type,
							// The data for our dataset
							data: {
								labels: data.labels,
								datasets: [data.datasets]
							},
							// Configuration options go here
							options: data.options
						});
					}

					/*Get image of canvas element*/ 
					setTimeout(function() {
						let url_base64jp = document.getElementById('result_graph_ppt').toDataURL('image/jpg');
						switch(n) {
							case 0:
								if(self.wcPpt[self.iChart] === 'yes') {
									// Palabras (1) o frases (2)
									let wordsOrPhrases = 2;

									if(object[self.iChart].data[0].tipoPregunta == 'S' || object[self.iChart].data[0].tipoPregunta == 'Q') {
										wordsOrPhrases = 1;
									}

									// Ruta WordCloud
									let src = self.wordCloudURL + '/?a=' + self.idPoll + '&b=' + pptJson.id + '&c=&d=&e=&f=&g=' + self.primaryColor + '&h=' + self.secundaryColor + '&i=' + wordsOrPhrases + '&j=' + self.numberWordsWordcloud + '&k=&l=&m=&n=&o=';

									window.addEventListener('message', loadWordCloud);
									function loadWordCloud(event) {
										pptJson.data.imgAnswer = event.data;
										window.removeEventListener('message', loadWordCloud);
									}
									$('#result_word_cloud').attr('src', src);
								} else {
									self.chart.destroy();
									pptJson.data.imgAnswer = url_base64jp;
								}
								break;
							case 1:
								self.chart.destroy();
								break;
							case 2:
								self.chart.destroy();
								break;
							case 3:
								self.chart.destroy();
								break;
							case 4:
								self.chart.destroy();
								break;
							case 5:
								self.chart.destroy();
								break;
						}

						self.arrayPpt.push(pptJson);
						self.iChart++;

						if(self.iChart < self.QuestQuantity) {
							self.graphsPpt(object);
						} else {
							self.returnPptData();
						}
					}, 3000);
				}
			}

			return recursiveGraphPpt(object, 0);
		} catch(e) {
			if(!self.abort) {
				self.errorsReports.ppt = true;
				self.generateExcel();
			}
		}
	}

	returnPptData() {
		let self = this;

		let steps = pf.const.language.RSC53 + '<br>' + pf.const.language.RSC54;
		$(`#downloadCardText_${self.idReport}`).html(steps);

		let token = sessionStorage['STCMBackEnd:token'];
		let idTenant = sessionStorage['STCMBackEnd:idTenant'];
		let reqName = 'printPpt';
		let reqLabel = 'printPpt' + self.idReport;
		this.reqLabel = reqLabel;
		let graphs = JSON.stringify(self.arrayPpt);
		let data = JSON.stringify(self.dataPpt);
		let wcPpt = JSON.stringify(self.wcPpt);
		let questionsPpt = JSON.stringify(self.questionsPpt);
		let generalCharts = JSON.stringify(self.generalCharts);
		let genderData = JSON.stringify(self.genderData);

		let form = new FormData();
		form.append('action', reqName);
		form.append('token', token);
		form.append('idTenant', idTenant);
		form.append('graphs', graphs);
		form.append('data', data);
		form.append('wcPpt', wcPpt);
		form.append('questionsPpt', questionsPpt);
		form.append('user', self.user);
		form.append('generalCharts', generalCharts);
		form.append('timestamp', self.timestamp);
		form.append('isWc', self.reports.wc);
		form.append('genderData', genderData);
		form.append('idmision', self.idmision);
		form.append('project', self.project);

		let reqData = {
			url: stcm.const.serverAPI,
			method: 'POST',
			timeout: stcm.const.AJAX_TIMEOUT_REPORTS,
			processData: false,
			mimeType: 'application/x-www-form-urlencoded',
			contentType: false,
			data: form
		};

		pf.ajax.request(reqLabel, reqData);
		$(document).off(reqLabel);
		$(document).on(reqLabel, function(event, response) {
			try {
				let resp = JSON.parse(response.resData.response);
				if(resp.status === 'OK') {
					self.generateExcel();
				} else if(!self.abort) {
					self.errorsReports.ppt = true;
					self.generateExcel();
					if(resp.result == 'Not authorized') {
						pf.ajax.setWindowLocationIndex();
					}
				}
			} catch(e) {
				if(!self.abort) {
					self.errorsReports.ppt = true;
					self.generateExcel();
				}
			}
		});
	}

	returnPptDataPerf(images) {
		let self = this;

		let steps = pf.const.language.RSC53 + '<br>' + pf.const.language.RSC54;
		$(`#downloadCardText_${self.idReport}`).html(steps);

		let token = sessionStorage['STCMBackEnd:token'];
		let idTenant = sessionStorage['STCMBackEnd:idTenant'];
		let reqName = 'printPptPerf';
		let reqLabel = 'printPptPerf' + self.idReport;
		this.reqLabel = reqLabel;
		let questionsPpt = JSON.stringify(self.questionsPpt);
		let data = JSON.stringify(self.dataPpt);

		let form = new FormData();
		form.append('action', reqName);
		form.append('token', token);
		form.append('idTenant', idTenant);
		form.append('data', data);
		form.append('images', JSON.stringify(images));
		form.append('questionsPpt', questionsPpt);
		form.append('user', self.user);
		form.append('timestamp', self.timestamp);
		form.append('idmision', self.idmision);
		form.append('project', self.project);

		let reqData = {
			url: stcm.const.serverAPI,
			method: 'POST',
			timeout: stcm.const.AJAX_TIMEOUT_REPORTS,
			processData: false,
			mimeType: 'application/x-www-form-urlencoded',
			contentType: false,
			data: form
		};

		pf.ajax.request(reqLabel, reqData);
		$(document).off(reqLabel);
		$(document).on(reqLabel, function(event, response) {
			try {
				let resp = JSON.parse(response.resData.response);
				if(resp.status === 'OK') {
					self.generateExcel();
				} else if(!self.abort) {
					self.errorReports.ppt = true;
					self.generateExcel();
				}
			} catch(e) {
				if(!self.abort) {
					self.errorsReports.ppt = true;
					self.generateExcel();
				}
			}
		});
	}

	deleteFiles() {
		let self = this;

		let token = sessionStorage['STCMBackEnd:token'];
		let reqName = 'deleteFilesUser';
		let reqLabel = 'deleteFilesUser' + self.idReport;
		this.reqLabel = reqLabel;

		let form = new FormData();
		form.append('action', reqName);
		form.append('token', token);
		form.append('user', self.user);

		let reqData = {
			url: stcm.const.serverAPI,
			method: 'POST',
			timeout: stcm.const.AJAX_TIMEOUT,
			processData: false,
			mimeType: 'application/x-www-form-urlencoded',
			contentType: false,
			data: form
		};

		pf.ajax.request(reqLabel, reqData);
		$(document).off(reqLabel);

		$(document).on(reqLabel, function(event, response) {
			//
		});
	}

	emptySurveyException() {
		let self = this;

		console.log('EMPTY survey');

		$(`#downloadCardTitle_${self.idReport}`).html(pf.const.language.RSC1517 + ' - ' + self.namePoll);
		$(`#downloadCardTitle_${self.idReport}`).addClass('main-color-text');
		$(`#downloadCardText_${self.idReport}`).html(pf.const.language.RSC1518);
		$(`#${self.idReport}`).removeClass('runningReport');
		CardGeneratorController.updateIcon();
		CardGeneratorController.showOnScreenNotification(self.idReport,pf.const.language.RSC55, 'check-circle');

		self.cancelAjax(false);
	}
}